mutant 0.11.18 → 0.11.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mutant/ast/find_metaclass_containing.rb +1 -1
  3. data/lib/mutant/ast/meta/const.rb +1 -1
  4. data/lib/mutant/ast/meta/optarg.rb +1 -1
  5. data/lib/mutant/ast/meta/resbody.rb +1 -1
  6. data/lib/mutant/ast/meta/send.rb +3 -3
  7. data/lib/mutant/ast/meta/symbol.rb +1 -1
  8. data/lib/mutant/ast/types.rb +2 -1311
  9. data/lib/mutant/bootstrap.rb +4 -4
  10. data/lib/mutant/cli/command/environment/run.rb +4 -3
  11. data/lib/mutant/cli/command/environment/test.rb +1 -1
  12. data/lib/mutant/cli/command/environment.rb +1 -7
  13. data/lib/mutant/cli/command/util.rb +6 -6
  14. data/lib/mutant/config/coverage_criteria.rb +13 -4
  15. data/lib/mutant/config.rb +51 -24
  16. data/lib/mutant/context.rb +1 -6
  17. data/lib/mutant/env.rb +18 -6
  18. data/lib/mutant/expression/method.rb +6 -3
  19. data/lib/mutant/expression/methods.rb +2 -2
  20. data/lib/mutant/expression/namespace.rb +2 -2
  21. data/lib/mutant/expression/parser.rb +1 -1
  22. data/lib/mutant/hooks.rb +8 -7
  23. data/lib/mutant/integration.rb +11 -1
  24. data/lib/mutant/isolation/fork.rb +1 -1
  25. data/lib/mutant/license/subscription/commercial.rb +3 -3
  26. data/lib/mutant/license/subscription/opensource.rb +5 -9
  27. data/lib/mutant/license/subscription.rb +1 -1
  28. data/lib/mutant/matcher/chain.rb +1 -1
  29. data/lib/mutant/matcher/config.rb +13 -7
  30. data/lib/mutant/matcher/descendants.rb +1 -1
  31. data/lib/mutant/matcher/filter.rb +1 -1
  32. data/lib/mutant/matcher/method/instance.rb +9 -4
  33. data/lib/mutant/matcher/method/metaclass.rb +4 -17
  34. data/lib/mutant/matcher/method/singleton.rb +3 -13
  35. data/lib/mutant/matcher/method.rb +13 -4
  36. data/lib/mutant/matcher/methods.rb +4 -2
  37. data/lib/mutant/matcher/namespace.rb +2 -2
  38. data/lib/mutant/matcher/scope.rb +3 -3
  39. data/lib/mutant/matcher/static.rb +1 -1
  40. data/lib/mutant/matcher.rb +5 -3
  41. data/lib/mutant/meta/example/verification.rb +2 -2
  42. data/lib/mutant/meta/example.rb +4 -4
  43. data/lib/mutant/mutation/config.rb +10 -4
  44. data/lib/mutant/mutation/runner/sink.rb +80 -0
  45. data/lib/mutant/mutation/runner.rb +62 -0
  46. data/lib/mutant/mutation.rb +1 -1
  47. data/lib/mutant/mutator/node/block.rb +2 -2
  48. data/lib/mutant/mutator/node/define.rb +1 -1
  49. data/lib/mutant/mutator/node/if.rb +9 -0
  50. data/lib/mutant/mutator/node/rescue.rb +1 -1
  51. data/lib/mutant/mutator/node/send.rb +4 -4
  52. data/lib/mutant/mutator/regexp.rb +2 -2
  53. data/lib/mutant/parallel/source.rb +1 -1
  54. data/lib/mutant/parallel/worker.rb +58 -54
  55. data/lib/mutant/parallel.rb +6 -5
  56. data/lib/mutant/pipe.rb +3 -3
  57. data/lib/mutant/registry.rb +2 -2
  58. data/lib/mutant/reporter/cli/format.rb +3 -3
  59. data/lib/mutant/reporter/cli/printer/env.rb +8 -6
  60. data/lib/mutant/reporter/cli/printer.rb +2 -2
  61. data/lib/mutant/reporter/cli.rb +4 -4
  62. data/lib/mutant/reporter/sequence.rb +1 -1
  63. data/lib/mutant/repository/diff.rb +11 -3
  64. data/lib/mutant/repository.rb +0 -14
  65. data/lib/mutant/result.rb +1 -1
  66. data/lib/mutant/scope.rb +1 -1
  67. data/lib/mutant/selector/expression.rb +2 -2
  68. data/lib/mutant/subject.rb +2 -2
  69. data/lib/mutant/timer.rb +3 -3
  70. data/lib/mutant/transform.rb +14 -14
  71. data/lib/mutant/version.rb +1 -1
  72. data/lib/mutant.rb +13 -11
  73. metadata +9 -9
  74. data/lib/mutant/runner/sink.rb +0 -78
  75. data/lib/mutant/runner.rb +0 -60
