<commit_before>require "test_utils"
require "logstash/filters/mutate"

describe LogStash::Filters::Mutate do
  extend LogStash::RSpec

  describe "basics" do
    config <<-CONFIG
      filter {
        mutate {
          lowercase => "lowerme"
          uppercase => "upperme"
          convert => [ "intme", "integer", "floatme", "float" ]
          rename => [ "rename1", "rename2" ]
          replace => [ "replaceme", "hello world" ]
          remove => [ "removeme" ]
        }
      }
    CONFIG

    event = { "@fields" => {
      "lowerme" => [ "ExAmPlE" ],
      "upperme" => [ "ExAmPlE" ],
      "intme" => [ "1234", "7890.4", "7.9" ],
      "floatme" => [ "1234.455" ],
      "rename1" => [ "hello world" ],
      "replaceme" => [ "who cares" ],
      "removeme" => [ "something" ]
      }
    }

    sample event do
      insist { subject["lowerme"] } == ['example']
      insist { subject["upperme"] } == ['EXAMPLE']
      insist { subject["intme"] }   == [1234, 7890, 7]
      insist { subject["floatme"] } == [1234.455]
      reject { subject }.include?("rename1")
      insist { subject["rename2"] } == [ "hello world" ]
      reject { subject }.include?("removeme")
    end
  end

  describe "regression - check grok+mutate" do
    config <<-CONFIG
      filter {
        grok {
          pattern => "%{WORD:foo}"<commit_msg>Spec mutate filter: adding cases for multi field remove and gsub<commit_after>require "test_utils"
require "logstash/filters/mutate"

describe LogStash::Filters::Mutate do
  extend LogStash::RSpec

  describe "basics" do
    config <<-CONFIG
      filter {
        mutate {
          lowercase => "lowerme"
          uppercase => "upperme"
          convert => [ "intme", "integer", "floatme", "float" ]
          rename => [ "rename1", "rename2" ]
          replace => [ "replaceme", "hello world" ]
          remove => [ "removeme" ]
        }
      }
    CONFIG

    event = { "@fields" => {
      "lowerme" => [ "ExAmPlE" ],
      "upperme" => [ "ExAmPlE" ],
      "intme" => [ "1234", "7890.4", "7.9" ],
      "floatme" => [ "1234.455" ],
      "rename1" => [ "hello world" ],
      "replaceme" => [ "who cares" ],
      "removeme" => [ "something" ]
      }
    }

    sample event do
      insist { subject["lowerme"] } == ['example']
      insist { subject["upperme"] } == ['EXAMPLE']
      insist { subject["intme"] }   == [1234, 7890, 7]
      insist { subject["floatme"] } == [1234.455]
      reject { subject }.include?("rename1")
      insist { subject["rename2"] } == [ "hello world" ]
      reject { subject }.include?("removeme")
    end
  end

  describe "remove multiple fields" do
    config '
      filter {
        mutate {
          remove => [ "remove-me", "remove-me2", "diedie" ]
        }
      }'

    sample "@fields" => {
      "remove-me"  => "Goodbye!",
      "remove-me2" => 1234,
      "diedie"     => [1, 2, 3, 4],
      "survivor"   => "Hello."
    } do
      insist { subject.fields } == { "survivor" => "Hello." }
    end
  end

  describe "convert one field to string" do
    config '
      filter {
        mutate {
          convert => [ "unicorns", "string" ]
        }
      }'

    sample "@fields" => {
      "unicorns" => 1234
    } do
      insist { subject.fields } == { "unicorns" => "1234" }
    end
  end

  describe "gsub on a String" do
    config '
      filter {
        mutate {
          gsub => [ "unicorns", "but extinct", "and common" ]
        }
      }'

    sample "@fields" => {
      "unicorns" => "Magnificient, but extinct, animals"
    } do
      insist { subject.fields } == {
        "unicorns" => "Magnificient, and common, animals"
      }
    end
  end

  describe "gsub on an Array of Strings" do
    config '
      filter {
        mutate {
          gsub => [ "unicorns", "extinct", "common" ]
        }
      }'

    sample "@fields" => {
      "unicorns" => [
        "Magnificient extinct animals",
        "Other extinct ideas"
      ]
    } do
      insist { subject.fields } == {
        "unicorns" => [
          "Magnificient common animals",
          "Other common ideas"
        ]
      }
    end
  end

  describe "gsub on multiple fields" do
    config '
      filter {
        mutate {
          gsub => [ "colors", "red", "blue",
                    "shapes", "square", "circle" ]
        }
      }'

    sample "@fields" => {
      "colors" => "One red car",
      "shapes" => "Four red squares"
    } do
      insist { subject.fields } == {
        "colors" => "One blue car",
        "shapes" => "Four red circles"
      }
    end
  end

  describe "regression - check grok+mutate" do
    config <<-CONFIG
      filter {
        grok {
          pattern => "%{WORD:foo}"
{'fraction_non_alphanumeric': 0.16578108395324123, 'fraction_numerical': 0.020403825717321997, 'mean_word_length': 1.885346413243409, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7211765', 'n_tokens_mistral': 1612, 'n_tokens_neox': 1553, 'n_words': 362}