mutant 0.11.18 → 0.11.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) 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 +2 -2
  10. data/lib/mutant/cli/command/environment/run.rb +1 -1
  11. data/lib/mutant/cli/command/environment.rb +1 -3
  12. data/lib/mutant/cli/command/util.rb +6 -6
  13. data/lib/mutant/config/coverage_criteria.rb +13 -4
  14. data/lib/mutant/config.rb +51 -24
  15. data/lib/mutant/context.rb +1 -6
  16. data/lib/mutant/env.rb +1 -1
  17. data/lib/mutant/expression/method.rb +6 -3
  18. data/lib/mutant/expression/methods.rb +2 -2
  19. data/lib/mutant/expression/namespace.rb +2 -2
  20. data/lib/mutant/expression/parser.rb +1 -1
  21. data/lib/mutant/hooks.rb +4 -4
  22. data/lib/mutant/isolation/fork.rb +1 -1
  23. data/lib/mutant/license/subscription/commercial.rb +3 -3
  24. data/lib/mutant/license/subscription/opensource.rb +5 -9
  25. data/lib/mutant/license/subscription.rb +1 -1
  26. data/lib/mutant/matcher/chain.rb +1 -1
  27. data/lib/mutant/matcher/config.rb +10 -4
  28. data/lib/mutant/matcher/descendants.rb +1 -1
  29. data/lib/mutant/matcher/filter.rb +1 -1
  30. data/lib/mutant/matcher/method/instance.rb +9 -4
  31. data/lib/mutant/matcher/method/metaclass.rb +4 -17
  32. data/lib/mutant/matcher/method/singleton.rb +3 -13
  33. data/lib/mutant/matcher/method.rb +4 -4
  34. data/lib/mutant/matcher/methods.rb +4 -2
  35. data/lib/mutant/matcher/namespace.rb +2 -2
  36. data/lib/mutant/matcher/scope.rb +3 -3
  37. data/lib/mutant/matcher/static.rb +1 -1
  38. data/lib/mutant/matcher.rb +2 -2
  39. data/lib/mutant/meta/example/verification.rb +2 -2
  40. data/lib/mutant/meta/example.rb +4 -4
  41. data/lib/mutant/mutation/config.rb +10 -4
  42. data/lib/mutant/mutation/runner/sink.rb +80 -0
  43. data/lib/mutant/mutation/runner.rb +61 -0
  44. data/lib/mutant/mutation.rb +1 -1
  45. data/lib/mutant/mutator/node/block.rb +2 -2
  46. data/lib/mutant/mutator/node/define.rb +1 -1
  47. data/lib/mutant/mutator/node/if.rb +9 -0
  48. data/lib/mutant/mutator/node/rescue.rb +1 -1
  49. data/lib/mutant/mutator/node/send.rb +4 -4
  50. data/lib/mutant/mutator/regexp.rb +2 -2
  51. data/lib/mutant/parallel/source.rb +1 -1
  52. data/lib/mutant/pipe.rb +3 -3
  53. data/lib/mutant/registry.rb +2 -2
  54. data/lib/mutant/reporter/cli/format.rb +3 -3
  55. data/lib/mutant/reporter/cli/printer.rb +2 -2
  56. data/lib/mutant/reporter/cli.rb +4 -4
  57. data/lib/mutant/reporter/sequence.rb +1 -1
  58. data/lib/mutant/repository.rb +1 -1
  59. data/lib/mutant/result.rb +1 -1
  60. data/lib/mutant/scope.rb +1 -1
  61. data/lib/mutant/selector/expression.rb +1 -1
  62. data/lib/mutant/subject.rb +2 -2
  63. data/lib/mutant/timer.rb +3 -3
  64. data/lib/mutant/transform.rb +14 -14
  65. data/lib/mutant/version.rb +1 -1
  66. data/lib/mutant.rb +13 -11
  67. metadata +9 -9
  68. data/lib/mutant/runner/sink.rb +0 -78
  69. data/lib/mutant/runner.rb +0 -60
@@ -51,7 +51,7 @@ module Mutant
51
51
  env.with(
52
52
  integration: integration,
53
53
  mutations: mutations,
54
- selector: Selector::Expression.new(integration),
54
+ selector: Selector::Expression.new(integration: integration),
55
55
  subjects: selected_subjects
56
56
  )
57
57
  end
@@ -115,7 +115,7 @@ module Mutant
115
115
 
116
116
  scopes = env.world.object_space.each_object(Module).with_object([]) do |scope, aggregate|
117
117
  expression = expression(config.reporter, config.expression_parser, scope) || next
