mutant 0.8.20 → 0.8.21

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +0 -2
  3. data/Changelog.md +4 -0
  4. data/Gemfile.lock +17 -18
  5. data/README.md +21 -4
  6. data/config/rubocop.yml +3 -4
  7. data/docs/mutant-minitest.md +4 -2
  8. data/docs/mutant-rspec.md +104 -14
  9. data/lib/mutant.rb +2 -1
  10. data/lib/mutant/ast/meta/send.rb +1 -15
  11. data/lib/mutant/ast/types.rb +47 -22
  12. data/lib/mutant/meta.rb +2 -2
  13. data/lib/mutant/meta/example.rb +2 -1
  14. data/lib/mutant/meta/example/dsl.rb +12 -9
  15. data/lib/mutant/meta/example/verification.rb +34 -16
  16. data/lib/mutant/mutator/node.rb +7 -0
  17. data/lib/mutant/mutator/node/argument.rb +0 -1
  18. data/lib/mutant/mutator/node/arguments.rb +13 -1
  19. data/lib/mutant/mutator/node/block.rb +1 -1
  20. data/lib/mutant/mutator/node/index.rb +129 -0
  21. data/lib/mutant/mutator/node/noop.rb +1 -1
  22. data/lib/mutant/mutator/node/procarg_zero.rb +45 -0
  23. data/lib/mutant/mutator/node/send.rb +1 -27
  24. data/lib/mutant/parser.rb +1 -1
  25. data/lib/mutant/reporter/cli/printer/mutation_result.rb +34 -32
  26. data/lib/mutant/version.rb +1 -1
  27. data/lib/mutant/warning_filter.rb +1 -1
  28. data/lib/mutant/zombifier.rb +1 -1
  29. data/meta/block.rb +22 -3
  30. data/meta/index.rb +133 -0
  31. data/meta/indexasgn.rb +31 -0
  32. data/meta/lambda.rb +9 -0
  33. data/meta/regexp.rb +0 -7
  34. data/meta/regexp/character_types.rb +1 -1
  35. data/meta/send.rb +0 -146
  36. data/mutant.gemspec +2 -3
  37. data/spec/spec_helper.rb +1 -1
  38. data/spec/support/corpus.rb +28 -12
  39. data/spec/unit/mutant/ast/meta/send/proc_predicate_spec.rb +1 -1
  40. data/spec/unit/mutant/ast/meta/send/receiver_possible_top_level_const_predicate_spec.rb +1 -1
  41. data/spec/unit/mutant/ast/meta/send_spec.rb +6 -8
  42. data/spec/unit/mutant/meta/example/dsl_spec.rb +9 -9
  43. data/spec/unit/mutant/meta/example/verification_spec.rb +36 -4
  44. data/spec/unit/mutant/meta/example_spec.rb +4 -4
  45. data/spec/unit/mutant/mutator/node_spec.rb +12 -7
  46. data/spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb +3 -1
  47. data/spec/unit/mutant/subject_spec.rb +1 -1
  48. data/spec/unit/mutant/zombifier_spec.rb +1 -1
  49. metadata +12 -24
  50. data/config/flay.yml +0 -3
  51. data/config/flog.yml +0 -2
  52. data/lib/mutant/mutator/node/send/index.rb +0 -52
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71ac041e8b933f1efd758494731566ff133404300a860e41362211c607fe5f0f
4
- data.tar.gz: d49c6b977cbe88912d3c93203473a3704c4287737fbe3fff14a46aaf951bc2a9
3
+ metadata.gz: c6bbd702d5eebd39b5e1b55fe8ec3ee4a8c6cce207046b014340345409ac1478
4
+ data.tar.gz: d95121d3aff3ae3c764036a0b36229a2332aaf3b2f72b358b9098c6a694a0cac
5
5
  SHA512:
