diff --git a/lib/mutest.rb b/lib/mutest.rb index 1d704717..e16f6390 100644 --- a/lib/mutest.rb +++ b/lib/mutest.rb @@ -96,6 +96,7 @@ def self.ci? require 'mutest/mutator/node/regexp/character_type' require 'mutest/mutator/node/regexp/end_of_line_anchor' require 'mutest/mutator/node/regexp/end_of_string_or_before_end_of_line_anchor' +require 'mutest/mutator/node/regexp/one_or_more' require 'mutest/mutator/node/regexp/zero_or_more' require 'mutest/mutator/node/literal' require 'mutest/mutator/node/literal/boolean' diff --git a/lib/mutest/mutator/node/generic.rb b/lib/mutest/mutator/node/generic.rb index 1bf8246a..d3d57a73 100644 --- a/lib/mutest/mutator/node/generic.rb +++ b/lib/mutest/mutator/node/generic.rb @@ -41,6 +41,7 @@ class Generic < self regexp_digit_type regexp_eol_anchor regexp_eos_ob_eol_anchor + regexp_greedy_one_or_more regexp_greedy_zero_or_more regexp_hex_type regexp_nondigit_type @@ -48,7 +49,9 @@ class Generic < self regexp_nonspace_type regexp_nonword_boundary_anchor regexp_nonword_type + regexp_possessive_one_or_more regexp_possessive_zero_or_more + regexp_reluctant_one_or_more regexp_reluctant_zero_or_more regexp_root_expression regexp_space_type diff --git a/lib/mutest/mutator/node/regexp/one_or_more.rb b/lib/mutest/mutator/node/regexp/one_or_more.rb new file mode 100644 index 00000000..94c098d0 --- /dev/null +++ b/lib/mutest/mutator/node/regexp/one_or_more.rb @@ -0,0 +1,29 @@ +module Mutest + class Mutator + class Node + module Regexp + # Mutator for one-or-more quantifier, `+` + class OneOrMore < Node + MAP = IceNine.deep_freeze( + regexp_greedy_one_or_more: :regexp_greedy_interval, + regexp_reluctant_one_or_more: :regexp_reluctant_interval, + regexp_possessive_one_or_more: :regexp_possessive_interval + ) + + handle(*MAP.keys) + + children :min, :max, :subject + + # Replace `/a+/` with `/a{2,}/`, `/a+?/` with `/a{2,}?/`, and `/a++/` with `/a{2,}+/` + # + # @return [undefined] + def dispatch + emit(s(MAP.fetch(node.type), 2, -1, subject)) + emit_subject_mutations + emit(subject) + end + end # GreedyZeroOrMore + end # Regexp + end # Node + end # Mutator +end # Mutest diff --git a/meta/regexp/regexp_one_or_more.rb b/meta/regexp/regexp_one_or_more.rb new file mode 100644 index 00000000..0c9b5341 --- /dev/null +++ b/meta/regexp/regexp_one_or_more.rb @@ -0,0 +1,32 @@ +Mutest::Meta::Example.add :regexp_greedy_one_or_more do + source '/\d+/' + + singleton_mutations + regexp_mutations + + mutation '/\d/' + mutation '/\d{2,}/' + mutation '/\D+/' +end + +Mutest::Meta::Example.add :regexp_reluctant_zero_or_more do + source '/\d+?/' + + singleton_mutations + regexp_mutations + + mutation '/\d/' + mutation '/\d{2,}?/' + mutation '/\D+?/' +end + +Mutest::Meta::Example.add :regexp_possessive_zero_or_more do + source '/\d++/' + + singleton_mutations + regexp_mutations + + mutation '/\d/' + mutation '/\d{2,}+/' + mutation '/\D++/' +end