mutant 0.11.5 → 0.11.8

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.
@@ -45,7 +45,7 @@ module Mutant
45
45
  end
46
46
 
47
47
  def metaclass_containing(node)
48
- AST::FindMetaclassContaining.call(ast, node)
48
+ AST::FindMetaclassContaining.call(ast.node, node)
49
49
  end
50
50
 
51
51
  def line?(node)
@@ -99,6 +99,7 @@ module Mutant
99
99
  node = matched_node_path.last || return
100
100
 
101
101
  self.class::SUBJECT_CLASS.new(
102
+ config: Subject::Config.parse(ast.comment_associations.fetch(node, [])),
102
103
  context: context,
103
104
  node: node,
104
105
  visibility: visibility
@@ -106,7 +107,7 @@ module Mutant
106
107
  end
107
108
 
108
109
  def matched_node_path
109
- AST.find_last_path(ast, &method(:match?))
110
+ AST.find_last_path(ast.node, &method(:match?))
110
111
  end
111
112
  memoize :matched_node_path
112
113
 
@@ -26,7 +26,7 @@ module Mutant
26
26
  end
27
27
 
28
28
  def self.allowed_subject?(config, subject)
29
- select_subject?(config, subject) && !ignore_subject?(config, subject)
29
+ select_subject?(config, subject) && !ignore_subject?(config, subject) && !subject.inline_disabled?
30
30
  end
31
31
  private_class_method :allowed_subject?
32
32
 
@@ -7,7 +7,7 @@ module Mutant
7
7
  include Concord::Public.new(:subject, :node)
8
8
 
9
9
  CODE_DELIMITER = "\0"
10
- CODE_RANGE = (0..4).freeze
10
+ CODE_RANGE = (..4).freeze
11
11
 
12
12
  # Mutation identification code
13
13
  #
@@ -19,17 +19,27 @@ module Mutant
19
19
  end
20
20
 
21
21
  def emit_argument_presence
22
- emit_type unless removed_block_arg?(EMPTY_ARRAY)
22
+ emit_type unless removed_block_arg?(EMPTY_ARRAY) || forward_arg?
23
23
 
24
- Util::Array::Presence.call(children).each do |children|
25
- unless removed_block_arg?(children) || (children.one? && n_mlhs?(children.first))
26
- emit_type(*children)
24
+ children.each_with_index do |removed, index|
25
+ new_arguments = children.dup
26
+ new_arguments.delete_at(index)
27
+ unless n_forward_arg?(removed) || removed_block_arg?(new_arguments) || only_mlhs?(new_arguments)
28
+ emit_type(*new_arguments)
27
29
  end
28
30
  end
29
31
  end
30
32
 
31
- def removed_block_arg?(children)
32
- anonymous_block_arg? && children.none?(&ANONYMOUS_BLOCKARG_PRED)
33
+ def only_mlhs?(new_arguments)
34
+ new_arguments.one? && n_mlhs?(new_arguments.first)
35
+ end
36
+
37
+ def forward_arg?
38
+ children.last && n_forward_arg?(children.last)
39
+ end
40
+
41
+ def removed_block_arg?(new_arguments)
42
+ anonymous_block_arg? && new_arguments.none?(&ANONYMOUS_BLOCKARG_PRED)
33
43
  end
34
44
 
35
45
  def anonymous_block_arg?
@@ -47,7 +57,7 @@ module Mutant
47
57
  end
48
58
 
49
59
  def invalid_argument_replacement?(mutant, index)
50
- n_arg?(mutant) && children[0...index].any?(&method(:n_optarg?))
60
+ n_arg?(mutant) && children[...index].any?(&method(:n_optarg?))
51
61
  end
52
62
 
53
63
  def emit_mlhs_expansion
@@ -7,7 +7,7 @@ module Mutant
7
7
  # Mutator for attribute assignments
8
8
  class AttributeAssignment < self
9
9
 
10
- ATTRIBUTE_RANGE = (0..-2).freeze
10
+ ATTRIBUTE_RANGE = (..-2).freeze
11
11
 
12
12
  private_constant(*constants(false))
13
13
 
@@ -241,7 +241,9 @@ module Mutant
241
241
 
242
242
  argument = Mutant::Util.one(arguments)
243
243
 
244
- emit_propagation(argument) unless n_kwargs?(argument)
244
+ return if n_kwargs?(argument) || n_forwarded_args?(argument)
245
+
246
+ emit_propagation(argument)
245
247
  end
246
248
 
247
249
  def mutate_receiver
@@ -22,7 +22,7 @@ module Mutant
22
22
 
23
23
  def mutate_conditions
24
24
  conditions = children.length - 1
25
- children[0..-2].each_index do |index|
25
+ children[..-2].each_index do |index|
26
26
  delete_child(index) if conditions > 1
27
27
  mutate_child(index)
28
28
  end
data/lib/mutant/parser.rb CHANGED
@@ -5,6 +5,13 @@ module Mutant
5
5
  class Parser
6
6
  include Adamantium, Equalizer.new
7
7
 
8
+ class AST
9
+ include Anima.new(
10
+ :node,
11
+ :comment_associations
12
+ )
13
+ end
14
+
8
15
  # Initialize object
9
16
  #
10
17
  # @return [undefined]
@@ -18,7 +25,18 @@ module Mutant
18
25
  #
19
26
  # @return [AST::Node]
20
27
  def call(path)
21
- @cache[path] ||= Unparser.parse(path.read)
28
+ @cache[path] ||= parse(path.read)
29
+ end
30
+
31
+ private
32
+
33
+ def parse(source)
34
+ node, comments = Unparser.parse_with_comments(source)
35
+
36
+ AST.new(
37
+ node: node,
38
+ comment_associations: ::Parser::Source::Comment.associate_by_identity(node, comments)
39
+ )
22
40
  end
23
41
 
24
42
  end # Parser
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mutant
4
+ class Subject
5
+ class Config
6
+ include Adamantium, Anima.new(:inline_disable)
7
+
8
+ DEFAULT = new(inline_disable: false)
9
+
10
+ DISABLE_REGEXP = /(\s|^)mutant:disable(?:\s|$)/.freeze
11
+ SYNTAX_REGEXP = /\A(?:#|=begin\n)/.freeze
12
+
13
+ def self.parse(comments)
14
+ new(
15
+ inline_disable: comments.any? { |comment| DISABLE_REGEXP.match?(comment_body(comment)) }
16
+ )
17
+ end
18
+
19
+ def self.comment_body(comment)
20
+ comment.text.sub(SYNTAX_REGEXP, '')
21
+ end
22
+ private_class_method :comment_body
23
+ end # Config
24
+ end # Subject
25
+ end # Mutant
@@ -4,7 +4,7 @@ module Mutant
4
4
  # Subject of a mutation
5
5
  class Subject
6
6
  include AbstractType, Adamantium, Enumerable
7
- include Anima.new(:context, :node)
7
+ include Anima.new(:config, :context, :node)
8
8
 
9
9
  # Mutations for this subject
10
10
  #
@@ -19,6 +19,10 @@ module Mutant
19
19
  end
20
20
  memoize :mutations
21
21
 
22
+ def inline_disabled?
23
+ config.inline_disable
24
+ end
25
+
22
26
  # Source path
23
27
  #
24
28
  # @return [Pathname]
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Mutant
4
4
  # Current mutant version
5
- VERSION = '0.11.5'
5
+ VERSION = '0.11.8'
6
6
  end # Mutant
data/lib/mutant.rb CHANGED
@@ -164,6 +164,7 @@ require 'mutant/loader'
164
164
  require 'mutant/context'
165
165
  require 'mutant/scope'
166
166
  require 'mutant/subject'
167
+ require 'mutant/subject/config'
167
168
  require 'mutant/subject/method'
168
169
  require 'mutant/subject/method/instance'
169
170
  require 'mutant/subject/method/singleton'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mutant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.5
4
+ version: 0.11.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-03 00:00:00.000000000 Z
11
+ date: 2022-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diff-lcs
@@ -44,20 +44,20 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '2.0'
47
+ version: '2.3'
48
48
  - - ">="
49
49
  - !ruby/object:Gem::Version
50
- version: 2.0.3
50
+ version: 2.3.1
51
51
  type: :runtime
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
55
  - - "~>"
56
56
  - !ruby/object:Gem::Version
57
- version: '2.0'
57
+ version: '2.3'
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: 2.0.3
60
+ version: 2.3.1
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: sorbet-runtime
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -78,14 +78,14 @@ dependencies:
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: 0.6.4
81
+ version: 0.6.5
82
82
  type: :runtime
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: 0.6.4
88
+ version: 0.6.5
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: parallel
91
91
  requirement: !ruby/object:Gem::Requirement
@@ -353,6 +353,7 @@ files:
353
353
  - lib/mutant/selector/expression.rb
354
354
  - lib/mutant/selector/null.rb
355
355
  - lib/mutant/subject.rb
356
+ - lib/mutant/subject/config.rb
356
357
  - lib/mutant/subject/method.rb
357
358
  - lib/mutant/subject/method/instance.rb
358
359
  - lib/mutant/subject/method/metaclass.rb
@@ -385,7 +386,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
385
386
  - !ruby/object:Gem::Version
386
387
  version: '0'
387
388
  requirements: []
388
- rubygems_version: 3.1.6
389
+ rubygems_version: 3.2.33
389
390
  signing_key:
390
391
  specification_version: 4
391
392
  summary: ''