@@ -12,7 +12,9 @@ module Mutant
12
12
  # @param [UnboundMethod] method
13
13
  #
14
14
  # @return [Matcher::Method::Instance]
15
- def self.new(scope, target_method)
15
+ #
16
+ # rubocop:disable Metrics/MethodLength
17
+ def self.new(scope:, target_method:)
16
18
  evaluator =
17
19
  if memoized_method?(scope, target_method.name)
18
20
  Evaluator::Memoized
@@ -20,8 +22,13 @@ module Mutant
20
22
  Evaluator
21
23
  end
22
24
 
23
- super(scope, target_method, evaluator)
25
+ super(
26
+ evaluator: evaluator,
27
+ scope: scope,
28
+ target_method: target_method
29
+ )
24
30
  end
31
+ # rubocop:enable Metrics/MethodLength
25
32
 
26
33
  def self.memoized_method?(scope, method_name)
27
34
  scope < Adamantium && scope.memoized?(method_name)
@@ -37,8 +44,6 @@ module Mutant
37
44
  private
38
45
 
39
46
  def match?(node)
40
- n_def?(node) &&
41
- node.location.line.equal?(source_line) &&
42
47
  node.children.fetch(NAME_INDEX).equal?(method_name)
43
48
  end
44
49
 
@@ -11,12 +11,9 @@ module Mutant
11
11
 
12
12
  # New singleton method matcher
13
13
  #
14
- # @param [Class, Module] scope
15
- # @param [Symbol] method_name
16
- #
17
14
  # @return [Matcher::Method::Singleton]
18
- def self.new(scope, method_name)
19
- super(scope, method_name, Evaluator)
15
+ def self.new(scope:, target_method:)
16
+ super(scope: scope, target_method: target_method, evaluator: Evaluator)
20
17
  end
21
18
 
22
19
  # Metaclass method evaluator
@@ -34,10 +31,7 @@ module Mutant
34
31
  private
35
32
 
36
33
  def match?(node)
37
- n_def?(node) &&
38
- name?(node) &&
39
- line?(node) &&
40
- metaclass_receiver?(node)
34
+ name?(node) && metaclass_receiver?(node)
41
35
  end
42
36
 
43
37
  def metaclass_receiver?(node)
@@ -46,14 +40,7 @@ module Mutant
46
40
  end
47
41
 
48
42
  def metaclass_containing(node)
49
- AST::FindMetaclassContaining.call(ast, node)
50
- end
51
-
52
- def line?(node)
53
- node
54
- .location
55
- .line
56
- .equal?(source_line)
43
+ AST::FindMetaclassContaining.call(ast: ast, target: node)
57
44
  end
58
45
 
59
46
  def name?(node)
@@ -8,12 +8,9 @@ module Mutant
8
8
 
9
9
  # New singleton method matcher
10
10
  #
11
- # @param [Class, Module] scope
12
- # @param [Symbol] method_name
13
- #
14
11
  # @return [Matcher::Method::Singleton]
15
- def self.new(scope, method_name)
16
- super(scope, method_name, Evaluator)
12
+ def self.new(scope:, target_method:)
13
+ super(scope: scope, target_method: target_method, evaluator: Evaluator)
17
14
  end
18
15
 
19
16
  # Singleton method evaluator
@@ -27,14 +24,7 @@ module Mutant
27
24
  private
28
25
 
29
26
  def match?(node)
30
- n_defs?(node) && line?(node) && name?(node) && receiver?(node)
31
- end
32
-
33
- def line?(node)
34
- node
35
- .location
36
- .line
37
- .equal?(source_line)
27
+ name?(node) && receiver?(node)
38
28
  end
39
29
 
40
30
  def name?(node)
@@ -6,7 +6,7 @@ module Mutant
6
6
  class Method < self
7
7
  include AbstractType,
8
8
  Adamantium,
9
- Concord::Public.new(:scope, :target_method, :evaluator)
9
+ Anima.new(:scope, :target_method, :evaluator)
10
10
 
11
11
  SOURCE_LOCATION_WARNING_FORMAT =