6
- metadata.gz: 5f241945cdedc4d38fd3328b4321c0e685d87c3102d73c122baae658daf5b9b42423b9aa12070e23e42abae6f3232f5752d67cdc27c49c16d8fa150c259655be
7
- data.tar.gz: 1400ba91b8275ee4c6a12af48ed05bd6bf1a0c290e16a227f87a81a251e536d269c71d9ca8d9d7fc4e4ba6b7dc02d3360061b2809fb21c58fcef9c7d708b89b6
6
+ metadata.gz: ef46516211349d4abad952ed4f285b2ba9d5d638fbfb666cd607cd9f46135acae8d06389a7658eaa3e25de243d1fec7ce6b3ae9fca83cfa1cdd83cb30cd4bb78
7
+ data.tar.gz: 12ee7c1507ddb9098d50da9db92b4dd8774140670b9c5b8c80c74e69c005617fa5b9abe30750e231328485ad43dc181e49564cf5e4ad2e16ba32310c72a36541
@@ -35,8 +35,6 @@ jobs:
35
35
  - run: bundle install
36
36
  - run: bundle exec rake metrics:rubocop
37
37
  - run: bundle exec rake metrics:reek
38
- - run: bundle exec rake metrics:flay
39
- - run: bundle exec rake metrics:flog
40
38
  mutant:
41
39
  <<: *defaults
42
40
  steps:
@@ -1,3 +1,7 @@
1
+ # v0.8.21 2018-12-03
2
+
3
+ * Change to modern ast format via unparser-0.4.1.
4
+
1
5
  # v0.8.20 2018-11-27
2
6
 
3
7
  * Replace internal timers with monotonic ones.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mutant (0.8.19)
4
+ mutant (0.8.20)
5
5
  abstract_type (~> 0.0.7)
6
6
  adamantium (~> 0.2.0)
7
7
  anima (~> 0.3.0)
@@ -15,9 +15,9 @@ PATH
15
15
  parser (~> 2.5.1)
16
16
  procto (~> 0.0.2)
17
17
  regexp_parser (~> 1.2)
18
- unparser (~> 0.3.0)
19
- mutant-rspec (0.8.19)
20
- mutant (~> 0.8.19)
18
+ unparser (~> 0.4.0)
19
+ mutant-rspec (0.8.20)
20
+ mutant (~> 0.8.20)
21
21
  rspec-core (>= 3.4.0, < 4.0.0)
22
22
 
23
23
  GEM
@@ -45,22 +45,22 @@ GEM
45
45
  equalizer (~> 0.0.9)
46
46
  descendants_tracker (0.0.4)
47
47
  thread_safe (~> 0.3, >= 0.3.1)
48
- devtools (0.1.21)
48
+ devtools (0.1.22)
49
49
  abstract_type (~> 0.0.7)
50
50
  adamantium (~> 0.2.0)
51
51
  anima (~> 0.3.0)
52
52
  concord (~> 0.1.5)
53
- flay (~> 2.10.0)
54
- flog (~> 4.6.1)
55
- mutant (~> 0.8.16)
56
- mutant-rspec (~> 0.8.16)
53
+ flay (~> 2.12.0)
54
+ flog (~> 4.6.2)
55
+ mutant (~> 0.8.19)
56
+ mutant-rspec (~> 0.8.19)
57
57
  procto (~> 0.0.3)
58
58
  rake (~> 12.3.0)
59
- reek (~> 5.0.2)
59
+ reek (~> 5.2.0)
60
60
  rspec (~> 3.8.0)
61
61
  rspec-core (~> 3.8.0)
62
62
  rspec-its (~> 1.2.0)
63
- rubocop (~> 0.59.0)
63
+ rubocop (~> 0.60.0)
64
64
  simplecov (~> 0.16.1)
65
65
  yard (~> 0.9.16)
66
66
  yardstick (~> 0.9.9)
@@ -68,7 +68,7 @@ GEM
68
68
  docile (1.3.1)
69
69
  equalizer (0.0.11)
70
70
  erubis (2.7.0)
71
- flay (2.10.0)
71
+ flay (2.12.0)
72
72
  erubis (~> 2.7.0)
73
73
  path_expander (~> 1.0)
74
74
  ruby_parser (~> 3.0)
@@ -100,7 +100,7 @@ GEM
100
100
  procto (0.0.3)
101
101
  rainbow (3.0.0)
102
102
  rake (12.3.1)
103
- reek (5.0.2)
103
+ reek (5.2.0)
104
104
  codeclimate-engine-rb (~> 0.4.0)
105
105
  kwalify (~> 0.7.0)
106
106
  parser (>= 2.5.0.0, < 2.6, != 2.5.1.1)
@@ -122,14 +122,14 @@ GEM
122
122
  diff-lcs (>= 1.2.0, < 2.0)
123
123
  rspec-support (~> 3.8.0)
