lib/mutant/mutator/node/send.rb in mutant-0.10.25 vs lib/mutant/mutator/node/send.rb in mutant-0.10.26
- old
+ new
@@ -11,11 +11,11 @@
handle(:send)
children :receiver, :selector
- SELECTOR_REPLACEMENTS = IceNine.deep_freeze(
+ SELECTOR_REPLACEMENTS = {
:< => %i[== eql? equal?],
:<= => %i[< == eql? equal?],
:== => %i[eql? equal?],
:=== => %i[is_a?],
:=~ => %i[match?],
@@ -30,29 +30,33 @@
flat_map: %i[map],
gsub: %i[sub],
is_a?: %i[instance_of?],
kind_of?: %i[instance_of?],
map: %i[each],
- method: %i[public_method],
match: %i[match?],
+ method: %i[public_method],
reverse_each: %i[each],
reverse_map: %i[map each],
reverse_merge: %i[merge],
send: %i[public_send __send__],
to_a: %i[to_ary],
to_h: %i[to_hash],
to_i: %i[to_int],
to_s: %i[to_str],
values_at: %i[fetch_values]
- )
+ }.freeze.tap { |hash| hash.values(&:freeze) }
- RECEIVER_SELECTOR_REPLACEMENTS = IceNine.deep_freeze(
+ RECEIVER_SELECTOR_REPLACEMENTS = {
Date: {
parse: %i[jd civil strptime iso8601 rfc3339 xmlschema rfc2822 rfc822 httpdate jisx0301]
- }
- )
+ }.freeze
+ }.freeze
+ REGEXP_MATCH_METHODS = %i[=~ match match?].freeze
+ REGEXP_START_WITH_NODES = %i[regexp_bos_anchor regexp_literal_literal].freeze
+ REGEXP_END_WITH_NODES = %i[regexp_literal_literal regexp_eos_anchor].freeze
+
private
def dispatch
emit_singletons
@@ -82,17 +86,47 @@
mutate_receiver
mutate_arguments
end
def emit_selector_specific_mutations
+ emit_start_end_with_mutations
emit_predicate_mutations
emit_array_mutation
emit_static_send
emit_const_get_mutation
emit_integer_mutation
emit_dig_mutation
emit_double_negation_mutation
emit_lambda_mutation
+ end
+
+ def emit_start_end_with_mutations # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
+ return unless REGEXP_MATCH_METHODS.include?(selector) && arguments.one?
+
+ argument = Mutant::Util.one(arguments)
+
+ return unless argument.type.equal?(:regexp) && (
+ regexp_ast = AST::Regexp.expand_regexp_ast(argument)
+ )
+
+ regexp_children = regexp_ast.children
+
+ case regexp_children.map(&:type)
+ when REGEXP_START_WITH_NODES
+ emit_start_with(regexp_children)
+ when REGEXP_END_WITH_NODES
+ emit_end_with(regexp_children)
+ end
+ end
+
+ def emit_start_with(regexp_nodes)
+ literal = Mutant::Util.one(regexp_nodes.last.children)
+ emit_type(receiver, :start_with?, s(:str, literal))
+ end
+
+ def emit_end_with(regexp_nodes)
+ literal = Mutant::Util.one(regexp_nodes.first.children)
+ emit_type(receiver, :end_with?, s(:str, literal))
end
def emit_predicate_mutations
return unless selector.match?(/\?\z/) && !selector.equal?(:defined?)