118
- aggregate << Scope.new(scope, expression)
118
+ aggregate << Scope.new(raw: scope, expression: expression)
119
119
  end
120
120
 
121
121
  scopes.sort_by { |scope| scope.expression.syntax }
@@ -36,7 +36,7 @@ module Mutant
36
36
  License.call(world)
37
37
  .bind { bootstrap }
38
38
  .bind(&method(:validate_tests))
39
- .bind(&Runner.public_method(:call))
39
+ .bind(&Mutation::Runner.public_method(:call))
40
40
  .bind(&method(:from_result))
41
41
  end
42
42
 
@@ -105,9 +105,7 @@ module Mutant
105
105
  parser.on('--since REVISION', 'Only select subjects touched since REVISION') do |revision|
106
106
  add_matcher(
107
107
  :subject_filters,
108
- Repository::SubjectFilter.new(
109
- Repository::Diff.new(to: revision, world: world)
110
- )
108
+ Repository::SubjectFilter.new(diff: Repository::Diff.new(to: revision, world: world))
111
109
  )
112
110
  end
113
111
  end
@@ -35,7 +35,7 @@ module Mutant
35
35
  memoize :node
36
36
 
37
37
  class File < self
38
- include Concord.new(:pathname, :source)
38
+ include Anima.new(:pathname, :source)
39
39
 
40
40
  public :source
41
41
 
@@ -45,7 +45,7 @@ module Mutant
45
45
  end # File
46
46
 
47
47
  class Source < self
48
- include Concord::Public.new(:source)
48
+ include Anima.new(:source)
49
49
 
50
50
  def identification
51
51
  '<cli-source>'
@@ -62,7 +62,7 @@ module Mutant
62
62
 
63
63
  def add_target_options(parser)
64
64
  parser.on('-e', '--evaluate SOURCE') do |source|
65
- @targets << Target::Source.new(source)
65
+ @targets << Target::Source.new(source: source)
66
66
  end
67
67
 
68
68
  parser.on('-i', '--ignore-pattern AST_PATTERN') do |pattern|
@@ -78,8 +78,8 @@ module Mutant
78
78
  node: target.node
79
79
  ).each do |mutation|
80
80
  Reporter::CLI::Printer::Mutation.call(
81
- world.stdout,
82
- Mutant::Mutation::Evil.new(target, mutation)
81
+ object: Mutant::Mutation::Evil.new(subject: target, node: mutation),
82
+ output: world.stdout
83
83
  )
84
84
  end
85
85
  end
@@ -97,7 +97,7 @@ module Mutant
97
97
  end
98
98
 
99
99
  def read_file(pathname)
100
- Either::Right.new(Target::File.new(pathname, pathname.read))
100
+ Either::Right.new(Target::File.new(pathname: pathname, source: pathname.read))
101
101
  rescue StandardError => exception
102
102
  Either::Left.new("Cannot read file: #{exception}")
103
103
  end
@@ -20,12 +20,21 @@ module Mutant
20
20
 
21
21
  TRANSFORM =