124
124
  rspec-support (3.8.0)
125
- rubocop (0.59.2)
125
+ rubocop (0.60.0)
126
126
  jaro_winkler (~> 1.5.1)
127
127
  parallel (~> 1.10)
128
128
  parser (>= 2.5, != 2.5.1.1)
129
129
  powerpack (~> 0.1)
130
130
  rainbow (>= 2.2.2, < 4.0)
131
131
  ruby-progressbar (~> 1.7)
132
- unicode-display_width (~> 1.0, >= 1.0.1)
132
+ unicode-display_width (~> 1.4.0)
133
133
  ruby-progressbar (1.10.0)
134
134
  ruby_parser (3.11.0)
135
135
  sexp_processor (~> 4.9)
@@ -141,7 +141,7 @@ GEM
141
141
  simplecov-html (0.10.2)
142
142
  thread_safe (0.3.6)
143
143
  unicode-display_width (1.4.0)
144
- unparser (0.3.0)
144
+ unparser (0.4.0)
145
145
  abstract_type (~> 0.0.7)
146
146
  adamantium (~> 0.2.0)
147
147
  concord (~> 0.1.5)
@@ -162,8 +162,7 @@ PLATFORMS
162
162
  ruby
163
163
 
164
164
  DEPENDENCIES
165
- bundler (~> 1.10)
166
- devtools (~> 0.1.21)
165
+ devtools (~> 0.1.22)
167
166
  mutant!
168
167
  parallel (~> 1.3)
169
168
 