12
12
  '%s does not have a valid source location, unable to emit subject'
@@ -20,7 +20,7 @@ module Mutant
20
20
  #
21
21
  # @return [Enumerable<Subject>]
22
22
  def call(env)
23
- evaluator.call(scope, target_method, env)
23
+ evaluator.call(scope: scope, target_method: target_method, env: env)
24
24
  end
25
25
 
26
26
  # Abstract method match evaluator
@@ -32,7 +32,7 @@ module Mutant
32
32
  include(
33
33
  AbstractType,
34
34
  Adamantium,
35
- Concord.new(:scope, :target_method, :env),
35
+ Anima.new(:scope, :target_method, :env),
36
36
  Procto,
37
37
  AST::NodePredicates
38
38
  )
@@ -80,7 +80,7 @@ module Mutant
80
80
  end
81
81
 
82
82
  def context
83
- Context.new(scope, source_path)
83
+ Context.new(scope: scope, source_path: source_path)
84
84
  end
85
85
 
86
86
  def ast
@@ -120,6 +120,11 @@ module Mutant
120
120
  def matched_view
121
121
  return if source_location.nil?
122
122
 
123
+ # This is a performance optimization when using --since to avoid the cost of parsing
124
+ # every source file that could possibly map to a subject. A more fine-grained filtering
125
+ # takes places later in the process.
126
+ return unless relevant_source_file?
127
+
123
128
  ast
124
129
  .on_line(source_line)
125
130
  .select { |view| view.node.type.eql?(self.class::MATCH_NODE_TYPE) && match?(view.node) }
@@ -127,6 +132,10 @@ module Mutant
127
132
  end
128
133
  memoize :matched_view
129
134
 
135
+ def relevant_source_file?
136
+ env.config.matcher.diffs.all? { |diff| diff.touches_path?(source_path) }
137
+ end
138
+
130
139
  def visibility
131
140
  # This can be cleaned up once we are on >ruby-3.0
132
141
  # Method#{public,private,protected}? exists there.
@@ -4,7 +4,7 @@ module Mutant
4
4
  class Matcher
5
5
  # Abstract base class for matcher that returns method subjects from scope
6
6
  class Methods < self
7
- include AbstractType, Concord.new(:scope)
7
+ include AbstractType, Anima.new(:scope)
8
8
 