22
22
  Transform::Sequence.new(
23
- [
23
+ steps: [
24
24
  Transform::Hash.new(
25
25
  optional: [
26
- Transform::Hash::Key.new('process_abort', Transform::BOOLEAN),
27
- Transform::Hash::Key.new('test_result', Transform::BOOLEAN),
28
- Transform::Hash::Key.new('timeout', Transform::BOOLEAN)
26
+ Transform::Hash::Key.new(
27
+ transform: Transform::BOOLEAN,
28
+ value: 'process_abort'
29
+ ),
30
+ Transform::Hash::Key.new(
31
+ transform: Transform::BOOLEAN,
32
+ value: 'test_result'
33
+ ),
34
+ Transform::Hash::Key.new(
35
+ transform: Transform::BOOLEAN,
36
+ value: 'timeout'
37
+ )
29
38
  ],
30
39
  required: []
31
40
  ),
data/lib/mutant/config.rb CHANGED
@@ -101,8 +101,8 @@ module Mutant
101
101
  def self.load_contents(env, path)
102
102
  Transform::Named
103
103
  .new(
104
- path.to_s,
105
- sequence(env.config.reporter)
104
+ name: path.to_s,
105
+ transform: sequence(env.config.reporter)
106
106
  )
107
107
  .call(path)
108
108
  .lmap(&:compact_message)
@@ -111,11 +111,11 @@ module Mutant
111
111
 
112
112
  def self.sequence(reporter)
113
113
  Transform::Sequence.new(
114
- [
115
- Transform::Exception.new(SystemCallError, :read.to_proc),
116
- Transform::Exception.new(YAML::SyntaxError, YAML.public_method(:safe_load)),
117
- Transform::Primitive.new(Hash),
118
- Transform::Success.new(->(hash) { deprecations(reporter, hash) }),
114
+ steps: [
115
+ Transform::Exception.new(error_class: SystemCallError, block: :read.to_proc),
116
+ Transform::Exception.new(error_class: YAML::SyntaxError, block: YAML.public_method(:safe_load)),
117
+ Transform::Primitive.new(primitive: Hash),
118
+ Transform::Success.new(block: ->(hash) { deprecations(reporter, hash) }),
119
119
  *TRANSFORMS
120
120
  ]
121
121
  )
@@ -130,10 +130,10 @@ module Mutant
130
130
  end
131
131
 
132
132
  PATHNAME_ARRAY = Transform::Array.new(
133
- Transform::Sequence.new(
134
- [
133
+ transform: Transform::Sequence.new(
134
+ steps: [
135
135
  Transform::STRING,
136
- Transform::Exception.new(ArgumentError, Pathname.public_method(:new))
136
+ Transform::Exception.new(error_class: ArgumentError, block: Pathname.public_method(:new))
137
137
  ]
138
138
  )
139
139
  )
@@ -170,24 +170,51 @@ module Mutant
170
170
  TRANSFORMS = [
171
171
  Transform::Hash.new(
172
172
  optional: [
173
- Transform::Hash::Key.new('coverage_criteria', ->(value) { CoverageCriteria::TRANSFORM.call(value) }),
174
173
  Transform::Hash::Key.new(
175
- 'environment_variables',
176
- Transform::Sequence.new(
177
- [
178
- Transform::Primitive.new(Hash),
174
+ transform: ->(value) { CoverageCriteria::TRANSFORM.call(value) },
175
+ value: 'coverage_criteria'
176
+ ),
177
+ Transform::Hash::Key.new(
178
+ transform: Transform::Sequence.new(
179
+ steps: [
180
+ Transform::Primitive.new(primitive: Hash),
179
181
  Transform::Block.capture(:environment_variables, &method(:parse_environment_variables))
180
182
  ]
181
- )
183
+ ),
184
+ value: 'environment_variables'
185
+ ),
186
+ Transform::Hash::Key.new(
187
+ transform: Transform::BOOLEAN,
188
+ value: 'fail_fast'
189
+ ),
190
+ Transform::Hash::Key.new(
191
+ transform: PATHNAME_ARRAY,
192
+ value: 'hooks'
193
+ ),
194
+ Transform::Hash::Key.new(
195
+ transform: Transform::STRING_ARRAY,
196
+ value: 'includes'
182
197
  ),
183
- Transform::Hash::Key.new('fail_fast', Transform::BOOLEAN),
184
- Transform::Hash::Key.new('hooks', PATHNAME_ARRAY),
185
- Transform::Hash::Key.new('includes', Transform::STRING_ARRAY),
186
- Transform::Hash::Key.new('integration', Transform::STRING),
187
- Transform::Hash::Key.new('jobs', Transform::INTEGER),
188
- Transform::Hash::Key.new('matcher', Matcher::Config::LOADER),
189
- Transform::Hash::Key.new('mutation', Mutation::Config::TRANSFORM),
190
- Transform::Hash::Key.new('requires', Transform::STRING_ARRAY)
198
+ Transform::Hash::Key.new(
199
+ transform: Transform::STRING,
200
+ value: 'integration'
201
+ ),
202
+ Transform::Hash::Key.new(
203
+ transform: Transform::INTEGER,
204
+ value: 'jobs'
205
+ ),
206
+ Transform::Hash::Key.new(
207
+ transform: Matcher::Config::LOADER,
208
+ value: 'matcher'
209
+ ),
210
+ Transform::Hash::Key.new(
211
+ transform: Mutation::Config::TRANSFORM,
212
+ value: 'mutation'
213
+ ),
214
+ Transform::Hash::Key.new(
215
+ transform: Transform::STRING_ARRAY,
216
+ value: 'requires'
217
+ )
191
218
  ],
192
219
  required: []
193
220
  ),
@@ -3,7 +3,7 @@
3
3
  module Mutant
4
4
  # An abstract context where mutations can be applied to.
5
5
  class Context
6
- include Adamantium, Concord::Public.new(:scope, :source_path)
6
+ include Adamantium, Anima.new(:scope, :source_path)
7
7
  extend AST::Sexp
8
8
 
9
9
  NAMESPACE_DELIMITER = '::'
@@ -74,11 +74,6 @@ module Mutant
74
74
  end
75
75
  memoize :match_expressions
76
76
 
77
- # Scope wrapped by context
78
- #
79
- # @return [Module|Class]
80
- attr_reader :scope
81
-
82
77
  private
83
78
 
84
79
  def name_nesting
data/lib/mutant/env.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mutant
4
- # Abstract base class for mutant environments
4
+ # Mutation testing execution environment
5
5
  class Env
6
6
  include Adamantium, Anima.new(
7
7
  :config,
@@ -41,11 +41,14 @@ module Mutant
41
41
  # @return [Matcher]
42
42
  def matcher
43
43
  matcher_candidates = MATCHERS.fetch(scope_symbol)
44
- .map { |submatcher| submatcher.new(scope) }
44
+ .map { |submatcher| submatcher.new(scope: scope) }
45
45
 
46
- methods_matcher = Matcher::Chain.new(matcher_candidates)
46
+ methods_matcher = Matcher::Chain.new(matchers: matcher_candidates)
47
47
 
48
- Matcher::Filter.new(methods_matcher, ->(subject) { subject.expression.eql?(self) })
48
+ Matcher::Filter.new(
49
+ matcher: methods_matcher,
50
+ predicate: ->(subject) { subject.expression.eql?(self) }
51
+ )
49
52
  end
50
53
 
51
54
  def self.try_parse(input)
@@ -36,9 +36,9 @@ module Mutant
36
36
  # @return [Matcher::Method]
37
37
  def matcher
38
38
  matcher_candidates = MATCHERS.fetch(scope_symbol)
39
- .map { |submatcher| submatcher.new(scope) }
39
+ .map { |submatcher| submatcher.new(scope: scope) }
40
40
 
41
- Matcher::Chain.new(matcher_candidates)
41
+ Matcher::Chain.new(matchers: matcher_candidates)
42
42
  end
43
43
 
44
44
  # Length of match with other expression
@@ -35,7 +35,7 @@ module Mutant
35
35
  #
36
36
  # @return [Matcher]
37
37
  def matcher
38
- Matcher::Namespace.new(self)
38
+ Matcher::Namespace.new(expression: self)
39
39
  end
40
40
 
41
41
  # Length of match with other expression
@@ -69,7 +69,7 @@ module Mutant
69
69
  scope = find_scope
70
70
 
71
71
  if scope
72
- Matcher::Scope.new(scope)
72
+ Matcher::Scope.new(scope: scope)
73
73
  else
74
74
  Matcher::Null.new
75
75
  end
@@ -3,7 +3,7 @@
3
3
  module Mutant
4
4
  class Expression
5
5
  class Parser
6
- include Concord.new(:types)
6
+ include Anima.new(:types)
7
7
 
8
8
  # Parse expression
9
9
  #
data/lib/mutant/hooks.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Mutant
4
4
  class Hooks
5
- include Adamantium, Concord::Public.new(:map)
5
+ include Adamantium, Anima.new(:map)
6
6
 
7
7
  DEFAULTS = %i[
8
8
  env_infection_pre
@@ -23,12 +23,12 @@ module Mutant
23
23
  end
24
24
 
25
25
  def self.empty
26
- new(DEFAULTS)
26
+ new(map: DEFAULTS)
27
27
  end
28
28
 
29
29
  def merge(other)
30
30
  self.class.new(
31
- other.map.merge(map) { |_key, new, old| (old + new).freeze }.freeze
31
+ map: other.map.merge(map) { |_key, new, old| (old + new).freeze }.freeze
32
32
  )
33
33
  end
34
34
 
@@ -54,7 +54,7 @@ module Mutant
54
54
  end
55
55
 
56
56
  def to_hooks
57
- Hooks.new(@map.transform_values(&:freeze).freeze)
57
+ Hooks.new(map: @map.transform_values(&:freeze).freeze)
58
58
  end
59
59
  end # Builder
60
60
 
@@ -28,7 +28,7 @@ module Mutant
28
28
  # * Child process freezing after closing the pipes needs to be
29
29
  # detected by parent process.
30
30
  class Fork < self
31
- include(Adamantium, Concord.new(:world))
31
+ include(Adamantium, Anima.new(:world))
32
32
 
33
33
  READ_SIZE = 4096
34
34
 
@@ -5,14 +5,14 @@ module Mutant
5
5
  class Subscription
6
6
  class Commercial < self
7
7
  class Author
8
- include Concord.new(:email)
8
+ include Anima.new(:email)
9
9
 
10
10
  alias_method :to_s, :email
11
11
  public :to_s
12
12
  end
13
13
 
14
14
  def self.from_json(value)
15
- new(value.fetch('authors').map(&Author.public_method(:new)).to_set)
15
+ new(licensed: value.fetch('authors').to_set { |email| Author.new(email: email) })
16
16
  end
17
17
 
18
18
  def call(world)
@@ -43,7 +43,7 @@ module Mutant
43
43
  world
44
44
  .capture_stdout(command)
45
45
  .fmap(&:chomp)
46
- .fmap(&Author.public_method(:new))
46
+ .fmap { |email| Author.new(email: email) }
47
47
  .fmap { |value| Set.new([value]) }
48
48
  .from_right { Set.new }
49
49
  end
@@ -5,7 +5,7 @@ module Mutant
5
5
  class Subscription
6
6
  class Opensource < self
7
7
  class Repository
8
- include Concord.new(:host, :path)
8
+ include Anima.new(:host, :path)
9
9
 
10
10
  REMOTE_REGEXP = /\A[^\t]+\t(?<url>[^ ]+) \((?:fetch|push)\)\n\z/.freeze
11
11
  GIT_SSH_REGEXP = %r{\A[^@]+@(?<host>[^:/]+)[:/](?<path>.+?)(?:\.git)?\z}.freeze
@@ -18,7 +18,8 @@ module Mutant
18
18
  end
19
19
 
20
20
  def self.parse(input)
21
- new(*input.split('/', 2).map(&:downcase))
21
+ host, path = *input.split('/', 2).map(&:downcase)
22
+ new(host: host, path: path)
22
23
  end
23
24
 
24
25
  def self.parse_remote(input)
@@ -36,7 +37,7 @@ module Mutant
36
37
  fail "Unmatched git remote URL: #{input.inspect}"
37
38
  end
38
39
 
39
- new(match[:host], match[:path].downcase)
40
+ new(host: match[:host], path: match[:path].downcase)
40
41
  end
41
42
  private_class_method :parse_url
42
43
 
@@ -52,12 +53,7 @@ module Mutant
52
53
  end # Opensource
53
54
 
54
55
  def self.from_json(value)
55
- new(
56
- value
57
- .fetch('repositories')
58
- .map(&Repository.public_method(:parse))
59
- .to_set
60
- )
56
+ new(licensed: value.fetch('repositories').map(&Repository.public_method(:parse)).to_set)
61
57
  end
62
58
 
63
59
  def call(world)
@@ -3,7 +3,7 @@
3
3
  module Mutant
4
4
  module License
5
5
  class Subscription
6
- include Concord.new(:licensed)
6
+ include Anima.new(:licensed)
7
7
 
8
8
  FORMAT = <<~'MESSAGE'
9
9
  %<subscription_name>s subscription:
@@ -4,7 +4,7 @@ module Mutant
4
4
  class Matcher
5
5
  # Matcher chaining results of other matchers together
6
6
  class Chain < self
7
- include Concord.new(:matchers)
7
+ include Anima.new(:matchers)
8
8
 
9
9
  # Call matcher
10
10
  #
@@ -31,15 +31,21 @@ module Mutant
31
31
  Mutant::Config::DEFAULT.expression_parser.call(input)
32
32
  end
33
33
 
34
- expression_array = Transform::Array.new(expression)
34
+ expression_array = Transform::Array.new(transform: expression)
35
35
 
36
36
  LOADER =
37
37
  Transform::Sequence.new(
38
- [
38
+ steps: [
39
39
  Transform::Hash.new(
40
40
  optional: [
41
- Transform::Hash::Key.new('subjects', expression_array),
42
- Transform::Hash::Key.new('ignore', expression_array)
41
+ Transform::Hash::Key.new(
42
+ transform: expression_array,
43
+ value: 'subjects'
44
+ ),
45
+ Transform::Hash::Key.new(
46
+ transform: expression_array,
47
+ value: 'ignore'
48
+ )
43
49
  ],
44
50
  required: []
45
51
  ),
@@ -10,7 +10,7 @@ module Mutant
10
10
  const = env.world.try_const_get(const_name) or return EMPTY_ARRAY
11
11
 
12
12
  Chain.new(
13
- matched_scopes(env, const).map { |scope| Scope.new(scope.raw) }
13
+ matchers: matched_scopes(env, const).map { |scope| Scope.new(scope: scope.raw) }
14
14
  ).call(env)
15
15
  end
16
16
 
@@ -4,7 +4,7 @@ module Mutant
4
4
  class Matcher
5
5
  # Matcher filter
6
6
  class Filter < self
7
- include Concord.new(:matcher, :predicate)
7
+ include Anima.new(:matcher, :predicate)
8
8
 
9
9
  # Enumerate matches
10
10
  #
@@ -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
@@ -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