data/README.md CHANGED
@@ -7,12 +7,29 @@ mutant
7
7
  [![Gem Version](https://img.shields.io/gem/v/mutant.svg)](https://rubygems.org/gems/mutant)
8
8
  [![Slack Status](https://mutation-testing-slack.herokuapp.com/badge.svg)](https://mutation-testing.slack.com/messages/mutant)
9
9
 
10
- Mutant is a mutation testing tool for Ruby.
10
+ ## What is Mutant?
11
11
 
12
- The idea is that if code can be changed and your tests do not notice, then either that code isn't being covered
13
- or it does not have a speced side effect.
12
+ Mutant is a mutation testing tool for Ruby. Mutation testing is a technique to verify semantic coverage of your code.
14
13
 
15
- Mutant supports ruby >= 2.5, MRI only.
14
+ ## Why do I want it?
15
+
16
+ Mutant adds to your toolbox: Detection of uncovered semantics in your code.
17
+ Coverage becomes a meaninful metric!
18
+
19
+ On each detection of uncovered semantics you have the opportunity to:
20
+
21
+ * Delete dead code, as you do not want the extra semantics not specified by the tests
22
+ * Add (or improve a test) to cover the unwanted semantics.
23
+ * Learn something new about the semantics of Ruby and your direct and indirect dependencies.
24
+
25
+ ## How Do I use it?
26
+
27
+ * Start with reading the [nomenclature](/docs/nomenclature.md) documentation.
28
+ * Than select and setup your [integration](/docs/nomenclature.md#interation), also make sure
29
+ you can reproduce the examples in the integration specific documentation.
30
+ * Identify your preferred mutation testing strategy. Its recommended to start at the commit level,
31
+ to test only the code you had been touching. See the [incremental](#only-mutating-changed-code)
32
+ mutation testing documentation.
16
33
 
17
34
  Mutant uses a pure Ruby [parser](https://github.com/whitequark/parser) and an [unparser](https://github.com/mbj/unparser)
18
35
  to do its magic.
@@ -173,14 +173,13 @@ IndentArray:
173
173
  MultilineMethodCallIndentation:
174
174
  EnforcedStyle: indented
175
175
 
176
- # Align keys and values in a multiline hash
177
- AlignHash:
178
- EnforcedColonStyle: table
179
-
180
176
  # Prefer `public_send` and `__send__` over `send`
181
177
  Send:
182
178
  Enabled: true
183
179
 
180
+ Layout/AlignHash:
181
+ EnforcedColonStyle: table
182
+ EnforcedHashRocketStyle: table
184
183
  Layout/EmptyLineAfterGuardClause:
185
184
  Enabled: false
186
185
  Layout/SpaceInsideArrayLiteralBrackets:
@@ -55,6 +55,7 @@ All the setup described above is already done.
55
55
 
56
56
  ```sh
57
57
  git clone https://github.com/mbj/auom
58
+ cd auom
58
59
  bundle install # gemfile references mutant-minitest already
59
60
  bundle exec mutant --include lib --require auom --use minitest -- 'AUOM*'
60
61
  ```
@@ -143,5 +144,6 @@ Mutations/s: 107.60
143
144
  Coverage: 99.90%
144
145
  ```
145
146
 
146
- This shows mutant detected the redundant alive conditional.
147
- Feel free to also remove some tests. Or do other modifications to either tests or code.
147
+ This shows mutant detected the alive mutation. Which shows the conditional we deliberately added above is redundant.
148
+
149
+ Feel free to also remove some tests. Or do other modifications to either test or code.
@@ -1,29 +1,119 @@
1
1
  mutant-rspec
2
2
  ============
3
3
 
4
- The integration into rspec.
4
+ Before starting with mutant its recommended to understand the
5
+ [nomenclature](/docs/nomenclature.md).
5
6
 
6
- Install `mutant-rspec` and use the `--use rspec` switch in your mutant command line.
7
+ ## Setup
8
+
9
+ To add mutant to your rspec code base you need to:
10
+
11
+ 1. Add `mutant-rspec` as development dependency to your `Gemfile` or `.gemspec`
12
+
13
+ This may look like:
14
+
15
+ ```ruby
16
+ # A gemfile
17
+ gem 'mutant-rspec'
18
+ ```
19
+
20
+ 2. Run mutant against the rspec integration
21
+
22
+ ```sh
23
+ bundle exec mutant --include lib --require 'your_library.rb' --use rspec -- 'YourLibrary*'
24
+ ```
25
+
26
+ ## Run through example
27
+
28
+ This uses [mbj/auom](https://github.com/mbj/auom) a small library that
29
+ has 100% mutation coverage. Its tests execute very fast and do not have any IO
30
+ so its a good playground example to interact with.
31
+
32
+ All the setup described above is already done.
7
33
 
8
34
  ```sh
9
- bundle exec mutant --include lib --require 'your_code' --use rspec -- 'YourCode*'
35
+ git clone https://github.com/mbj/auom
36
+ cd auom
37
+ bundle install # gemfile references mutant-rspec already
38
+ bundle exec mutant --include lib --require auom --use rspec -- 'AUOM*'
10
39
  ```
11
40
 
12
- Examples
13
- --------
41
+ This prints a report like:
14
42
 
43
+ ```sh
44
+ Mutant configuration:
45
+ Matcher: #<Mutant::Matcher::Config match_expressions: [AUOM*]>
46
+ Integration: Mutant::Integration::Rspec
47
+ Jobs: 8
48
+ Includes: ["lib"]
49
+ Requires: ["auom"]
50
+ Subjects: 23
51
+ Mutations: 1003
52
+ Results: 1003
53
+ Kills: 1003
54
+ Alive: 0
55
+ Runtime: 51.52s
56
+ Killtime: 200.13s
57
+ Overhead: -74.26%
58
+ Mutations/s: 19.47
59
+ Coverage: 100.00%
15
60
  ```
16
- cd virtus
17
- # Run mutant on virtus namespace
18
- bundle exec mutant --include lib --require virtus --use rspec Virtus*
19
- # Run mutant on specific virtus class
20
- bundle exec mutant --include lib --require virtus --use rspec Virtus::Attribute
21
- # Run mutant on specific virtus class method
22
- bundle exec mutant --include lib --require virtus --use rspec Virtus::Attribute.build
23
- # Run mutant on specific virtus instance method
24
- bundle exec mutant --include lib --require virtus --use rspec Virtus::Attribute#type
61
+
62
+ Now lets try adding some redundant (or unspecified) code:
63
+
64
+ ```sh
65
+ patch -p1 <<'PATCH'
66
+ --- a/lib/auom/unit.rb
67
+ +++ b/lib/auom/unit.rb
68
+ @@ -170,7 +170,7 @@ module AUOM
69
+ # TODO: Move defaults coercions etc to .build method
70
+ #
71
+ def self.new(scalar, numerators = nil, denominators = nil)
72
+ - scalar = rational(scalar)
73
+ + scalar = rational(scalar) if true
74
+
75
+ scalar, numerators = resolve([*numerators], scalar, :*)
76
+ scalar, denominators = resolve([*denominators], scalar, :/)
77
+ PATCH
25
78
  ```
26
79
 
80
+ Running mutant again prints the following:
81
+
82
+ ```sh
83
+ evil:AUOM::Unit.new:/home/mrh-dev/example/auom/lib/auom/unit.rb:172:45e17
84
+ @@ -1,9 +1,7 @@
85
+ def self.new(scalar, numerators = nil, denominators = nil)
86
+ - if true
87
+ - scalar = rational(scalar)
88
+ - end
89
+ + scalar = rational(scalar)
90
+ scalar, numerators = resolve([*numerators], scalar, :*)
91
+ scalar, denominators = resolve([*denominators], scalar, :/)
92
+ super(scalar, *[numerators, denominators].map(&:sort)).freeze
93
+ end
94
+ -----------------------
95
+ Mutant configuration:
96
+ Matcher: #<Mutant::Matcher::Config match_expressions: [AUOM*]>
97
+ Integration: Mutant::Integration::Rspec
98
+ Jobs: 8
99
+ Includes: ["lib"]
100
+ Requires: ["auom"]
101
+ Subjects: 23
102
+ Mutations: 1009
103
+ Results: 1009
104
+ Kills: 1008
105
+ Alive: 1
106
+ Runtime: 50.93s
107
+ Killtime: 190.09s
108
+ Overhead: -73.21%
109
+ Mutations/s: 19.81
110
+ Coverage: 99.90%
111
+ ```
112
+
113
+ This shows mutant detected the alive mutation. Which shows the conditional we deliberately added above is redundant.
114
+
115
+ Feel free to also remove some tests. Or do other modifications to either test or code.
116
+
27
117
  Test-Selection
28
118
  --------------
29
119
 
@@ -135,7 +135,6 @@ require 'mutant/mutator/node/send'
135
135
  require 'mutant/mutator/node/send/binary'
136
136
  require 'mutant/mutator/node/send/conditional'
137
137
  require 'mutant/mutator/node/send/attribute_assignment'
138
- require 'mutant/mutator/node/send/index'
139
138
  require 'mutant/mutator/node/when'
140
139
  require 'mutant/mutator/node/class'
141
140
  require 'mutant/mutator/node/define'
@@ -151,6 +150,8 @@ require 'mutant/mutator/node/regopt'
151
150
  require 'mutant/mutator/node/resbody'
152
151
  require 'mutant/mutator/node/rescue'
153
152
  require 'mutant/mutator/node/match_current_line'
153
+ require 'mutant/mutator/node/index'
154
+ require 'mutant/mutator/node/procarg_zero'
154
155
  require 'mutant/loader'
155
156
  require 'mutant/context'
156
157
  require 'mutant/scope'
@@ -30,14 +30,7 @@ module Mutant
30
30
  naked_proc? || proc_new?
31
31
  end
32
32
 
33
- # Test if AST node is a valid assignment target
34
- #
35
- # @return [Boolean]
36
- def assignment?
37
- index_assignment? || attribute_assignment?
38
- end
39
-
40
- # Test if AST node is an attribute assignment?
33
+ # Test if AST node is a valid attribute assignment
41
34
  #
42
35
  # @return [Boolean]
43
36
  def attribute_assignment?
@@ -45,13 +38,6 @@ module Mutant
45
38
  selector.to_s.end_with?(ATTRIBUTE_ASSIGNMENT_SELECTOR_SUFFIX)
46
39
  end
47
40
 
48
- # Test if AST node is an index assign
49
- #
50
- # @return [Boolean]
51
- def index_assignment?
52
- selector.equal?(INDEX_ASSIGNMENT_SELECTOR)
53
- end
54
-
55
41
  # Test for binary operator implemented as method
56
42
  #
57
43
  # @return [Boolean]
@@ -7,44 +7,67 @@ module Mutant
7
7
  # :reek:TooManyConstants
8
8
  # rubocop:disable Metrics/ModuleLength
9
9
  module Types
10
- symbolset = ->(strings) { strings.map(&:to_sym).to_set.freeze }
11
-
12
- ASSIGNABLE_VARIABLES = symbolset.(%w[ivasgn lvasgn cvasgn gvasgn])
10
+ ASSIGNABLE_VARIABLES = Set.new(%i[ivasgn lvasgn cvasgn gvasgn]).freeze
13
11
 
14
12
  INDEX_ASSIGN_OPERATOR = :[]=
15
13
 
16
14
  # Set of nodes that cannot be on the LHS of an assignment
17
- NOT_ASSIGNABLE = symbolset.(%w[int float str dstr class module self nil])
15
+ NOT_ASSIGNABLE = Set.new(%i[int float str dstr class module self nil]).freeze
18
16
 
19
17
  # Set of op-assign types
20
- OP_ASSIGN = symbolset.(%w[or_asgn and_asgn op_asgn])
18
+ OP_ASSIGN = Set.new(%i[or_asgn and_asgn op_asgn]).freeze
21
19
  # Set of node types that are not valid when emitted standalone
22
- NOT_STANDALONE = symbolset.(%w[splat restarg block_pass])
23
- INDEX_OPERATORS = symbolset.(%w[[] []=])
24
- UNARY_METHOD_OPERATORS = symbolset.(%w[~@ +@ -@ !])
20
+ NOT_STANDALONE = Set.new(%i[splat restarg block_pass]).freeze
21
+ INDEX_OPERATORS = Set.new(%i[[] []=]).freeze
22
+ UNARY_METHOD_OPERATORS = Set.new(%i[~@ +@ -@ !]).freeze
25
23
 
26
24
  # Operators ruby implements as methods
27
- METHOD_OPERATORS = symbolset.(%w[
28
- <=> === []= [] <= >= == !~ != =~ <<
29
- >> ** * % / | ^ & < > + - ~@ +@ -@ !
30
- ])
25
+ METHOD_OPERATORS = Set.new(%i[
26
+ !
27
+ !=
28
+ !~
29
+ %
30
+ &
31
+ *
32
+ **
33
+ +
34
+ +@
35
+ -
36
+ -@
37
+ /
38
+ <
39
+ <<
40
+ <=
41
+ <=>
42
+ ==
43
+ ===
44
+ =~
45
+ >
46
+ >=
47
+ >>
48
+ []
49
+ []=
50
+ ^
51
+ |
52
+ ~@
53
+ ]).freeze
31
54
 
32
- BINARY_METHOD_OPERATORS = symbolset.(
55
+ BINARY_METHOD_OPERATORS = Set.new(
33
56
  METHOD_OPERATORS - (INDEX_OPERATORS + UNARY_METHOD_OPERATORS)
34
57
  )
35
58
 
36
- OPERATOR_METHODS = symbolset.(
59
+ OPERATOR_METHODS = Set.new(
37
60
  METHOD_OPERATORS + INDEX_OPERATORS + UNARY_METHOD_OPERATORS
38
- )
61
+ ).freeze
39
62
 
40
63
  # Nodes that are NOT handled by mutant.
41
64
  #
42
65
  # not - 1.8 only, mutant does not support 1.8
43
66
  #
44
- BLACKLIST = symbolset.(%w[not])
67
+ BLACKLIST = Set.new(%i[not]).freeze
45
68
 
46
69
  # Nodes generated by regular expression body parsing
47
- REGEXP = symbolset.(%w[
70
+ REGEXP = Set.new(%i[
48
71
  regexp_alnum_posixclass
49
72
  regexp_alpha_posixclass
50
73
  regexp_alpha_property
@@ -154,15 +177,17 @@ module Mutant
154
177
  regexp_xgrapheme_type
155
178
  regexp_zero_or_more_escape
156
179
  regexp_zero_or_one_escape
157
- ])
180
+ ]).freeze
158
181
 
159
182
  # Nodes that are NOT generated by parser but used by mutant / unparser.
160
- GENERATED = symbolset.(%w[empty])
183
+ GENERATED = Set.new(%i[empty]).freeze
161
184
 
162
- EXTRA = symbolset.(GENERATED + REGEXP)
185
+ # Nodes missing from parser metadata
186
+ MISSING = Set.new(%i[index indexasgn lambda procarg0]).freeze
163
187
 
164
- # All node types mutant handles
165
- ALL = symbolset.((Parser::Meta::NODE_TYPES + EXTRA) - BLACKLIST)
188
+ ALL = Set.new(
189
+ (Parser::Meta::NODE_TYPES + GENERATED + REGEXP + MISSING) - BLACKLIST
190
+ ).freeze
166
191
  end # Types
167
192
  end # AST
168
193
  end # Mutant