9
9
  CANDIDATE_NAMES = %i[
10
10
  public_instance_methods
@@ -21,7 +21,9 @@ module Mutant
21
21
  # @return [Enumerable<Subject>]
22
22
  def call(env)
23
23
  Chain.new(
24
- methods(env).map { |method| matcher.new(scope, method) }
24
+ matchers: methods(env).map do |target_method|
25
+ matcher.new(scope: scope, target_method: target_method)
26
+ end
25
27
  ).call(env)
26
28
  end
27
29
 
@@ -4,7 +4,7 @@ module Mutant
4
4
  class Matcher
5
5
  # Matcher for specific namespace
6
6
  class Namespace < self
7
- include Concord::Public.new(:expression)
7
+ include Anima.new(:expression)
8
8
 
9
9
  # Enumerate subjects
10
10
  #
@@ -13,7 +13,7 @@ module Mutant
13
13
  # @return [Enumerable<Subject>]
14
14
  def call(env)
15
15
  Chain.new(
16
- matched_scopes(env).map { |scope| Scope.new(scope.raw) }
16
+ matchers: matched_scopes(env).map { |scope| Scope.new(scope: scope.raw) }
17
17
  ).call(env)
18
18
  end
19
19
 
@@ -9,7 +9,7 @@ module Mutant
9
9
  # to hook in custom matchers. In that case the scope matchers to expand
10
10
  # should be passed as arguments to the constructor.
11
11
  class Scope < self
12
- include Concord.new(:scope)
12
+ include Anima.new(:scope)
13
13
 
14
14
  MATCHERS = [
15
15
  Matcher::Methods::Singleton,
@@ -25,13 +25,13 @@ module Mutant
25
25
  #
26
26
  # @return [Enumerable<Subject>]
27
27
  def call(env)
28
- Chain.new(effective_matchers).call(env)
28
+ Chain.new(matchers: effective_matchers).call(env)
29
29
  end
30
30
 
31
31
  private
32
32
 
33
33
  def effective_matchers
34
- MATCHERS.map { |matcher| matcher.new(scope) }
34
+ MATCHERS.map { |matcher| matcher.new(scope: scope) }
35
35
  end
36
36
 
37
37
  end # Scope
@@ -4,7 +4,7 @@ module Mutant
4
4
  class Matcher
5
5
  # Matcher returning subjects already known at its creation time
6
6
  class Static
7
- include Concord.new(:subjects)
7
+ include Anima.new(:subjects)
8
8
 
9
9
  # Call matcher
10
10
  #
@@ -20,8 +20,8 @@ module Mutant
20
20
  # @return [Matcher]
21
21
  def self.from_config(config)
22
22
  Filter.new(
23
- Chain.new(config.subjects.map(&:matcher)),
24
- method(:allowed_subject?).curry.call(config)
23
+ matcher: Chain.new(matchers: config.subjects.map(&:matcher)),
24
+ predicate: method(:allowed_subject?).curry.call(config)
25
25
  )
26
26
  end
27
27
 
@@ -31,7 +31,9 @@ module Mutant
31
31
  private_class_method :allowed_subject?
32
32
 
33
33
  def self.select_subject?(config, subject)
34
- config.subject_filters.all? { |filter| filter.call(subject) }
34
+ config.diffs.all? do |diff|
35
+ diff.touches?(subject.source_path, subject.source_lines)
36
+ end
35
37
  end
36
38
  private_class_method :select_subject?
37
39
 
@@ -5,7 +5,7 @@ module Mutant
5
5
  class Example
6
6
  # Example verification
7
7
  class Verification
8
- include Adamantium, Concord.new(:example, :mutations)
8
+ include Adamantium, Anima.new(:example, :mutations)
9
9
 
10
10
  # Test if mutation was verified successfully
11
11
  #
@@ -94,7 +94,7 @@ module Mutant
94
94
 
95
95
  def missing
96
96
  (example.expected.map(&:node) - mutations.map(&:node)).map do |node|
97
- Mutation::Evil.new(example, node)
97
+ Mutation::Evil.new(subject: example, node: node)
98
98
  end
99
99
  end
100
100
  memoize :missing
@@ -22,7 +22,7 @@ module Mutant
22
22
  #
23
23
  # @return [Verification]
24
24
  def verification
25
- Verification.new(self, generated)
25
+ Verification.new(example: self, mutations: generated)
26
26
  end
27
27
  memoize :verification
28
28
 
@@ -38,8 +38,8 @@ module Mutant
38
38
  # @return [Context]
39
39
  def context
40
40
  Context.new(
41
- Object,
42
- location.path
41
+ scope: Object,
42
+ source_path: location.path
43
43
  )
44
44
  end
45
45
 
@@ -59,7 +59,7 @@ module Mutant
59
59
  config: Mutation::Config::DEFAULT,
60
60
  node: node
61
61
  ).map do |node|
62
- Mutation::Evil.new(self, node)
62
+ Mutation::Evil.new(subject: self, node: node)
63
63
  end
64
64
  end
65
65
  memoize :generated
@@ -13,16 +13,22 @@ module Mutant
13
13
  ignore_pattern = Transform::Block.capture('ignore pattern', &AST::Pattern.method(:parse))
14
14
 
15
15
  TRANSFORM = Transform::Sequence.new(
16
- [
16
+ steps: [
17
17
  Transform::Hash.new(
18
18
  optional: [
19
- Transform::Hash::Key.new('ignore_patterns', Transform::Array.new(ignore_pattern)),
20
- Transform::Hash::Key.new('timeout', Transform::FLOAT)
19
+ Transform::Hash::Key.new(
20
+ transform: Transform::Array.new(transform: ignore_pattern),
21
+ value: 'ignore_patterns'
22
+ ),
23
+ Transform::Hash::Key.new(
24
+ transform: Transform::FLOAT,
25
+ value: 'timeout'
26
+ )
21
27
  ],
22
28
  required: []
23
29
  ),
24
30
  Transform::Hash::Symbolize.new,
25
- Transform::Success.new(DEFAULT.method(:with))
31
+ Transform::Success.new(block: DEFAULT.method(:with))
26
32
  ]
27
33
  )
28
34
 
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mutant
4
+ class Mutation
5
+ module Runner
6
+ class Sink
7
+ include Anima.new(:env)
8
+
9
+ # Initialize object
10
+ #
11
+ # @return [undefined]
12
+ def initialize(*)
13
+ super
14
+ @start = env.world.timer.now
15
+ @subject_results = {}
16
+ end
17
+
18
+ # Runner status
19
+ #
20
+ # @return [Result::Env]
21
+ def status
22
+ Result::Env.new(
23
+ env: env,
24
+ runtime: env.world.timer.now - @start,
25
+ subject_results: @subject_results.values
26
+ )
27
+ end
28
+
29
+ # Test if scheduling stopped
30
+ #
31
+ # @return [Boolean]
32
+ def stop?
33
+ status.stop?
34
+ end
35
+
36
+ # Handle mutation finish
37
+ #
38
+ # @param [Result::MutationIndex] mutation_index_result
39
+ #
40
+ # @return [self]
41
+ def result(mutation_index_result)
42
+ mutation_result = mutation_result(mutation_index_result)
43
+
44
+ subject = mutation_result.mutation.subject
45
+
46
+ @subject_results[subject] = Result::Subject.new(
47
+ subject: subject,
48
+ coverage_results: previous_coverage_results(subject).dup << coverage_result(mutation_result),
49
+ tests: env.selections.fetch(subject)
50
+ )
51
+
52
+ self
53
+ end
54
+
55
+ private
56
+
57
+ def coverage_result(mutation_result)
58
+ Result::Coverage.new(
59
+ mutation_result: mutation_result,
60
+ criteria_result: mutation_result.criteria_result(env.config.coverage_criteria)
61
+ )
62
+ end
63
+
64
+ def mutation_result(mutation_index_result)
65
+ Result::Mutation.new(
66
+ isolation_result: mutation_index_result.isolation_result,
67
+ mutation: env.mutations.fetch(mutation_index_result.mutation_index),
68
+ runtime: mutation_index_result.runtime
69
+ )
70
+ end
71
+
72
+ def previous_coverage_results(subject)
73
+ subject_result = @subject_results.fetch(subject) { return EMPTY_ARRAY }
74
+ subject_result.coverage_results
75
+ end
76
+
77
+ end # Sink
78
+ end # Runner
79
+ end # Mutation
80
+ end # Mutant
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mutant
4
+ class Mutation
5
+ module Runner
6
+ # Run against env
7
+ #
8
+ # @return [Either<String, Result>]
9
+ def self.call(env)
10
+ reporter(env).start(env)
11
+
12
+ Either::Right.new(run_mutation_analysis(env))
13
+ end
14
+
15
+ def self.run_mutation_analysis(env)
16
+ reporter = reporter(env)
17
+
18
+ env
19
+ .record(:analysis) { run_driver(reporter, async_driver(env)) }
20
+ .tap { |result| env.record(:report) { reporter.report(result) } }
21
+ end
22
+ private_class_method :run_mutation_analysis
23
+
24
+ def self.async_driver(env)
25
+ Parallel.async(env.world, mutation_test_config(env))
26
+ end
27
+ private_class_method :async_driver
28
+
29
+ def self.run_driver(reporter, driver)
30
+ Signal.trap('INT') do
31
+ driver.stop
32
+ end
33
+
34
+ loop do
35
+ status = driver.wait_timeout(reporter.delay)
36
+ break status.payload if status.done?
37
+ reporter.progress(status)
38
+ end
39
+ end
40
+ private_class_method :run_driver
41
+
42
+ def self.mutation_test_config(env)
43
+ Parallel::Config.new(
44
+ block: env.method(:cover_index),
45
+ jobs: env.config.jobs,
46
+ on_process_start: env.method(:emit_mutation_worker_process_start),
47
+ process_name: 'mutant-worker-process',
48
+ sink: Sink.new(env: env),
49
+ source: Parallel::Source::Array.new(jobs: env.mutations.each_index.to_a),
50
+ thread_name: 'mutant-worker-thread'
51
+ )
52
+ end
53
+ private_class_method :mutation_test_config
54
+
55
+ def self.reporter(env)
56
+ env.config.reporter
57
+ end
58
+ private_class_method :reporter
59
+
60
+ end # Runner
61
+ end # Mutation
62
+ end # Mutant
@@ -4,7 +4,7 @@ module Mutant
4
4
  # Represent a mutated node with its subject
5
5
  class Mutation
6
6
  include AbstractType, Adamantium
7
- include Concord::Public.new(:subject, :node)
7
+ include Anima.new(:subject, :node)
8
8
 
9
9
  CODE_DELIMITER = "\0"
10
10
  CODE_RANGE = (..4).freeze
@@ -48,7 +48,7 @@ module Mutant
48
48
  def mutate_body_receiver
49
49
  return if n_lambda?(send) || !n_send?(body)
50
50
 
51
- body_meta = AST::Meta::Send.new(body)
51
+ body_meta = AST::Meta::Send.new(node: body)
52
52
 
53
53
  emit(s(:send, send, body_meta.selector, *body_meta.arguments))
54
54
  end
@@ -56,7 +56,7 @@ module Mutant
56
56
  def valid_send_mutation?(node)
57
57
  return unless n_send?(node)
58
58
 
59
- last = AST::Meta::Send.new(node).arguments.last
59
+ last = AST::Meta::Send.new(node: node).arguments.last
60
60
 
61
61
  !last&.type.equal?(:block_pass)
62
62
  end
@@ -23,7 +23,7 @@ module Mutant
23
23
 
24
24
  def emit_optarg_body_assignments
25
25
  arguments.children.each do |argument|
26
- next unless n_optarg?(argument) && AST::Meta::Optarg.new(argument).used?
26
+ next unless n_optarg?(argument) && AST::Meta::Optarg.new(node: argument).used?
27
27
 
28
28
  emit_body_prepend(s(:lvasgn, *argument))
29
29
  end
@@ -5,6 +5,7 @@ module Mutant
5
5
  class Node
6
6
  # Mutator for if nodes
7
7
  class If < self
8
+ FLOW_MODIFIER = %i[return next break].to_set.freeze
8
9
 
9
10
  handle(:if)
10
11
 
@@ -43,6 +44,14 @@ module Mutant
43
44
  emit_type(condition, nil, else_branch)
44
45
  end
45
46
 
47
+ def emit_type(_condition, if_branch, else_branch)
48
+ super unless ternary? && (if_branch.nil? || else_branch.nil?)
49
+ end
50
+
51
+ def ternary?
52
+ parent && FLOW_MODIFIER.include?(parent.node.type)
53
+ end
54
+
46
55
  end # If
47
56
  end # Node
48
57
  end # Mutator
@@ -25,7 +25,7 @@ module Mutant
25
25
  def mutate_rescue_bodies
26
26
  children_indices(RESCUE_INDICES).each do |index|
27
27
  mutate_child(index)
28
- resbody_body = AST::Meta::Resbody.new(children.fetch(index)).body
28
+ resbody_body = AST::Meta::Resbody.new(node: children.fetch(index)).body
29
29
  emit_concat(resbody_body) if resbody_body
30
30
  end
31
31
  end
@@ -79,7 +79,7 @@ module Mutant
79
79
  end
80
80
 
81
81
  def meta
82
- AST::Meta::Send.new(node)
82
+ AST::Meta::Send.new(node: node)
83
83
  end
84
84
  memoize :meta
85
85
 
@@ -173,7 +173,7 @@ module Mutant
173
173
 
174
174
  return unless dynamic_selector && n_sym?(dynamic_selector)
175
175
 
176
- method_name = AST::Meta::Symbol.new(dynamic_selector).name
176
+ method_name = AST::Meta::Symbol.new(node: dynamic_selector).name
177
177
 
178
178
  emit(s(node.type, receiver, method_name, *actual_arguments))
179
179
  end
@@ -194,7 +194,7 @@ module Mutant
194
194
  def emit_double_negation_mutation
195
195
  return unless selector.equal?(:!) && n_send?(receiver)
196
196
 
197
- negated = AST::Meta::Send.new(meta.receiver)
197
+ negated = AST::Meta::Send.new(node: receiver)
198
198
  emit(negated.receiver) if negated.selector.equal?(:!)
199
199
  end
200
200
 
@@ -223,7 +223,7 @@ module Mutant
223
223
  def emit_const_get_mutation
224
224
  return unless selector.equal?(:const_get) && n_sym?(arguments.first)
225
225
 
226
- emit(s(:const, receiver, AST::Meta::Symbol.new(arguments.first).name))
226
+ emit(s(:const, receiver, AST::Meta::Symbol.new(node: arguments.first).name))
227
227
  end
228
228
 
229
229
  def emit_selector_replacement
@@ -13,10 +13,10 @@ module Mutant
13
13
  end
14
14
 
15
15
  class Registry
16
- include Concord.new(:contents)
16
+ include Anima.new(:contents)
17
17
 
18
18
  def initialize
19
- super({})
19
+ super(contents: {})
20
20
  end
21
21
 
22
22
  def register(expression_class, mutator_class)
@@ -27,7 +27,7 @@ module Mutant
27
27
 
28
28
  # Job source backed by a finite array
29
29
  class Array
30
- include Concord.new(:jobs)
30
+ include Anima.new(:jobs)
31
31
 
32
32
  # Initialize objecto
33
33
  #