mutant 0.8.24 → 0.9.0

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 (218) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +3 -3
  3. data/Changelog.md +14 -654
  4. data/Gemfile +13 -0
  5. data/Gemfile.lock +59 -64
  6. data/LICENSE +271 -20
  7. data/README.md +73 -140
  8. data/Rakefile +0 -21
  9. data/bin/mutant +7 -2
  10. data/config/reek.yml +2 -1
  11. data/config/rubocop.yml +5 -9
  12. data/docs/incremental.md +76 -0
  13. data/docs/known-problems.md +0 -14
  14. data/docs/mutant-minitest.md +1 -1
  15. data/docs/mutant-rspec.md +2 -24
  16. data/lib/mutant.rb +45 -53
  17. data/lib/mutant/ast/nodes.rb +0 -2
  18. data/lib/mutant/ast/types.rb +1 -117
  19. data/lib/mutant/base.rb +192 -0
  20. data/lib/mutant/bootstrap.rb +145 -0
  21. data/lib/mutant/cli.rb +68 -54
  22. data/lib/mutant/config.rb +119 -6
  23. data/lib/mutant/env.rb +94 -8
  24. data/lib/mutant/expression.rb +6 -1
  25. data/lib/mutant/expression/parser.rb +9 -31
  26. data/lib/mutant/integration.rb +64 -36
  27. data/lib/mutant/isolation.rb +16 -1
  28. data/lib/mutant/isolation/fork.rb +105 -40
  29. data/lib/mutant/license.rb +34 -0
  30. data/lib/mutant/license/subscription.rb +47 -0
  31. data/lib/mutant/license/subscription/commercial.rb +57 -0
  32. data/lib/mutant/license/subscription/opensource.rb +77 -0
  33. data/lib/mutant/loader.rb +27 -4
  34. data/lib/mutant/matcher.rb +48 -1
  35. data/lib/mutant/matcher/chain.rb +1 -1
  36. data/lib/mutant/matcher/config.rb +0 -2
  37. data/lib/mutant/matcher/filter.rb +1 -1
  38. data/lib/mutant/matcher/method.rb +11 -7
  39. data/lib/mutant/matcher/methods.rb +1 -1
  40. data/lib/mutant/matcher/namespace.rb +1 -1
  41. data/lib/mutant/matcher/null.rb +1 -1
  42. data/lib/mutant/matcher/scope.rb +1 -1
  43. data/lib/mutant/meta/example/dsl.rb +0 -8
  44. data/lib/mutant/mutation.rb +1 -2
  45. data/lib/mutant/mutator/node.rb +2 -9
  46. data/lib/mutant/mutator/node/arguments.rb +1 -1
  47. data/lib/mutant/mutator/node/class.rb +0 -8
  48. data/lib/mutant/mutator/node/define.rb +0 -12
  49. data/lib/mutant/mutator/node/generic.rb +30 -44
  50. data/lib/mutant/mutator/node/index.rb +4 -4
  51. data/lib/mutant/mutator/node/literal/regex.rb +0 -39
  52. data/lib/mutant/mutator/node/send.rb +13 -12
  53. data/lib/mutant/parallel.rb +61 -40
  54. data/lib/mutant/parallel/driver.rb +59 -0
  55. data/lib/mutant/parallel/source.rb +6 -2
  56. data/lib/mutant/parallel/worker.rb +63 -45
  57. data/lib/mutant/range.rb +15 -0
  58. data/lib/mutant/reporter/cli.rb +5 -11
  59. data/lib/mutant/reporter/cli/format.rb +3 -46
  60. data/lib/mutant/reporter/cli/printer/config.rb +5 -6
  61. data/lib/mutant/reporter/cli/printer/env.rb +40 -0
  62. data/lib/mutant/reporter/cli/printer/env_progress.rb +13 -17
  63. data/lib/mutant/reporter/cli/printer/isolation_result.rb +17 -3
  64. data/lib/mutant/reporter/cli/printer/mutation_result.rb +2 -3
  65. data/lib/mutant/reporter/cli/printer/status_progressive.rb +19 -10
  66. data/lib/mutant/repository.rb +0 -65
  67. data/lib/mutant/repository/diff.rb +104 -0
  68. data/lib/mutant/repository/diff/ranges.rb +52 -0
  69. data/lib/mutant/result.rb +16 -7
  70. data/lib/mutant/runner.rb +38 -47
  71. data/lib/mutant/runner/sink.rb +1 -1
  72. data/lib/mutant/selector/null.rb +19 -0
  73. data/lib/mutant/subject.rb +3 -1
  74. data/lib/mutant/subject/method/instance.rb +3 -1
  75. data/lib/mutant/transform.rb +511 -0
  76. data/lib/mutant/variable.rb +282 -0
  77. data/lib/mutant/version.rb +1 -1
  78. data/lib/mutant/warnings.rb +113 -0
  79. data/meta/case.rb +1 -0
  80. data/meta/class.rb +0 -9
  81. data/meta/def.rb +1 -26
  82. data/meta/regexp.rb +10 -20
  83. data/meta/send.rb +14 -46
  84. data/mutant-minitest.gemspec +1 -1
  85. data/mutant-rspec.gemspec +2 -2
  86. data/mutant.gemspec +15 -16
  87. data/mutant.yml +6 -0
  88. data/spec/integration/mutant/isolation/fork_spec.rb +22 -5
  89. data/spec/integration/mutant/minitest_spec.rb +3 -2
  90. data/spec/integration/mutant/rspec_spec.rb +4 -3
  91. data/spec/integrations.yml +16 -13
  92. data/spec/shared/base_behavior.rb +45 -0
  93. data/spec/shared/framework_integration_behavior.rb +43 -14
  94. data/spec/spec_helper.rb +21 -17
  95. data/spec/support/corpus.rb +56 -95
  96. data/spec/support/shared_context.rb +37 -14
  97. data/spec/support/xspec.rb +7 -3
  98. data/spec/unit/mutant/bootstrap_spec.rb +216 -0
  99. data/spec/unit/mutant/cli_spec.rb +173 -117
  100. data/spec/unit/mutant/config_spec.rb +126 -0
  101. data/spec/unit/mutant/either_spec.rb +247 -0
  102. data/spec/unit/mutant/env_spec.rb +162 -40
  103. data/spec/unit/mutant/expression/method_spec.rb +16 -0
  104. data/spec/unit/mutant/expression/parser_spec.rb +29 -33
  105. data/spec/unit/mutant/expression_spec.rb +5 -7
  106. data/spec/unit/mutant/integration_spec.rb +100 -9
  107. data/spec/unit/mutant/isolation/fork_spec.rb +125 -67
  108. data/spec/unit/mutant/isolation/result_spec.rb +33 -1
  109. data/spec/unit/mutant/license_spec.rb +257 -0
  110. data/spec/unit/mutant/loader_spec.rb +50 -11
  111. data/spec/unit/mutant/matcher/compiler_spec.rb +0 -78
  112. data/spec/unit/mutant/matcher/method/instance_spec.rb +55 -11
  113. data/spec/unit/mutant/matcher/method/singleton_spec.rb +12 -2
  114. data/spec/unit/mutant/matcher_spec.rb +102 -0
  115. data/spec/unit/mutant/maybe_spec.rb +60 -0
  116. data/spec/unit/mutant/meta/example/dsl_spec.rb +1 -17
  117. data/spec/unit/mutant/mutation_spec.rb +13 -6
  118. data/spec/unit/mutant/parallel/driver_spec.rb +112 -14
  119. data/spec/unit/mutant/parallel/source/array_spec.rb +25 -17
  120. data/spec/unit/mutant/parallel/worker_spec.rb +182 -44
  121. data/spec/unit/mutant/parallel_spec.rb +105 -8
  122. data/spec/unit/mutant/range_spec.rb +141 -0
  123. data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +7 -21
  124. data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +15 -6
  125. data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +10 -2
  126. data/spec/unit/mutant/reporter/cli/printer/isolation_result_spec.rb +12 -4
  127. data/spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb +31 -2
  128. data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +4 -4
  129. data/spec/unit/mutant/reporter/cli/printer/subject_result_spec.rb +5 -0
  130. data/spec/unit/mutant/reporter/cli_spec.rb +46 -123
  131. data/spec/unit/mutant/repository/diff/ranges_spec.rb +180 -0
  132. data/spec/unit/mutant/repository/diff_spec.rb +84 -71
  133. data/spec/unit/mutant/require_highjack_spec.rb +1 -1
  134. data/spec/unit/mutant/result/env_spec.rb +39 -9
  135. data/spec/unit/mutant/result/test_spec.rb +14 -0
  136. data/spec/unit/mutant/runner_spec.rb +88 -41
  137. data/spec/unit/mutant/selector/expression_spec.rb +11 -10
  138. data/spec/unit/mutant/selector/null_spec.rb +17 -0
  139. data/spec/unit/mutant/subject/method/instance_spec.rb +44 -5
  140. data/spec/unit/mutant/subject/method/singleton_spec.rb +9 -2
  141. data/spec/unit/mutant/subject_spec.rb +9 -1
  142. data/spec/unit/mutant/transform/array_spec.rb +92 -0
  143. data/spec/unit/mutant/transform/bool_spec.rb +63 -0
  144. data/spec/unit/mutant/transform/error_spec.rb +132 -0
  145. data/spec/unit/mutant/transform/exception_spec.rb +44 -0
  146. data/spec/unit/mutant/transform/hash_spec.rb +236 -0
  147. data/spec/unit/mutant/transform/index_spec.rb +92 -0
  148. data/spec/unit/mutant/transform/named_spec.rb +49 -0
  149. data/spec/unit/mutant/transform/primitive_spec.rb +56 -0
  150. data/spec/unit/mutant/transform/sequence_spec.rb +98 -0
  151. data/spec/unit/mutant/variable_spec.rb +618 -0
  152. data/spec/unit/mutant/warnings_spec.rb +89 -0
  153. data/spec/unit/mutant/world_spec.rb +63 -0
  154. data/test_app/Gemfile.minitest +0 -2
  155. metadata +79 -113
  156. data/.gitattributes +0 -1
  157. data/.ruby-gemset +0 -1
  158. data/config/triage.yml +0 -2
  159. data/lib/mutant/actor.rb +0 -57
  160. data/lib/mutant/actor/env.rb +0 -31
  161. data/lib/mutant/actor/mailbox.rb +0 -34
  162. data/lib/mutant/actor/receiver.rb +0 -42
  163. data/lib/mutant/actor/sender.rb +0 -26
  164. data/lib/mutant/ast/meta/restarg.rb +0 -19
  165. data/lib/mutant/ast/regexp.rb +0 -42
  166. data/lib/mutant/ast/regexp/transformer.rb +0 -187
  167. data/lib/mutant/ast/regexp/transformer/direct.rb +0 -123
  168. data/lib/mutant/ast/regexp/transformer/named_group.rb +0 -59
  169. data/lib/mutant/ast/regexp/transformer/options_group.rb +0 -83
  170. data/lib/mutant/ast/regexp/transformer/quantifier.rb +0 -114
  171. data/lib/mutant/ast/regexp/transformer/recursive.rb +0 -58
  172. data/lib/mutant/ast/regexp/transformer/root.rb +0 -31
  173. data/lib/mutant/ast/regexp/transformer/text.rb +0 -60
  174. data/lib/mutant/env/bootstrap.rb +0 -160
  175. data/lib/mutant/matcher/compiler.rb +0 -60
  176. data/lib/mutant/mutator/node/regexp.rb +0 -35
  177. data/lib/mutant/mutator/node/regexp/alternation_meta.rb +0 -23
  178. data/lib/mutant/mutator/node/regexp/capture_group.rb +0 -28
  179. data/lib/mutant/mutator/node/regexp/character_type.rb +0 -32
  180. data/lib/mutant/mutator/node/regexp/end_of_line_anchor.rb +0 -23
  181. data/lib/mutant/mutator/node/regexp/end_of_string_or_before_end_of_line_anchor.rb +0 -23
  182. data/lib/mutant/mutator/node/regexp/greedy_zero_or_more.rb +0 -27
  183. data/lib/mutant/parallel/master.rb +0 -181
  184. data/lib/mutant/reporter/cli/printer/status.rb +0 -53
  185. data/lib/mutant/reporter/cli/tput.rb +0 -46
  186. data/lib/mutant/warning_filter.rb +0 -61
  187. data/meta/regexp/character_types.rb +0 -23
  188. data/meta/regexp/regexp_alternation_meta.rb +0 -13
  189. data/meta/regexp/regexp_bol_anchor.rb +0 -10
  190. data/meta/regexp/regexp_bos_anchor.rb +0 -18
  191. data/meta/regexp/regexp_capture_group.rb +0 -19
  192. data/meta/regexp/regexp_eol_anchor.rb +0 -10
  193. data/meta/regexp/regexp_eos_anchor.rb +0 -8
  194. data/meta/regexp/regexp_eos_ob_eol_anchor.rb +0 -10
  195. data/meta/regexp/regexp_greedy_zero_or_more.rb +0 -12
  196. data/meta/regexp/regexp_root_expression.rb +0 -10
  197. data/meta/restarg.rb +0 -10
  198. data/spec/support/fake_actor.rb +0 -111
  199. data/spec/support/warning.rb +0 -66
  200. data/spec/unit/mutant/actor/binding_spec.rb +0 -34
  201. data/spec/unit/mutant/actor/env_spec.rb +0 -31
  202. data/spec/unit/mutant/actor/mailbox_spec.rb +0 -28
  203. data/spec/unit/mutant/actor/message_spec.rb +0 -25
  204. data/spec/unit/mutant/actor/receiver_spec.rb +0 -58
  205. data/spec/unit/mutant/actor/sender_spec.rb +0 -24
  206. data/spec/unit/mutant/ast/regexp/parse_spec.rb +0 -19
  207. data/spec/unit/mutant/ast/regexp/transformer/lookup_table/table_spec.rb +0 -21
  208. data/spec/unit/mutant/ast/regexp/transformer/lookup_table_spec.rb +0 -35
  209. data/spec/unit/mutant/ast/regexp/transformer_spec.rb +0 -21
  210. data/spec/unit/mutant/ast/regexp_spec.rb +0 -704
  211. data/spec/unit/mutant/env/bootstrap_spec.rb +0 -188
  212. data/spec/unit/mutant/matcher/compiler/subject_prefix_spec.rb +0 -26
  213. data/spec/unit/mutant/parallel/master_spec.rb +0 -338
  214. data/spec/unit/mutant/reporter/cli/printer/status_spec.rb +0 -121
  215. data/spec/unit/mutant/reporter/cli/tput_spec.rb +0 -50
  216. data/spec/unit/mutant/warning_filter_spec.rb +0 -106
  217. data/spec/unit/mutant_spec.rb +0 -17
  218. data/test_app/Gemfile.rspec3.7 +0 -7
@@ -63,7 +63,7 @@ bundle exec mutant --include lib --require auom --use minitest -- 'AUOM*'
63
63
  This prints a report like:
64
64
 
65
65
  ```sh
66
- Mutant configuration:
66
+ Mutant environment:
67
67
  Matcher: #<Mutant::Matcher::Config match_expressions: [AUOM*]>
68
68
  Integration: Mutant::Integration::Minitest
69
69
  Jobs: 8
@@ -17,11 +17,7 @@ To add mutant to your rspec code base you need to:
17
17
  gem 'mutant-rspec'
18
18
  ```
19
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
- ```
20
+ 2. Run mutant against the rspec integration via the `--use rspec` flag.
25
21
 
26
22
  ## Run through example
27
23
 
@@ -41,7 +37,7 @@ bundle exec mutant --include lib --require auom --use rspec -- 'AUOM*'
41
37
  This prints a report like:
42
38
 
43
39
  ```sh
44
- Mutant configuration:
40
+ Mutant environment:
45
41
  Matcher: #<Mutant::Matcher::Config match_expressions: [AUOM*]>
46
42
  Integration: Mutant::Integration::Rspec
47
43
  Jobs: 8
@@ -129,24 +125,6 @@ description prefixes in `Foo::Bar#baz`, `Foo::Bar` and `Foo`. The order is
129
125
  important, so if mutant finds example groups in the current prefix level,
130
126
  these example groups *must* kill the mutation.
131
127
 
132
- Rails
133
- -------
134
-
135
- To mutation test Rails models with rspec, comment out `require 'rspec/autorun'`
136
- from your `spec_helper.rb` file. Having done so you should be able to use
137
- commands like the following:
138
-
139
128
  ```sh
140
129
  RAILS_ENV=test bundle exec mutant -r ./config/environment --use rspec User
141
130
  ```
142
-
143
- Passing in RSpec Options
144
- ------------------------
145
-
146
- **NOTE: Experimental**
147
-
148
- You can control some aspects of RSpec using the `SPEC_OPTS` environment variable as usual. If you want mutant to only pay attention to specs in a certain directory, you can run
149
-
150
- ```sh
151
- SPEC_OPTS="--pattern spec/subdir_only/**/*_spec.rb" bundle exec mutant --use rspec SomeClass
152
- ```
@@ -7,19 +7,22 @@ require 'concord'
7
7
  require 'diff/lcs'
8
8
  require 'diff/lcs/hunk'
9
9
  require 'digest/sha1'
10
- require 'etc'
11
10
  require 'equalizer'
11
+ require 'etc'
12
12
  require 'ice_nine'
13
- require 'morpher'
13
+ require 'json'
14
14
  require 'open3'
15
15
  require 'optparse'
16
16
  require 'parser'
17
17
  require 'parser/current'
18
18
  require 'pathname'
19
- require 'regexp_parser'
20
19
  require 'set'
20
+ require 'singleton'
21
21
  require 'stringio'
22
22
  require 'unparser'
23
+ require 'yaml'
24
+
25
+ gem 'mutant-license'
23
26
 
24
27
  # This setting is done to make errors within the parallel
25
28
  # reporter / execution visible in the main thread.
@@ -33,18 +36,12 @@ module Mutant
33
36
  EMPTY_ARRAY = [].freeze
34
37
  EMPTY_HASH = {}.freeze
35
38
  SCOPE_OPERATOR = '::'
36
-
37
- # Test if CI is detected via environment
38
- #
39
- # @return [Boolean]
40
- def self.ci?
41
- ENV.key?('CI')
42
- end
43
39
  end # Mutant
44
40
 
41
+ require 'mutant/base'
42
+ require 'mutant/bootstrap'
45
43
  require 'mutant/version'
46
44
  require 'mutant/env'
47
- require 'mutant/env/bootstrap'
48
45
  require 'mutant/util'
49
46
  require 'mutant/registry'
50
47
  require 'mutant/ast'
@@ -53,36 +50,20 @@ require 'mutant/ast/types'
53
50
  require 'mutant/ast/nodes'
54
51
  require 'mutant/ast/named_children'
55
52
  require 'mutant/ast/node_predicates'
56
- require 'mutant/ast/regexp'
57
- require 'mutant/ast/regexp/transformer'
58
- require 'mutant/ast/regexp/transformer/direct'
59
- require 'mutant/ast/regexp/transformer/named_group'
60
- require 'mutant/ast/regexp/transformer/options_group'
61
- require 'mutant/ast/regexp/transformer/quantifier'
62
- require 'mutant/ast/regexp/transformer/recursive'
63
- require 'mutant/ast/regexp/transformer/root'
64
- require 'mutant/ast/regexp/transformer/text'
65
53
  require 'mutant/ast/meta'
66
54
  require 'mutant/ast/meta/send'
67
55
  require 'mutant/ast/meta/const'
68
56
  require 'mutant/ast/meta/symbol'
69
57
  require 'mutant/ast/meta/optarg'
70
58
  require 'mutant/ast/meta/resbody'
71
- require 'mutant/ast/meta/restarg'
72
- require 'mutant/actor'
73
- require 'mutant/actor/receiver'
74
- require 'mutant/actor/sender'
75
- require 'mutant/actor/mailbox'
76
- require 'mutant/actor/env'
77
59
  require 'mutant/parser'
78
60
  require 'mutant/isolation'
79
61
  require 'mutant/isolation/none'
80
62
  require 'mutant/isolation/fork'
81
63
  require 'mutant/parallel'
82
- require 'mutant/parallel/master'
83
- require 'mutant/parallel/worker'
64
+ require 'mutant/parallel/driver'
84
65
  require 'mutant/parallel/source'
85
- require 'mutant/warning_filter'
66
+ require 'mutant/parallel/worker'
86
67
  require 'mutant/require_highjack'
87
68
  require 'mutant/mutation'
88
69
  require 'mutant/mutator'
@@ -91,13 +72,6 @@ require 'mutant/mutator/util/array'
91
72
  require 'mutant/mutator/util/symbol'
92
73
  require 'mutant/mutator/node'
93
74
  require 'mutant/mutator/node/generic'
94
- require 'mutant/mutator/node/regexp'
95
- require 'mutant/mutator/node/regexp/alternation_meta'
96
- require 'mutant/mutator/node/regexp/capture_group'
97
- require 'mutant/mutator/node/regexp/character_type'
98
- require 'mutant/mutator/node/regexp/end_of_line_anchor'
99
- require 'mutant/mutator/node/regexp/end_of_string_or_before_end_of_line_anchor'
100
- require 'mutant/mutator/node/regexp/greedy_zero_or_more'
101
75
  require 'mutant/mutator/node/literal'
102
76
  require 'mutant/mutator/node/literal/boolean'
103
77
  require 'mutant/mutator/node/literal/range'
@@ -161,7 +135,6 @@ require 'mutant/subject/method/instance'
161
135
  require 'mutant/subject/method/singleton'
162
136
  require 'mutant/matcher'
163
137
  require 'mutant/matcher/config'
164
- require 'mutant/matcher/compiler'
165
138
  require 'mutant/matcher/chain'
166
139
  require 'mutant/matcher/method'
167
140
  require 'mutant/matcher/method/singleton'
@@ -179,9 +152,12 @@ require 'mutant/expression/methods'
179
152
  require 'mutant/expression/namespace'
180
153
  require 'mutant/test'
181
154
  require 'mutant/timer'
155
+ require 'mutant/transform'
182
156
  require 'mutant/integration'
157
+ require 'mutant/integration/null'
183
158
  require 'mutant/selector'
184
159
  require 'mutant/selector/expression'
160
+ require 'mutant/selector/null'
185
161
  require 'mutant/config'
186
162
  require 'mutant/cli'
187
163
  require 'mutant/color'
@@ -195,22 +171,49 @@ require 'mutant/reporter/sequence'
195
171
  require 'mutant/reporter/cli'
196
172
  require 'mutant/reporter/cli/printer'
197
173
  require 'mutant/reporter/cli/printer/config'
174
+ require 'mutant/reporter/cli/printer/env'
198
175
  require 'mutant/reporter/cli/printer/env_progress'
199
176
  require 'mutant/reporter/cli/printer/env_result'
200
177
  require 'mutant/reporter/cli/printer/isolation_result'
201
178
  require 'mutant/reporter/cli/printer/mutation_progress_result'
202
179
  require 'mutant/reporter/cli/printer/mutation_result'
203
- require 'mutant/reporter/cli/printer/status'
204
180
  require 'mutant/reporter/cli/printer/status_progressive'
205
181
  require 'mutant/reporter/cli/printer/subject_progress'
206
182
  require 'mutant/reporter/cli/printer/subject_result'
207
183
  require 'mutant/reporter/cli/printer/test_result'
208
- require 'mutant/reporter/cli/tput'
209
184
  require 'mutant/reporter/cli/format'
210
185
  require 'mutant/repository'
186
+ require 'mutant/repository/diff'
187
+ require 'mutant/repository/diff/ranges'
188
+ require 'mutant/variable'
189
+ require 'mutant/warnings'
211
190
  require 'mutant/zombifier'
191
+ require 'mutant/range'
192
+ require 'mutant/license'
193
+ require 'mutant/license/subscription'
194
+ require 'mutant/license/subscription/opensource'
195
+ require 'mutant/license/subscription/commercial'
212
196
 
213
197
  module Mutant
198
+ WORLD = World.new(
199
+ condition_variable: ConditionVariable,
200
+ gem: Gem,
201
+ io: IO,
202
+ json: JSON,
203
+ kernel: Kernel,
204
+ load_path: $LOAD_PATH,
205
+ marshal: Marshal,
206
+ mutex: Mutex,
207
+ object_space: ObjectSpace,
208
+ open3: Open3,
209
+ pathname: Pathname,
210
+ process: Process,
211
+ stderr: STDERR,
212
+ stdout: STDOUT,
213
+ thread: Thread,
214
+ warnings: Warnings.new(Warning)
215
+ )
216
+
214
217
  # Reopen class to initialize constant to avoid dep circle
215
218
  class Config
216
219
  DEFAULT = new(
@@ -222,23 +225,12 @@ module Mutant
222
225
  ]),
223
226
  fail_fast: false,
224
227
  includes: EMPTY_ARRAY,
225
- integration: Integration::Null,
226
- isolation: Mutant::Isolation::Fork.new(
227
- devnull: ->(&block) { File.open(File::NULL, File::WRONLY, &block) },
228
- stdout: $stdout,
229
- stderr: $stderr,
230
- io: IO,
231
- marshal: Marshal,
232
- process: Process
233
- ),
228
+ integration: 'null',
229
+ isolation: Mutant::Isolation::Fork.new(WORLD),
234
230
  jobs: Etc.nprocessors,
235
- kernel: Kernel,
236
- load_path: $LOAD_PATH,
237
231
  matcher: Matcher::Config::DEFAULT,
238
- open3: Open3,
239
- pathname: Pathname,
232
+ reporter: Reporter::CLI.build(WORLD.stdout),
240
233
  requires: EMPTY_ARRAY,
241
- reporter: Reporter::CLI.build($stdout),
242
234
  zombie: false
243
235
  )
244
236
  end # Config
@@ -3,8 +3,6 @@
3
3
  module Mutant
4
4
  module AST
5
5
  # Singleton nodes
6
- #
7
- # :reek:TooManyConstants
8
6
  module Nodes
9
7
  extend Sexp
10
8
 
@@ -3,9 +3,6 @@
3
3
  module Mutant
4
4
  module AST
5
5
  # Groups of node types
6
- #
7
- # :reek:TooManyConstants
8
- # rubocop:disable Metrics/ModuleLength
9
6
  module Types
10
7
  ASSIGNABLE_VARIABLES = Set.new(%i[ivasgn lvasgn cvasgn gvasgn]).freeze
11
8
 
@@ -66,119 +63,6 @@ module Mutant
66
63
  #
67
64
  BLACKLIST = Set.new(%i[not]).freeze
68
65
 
69
- # Nodes generated by regular expression body parsing
70
- REGEXP = Set.new(%i[
71
- regexp_alnum_posixclass
72
- regexp_alpha_posixclass
73
- regexp_alpha_property
74
- regexp_alternation_escape
75
- regexp_alternation_meta
76
- regexp_arabic_property
77
- regexp_ascii_posixclass
78
- regexp_atomic_group
79
- regexp_backslash_escape
80
- regexp_backspace_escape
81
- regexp_bell_escape
82
- regexp_blank_posixclass
83
- regexp_bol_anchor
84
- regexp_bol_escape
85
- regexp_bos_anchor
86
- regexp_capture_group
87
- regexp_carriage_escape
88
- regexp_character_set
89
- regexp_cntrl_posixclass
90
- regexp_codepoint_escape
91
- regexp_codepoint_list_escape
92
- regexp_comment_free_space
93
- regexp_comment_group
94
- regexp_condition_conditional
95
- regexp_control_escape
96
- regexp_digit_posixclass
97
- regexp_digit_type
98
- regexp_dot_escape
99
- regexp_dot_meta
100
- regexp_eol_anchor
101
- regexp_eol_escape
102
- regexp_eos_anchor
103
- regexp_eos_ob_eol_anchor
104
- regexp_escape_escape
105
- regexp_form_feed_escape
106
- regexp_graph_posixclass
107
- regexp_greedy_interval
108
- regexp_greedy_one_or_more
109
- regexp_greedy_zero_or_more
110
- regexp_greedy_zero_or_one
111
- regexp_group_close_escape
112
- regexp_group_open_escape
113
- regexp_han_property
114
- regexp_hangul_property
115
- regexp_hex_escape
116
- regexp_hex_type
117
- regexp_hiragana_property
118
- regexp_intersection_set
119
- regexp_interval_close_escape
120
- regexp_interval_open_escape
121
- regexp_katakana_property
122
- regexp_letter_property
123
- regexp_linebreak_type
124
- regexp_literal_escape
125
- regexp_literal_literal
126
- regexp_lookahead_assertion
127
- regexp_lookbehind_assertion
128
- regexp_lower_posixclass
129
- regexp_mark_keep
130
- regexp_match_start_anchor
131
- regexp_meta_sequence_escape
132
- regexp_name_call_backref
133
- regexp_named_group
134
- regexp_newline_escape
135
- regexp_nlookahead_assertion
136
- regexp_nlookbehind_assertion
137
- regexp_nondigit_type
138
- regexp_nonhex_type
139
- regexp_nonspace_type
140
- regexp_nonword_boundary_anchor
141
- regexp_nonword_type
142
- regexp_number_backref
143
- regexp_octal_escape
144
- regexp_one_or_more_escape
145
- regexp_open_conditional
146
- regexp_options_group
147
- regexp_options_switch_group
148
- regexp_passive_group
149
- regexp_possessive_interval
150
- regexp_possessive_one_or_more
151
- regexp_possessive_zero_or_more
152
- regexp_possessive_zero_or_one
153
- regexp_print_nonposixclass
154
- regexp_print_nonproperty
155
- regexp_print_posixclass
156
- regexp_print_posixclass
157
- regexp_print_property
158
- regexp_punct_posixclass
159
- regexp_range_set
160
- regexp_reluctant_interval
161
- regexp_reluctant_one_or_more
162
- regexp_reluctant_zero_or_more
163
- regexp_root_expression
164
- regexp_sequence_expression
165
- regexp_set_close_escape
166
- regexp_set_open_escape
167
- regexp_space_posixclass
168
- regexp_space_type
169
- regexp_tab_escape
170
- regexp_upper_posixclass
171
- regexp_vertical_tab_escape
172
- regexp_whitespace_free_space
173
- regexp_word_boundary_anchor
174
- regexp_word_posixclass
175
- regexp_word_type
176
- regexp_xdigit_posixclass
177
- regexp_xgrapheme_type
178
- regexp_zero_or_more_escape
179
- regexp_zero_or_one_escape
180
- ]).freeze
181
-
182
66
  # Nodes that are NOT generated by parser but used by mutant / unparser.
183
67
  GENERATED = Set.new(%i[empty]).freeze
184
68
 
@@ -186,7 +70,7 @@ module Mutant
186
70
  MISSING = Set.new(%i[index indexasgn lambda procarg0]).freeze
187
71
 
188
72
  ALL = Set.new(
189
- (Parser::Meta::NODE_TYPES + GENERATED + REGEXP + MISSING) - BLACKLIST
73
+ (Parser::Meta::NODE_TYPES + GENERATED + MISSING) - BLACKLIST
190
74
  ).freeze
191
75
  end # Types
192
76
  end # AST
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mutant
4
+ module Functor
5
+ include AbstractType
6
+
7
+ abstract_method :fmap
8
+
9
+ private
10
+
11
+ # Raise error unless block is provided
12
+ #
13
+ # @raise [MissingBlockError]
14
+ # if no block is given
15
+ #
16
+ # @return [self]
17
+ def require_block
18
+ fail LocalJumpError unless block_given?
19
+ self
20
+ end
21
+ end # Functor
22
+
23
+ class Maybe
24
+ include(
25
+ AbstractType,
26
+ Adamantium::Flat,
27
+ Functor
28
+ )
29
+
30
+ class Nothing < self
31
+ instance = new
32
+
33
+ define_method(:new) { instance }
34
+
35
+ # Evaluate functor block
36
+ #
37
+ # @return [Maybe::Nothing]
38
+ def fmap(&block)
39
+ require_block(&block)
40
+ end
41
+
42
+ # Evaluate applicative block
43
+ #
44
+ # @return [Maybe::Nothing]
45
+ def apply(&block)
46
+ require_block(&block)
47
+ end
48
+ end # Nothing
49
+
50
+ class Just < self
51
+ include Concord.new(:value)
52
+
53
+ # Evalute functor block
54
+ #
55
+ # @return [Maybe::Just<Object>]
56
+ def fmap
57
+ Just.new(yield(value))
58
+ end
59
+
60
+ # Evalute applicative block
61
+ #
62
+ # @return [Maybe]
63
+ def apply
64
+ yield(value)
65
+ end
66
+ end # Just
67
+ end # Maybe
68
+
69
+ class Either
70
+ include(
71
+ AbstractType,
72
+ Adamantium::Flat,
73
+ Concord.new(:value),
74
+ Functor
75
+ )
76
+
77
+ # Execute block and wrap error in left
78
+ #
79
+ # @param [Class:Exception] error
80
+ #
81
+ # @return [Either<Exception, Object>]
82
+ def self.wrap_error(error)
83
+ Right.new(yield)
84
+ rescue error => exception
85
+ Left.new(exception)
86
+ end
87
+
88
+ class Left < self
89
+ # Evaluate functor block
90
+ #
91
+ # @return [Either::Left<Object>]
92
+ def fmap(&block)
93
+ require_block(&block)
94
+ end
95
+
96
+ # Evaluate applicative block
97
+ #
98
+ # @return [Either::Left<Object>]
99
+ def apply(&block)
100
+ require_block(&block)
101
+ end
102
+
103
+ # Unwrap value from left
104
+ #
105
+ # @return [Object]
106
+ def from_left
107
+ value
108
+ end
109
+
110
+ # Unwrap value from right
111
+ #
112
+ # @return [Object]
113
+ #
114
+ # rubocop:disable Style/GuardClause
115
+ def from_right
116
+ if block_given?
117
+ yield(value)
118
+ else
119
+ fail "Expected right value, got #{inspect}"
120
+ end
121
+ end
122
+ # rubocop:enable Style/GuardClause
123
+
124
+ # Map over left value
125
+ #
126
+ # @return [Either::Right<Object>]
127
+ def lmap
128
+ Left.new(yield(value))
129
+ end
130
+
131
+ # Evaluate left side of branch
132
+ #
133
+ # @param [#call] left
134
+ # @param [#call] _right
135
+ def either(left, _right)
136
+ left.call(value)
137
+ end
138
+ end # Left
139
+
140
+ class Right < self
141
+ # Evaluate functor block
142
+ #
143
+ # @return [Either::Right<Object>]
144
+ def fmap
145
+ Right.new(yield(value))
146
+ end
147
+
148
+ # Evaluate applicative block
149
+ #
150
+ # @return [Either<Object>]
151
+ def apply
152
+ yield(value)
153
+ end
154
+
155
+ # Unwrap value from left
156
+ #
157
+ # @return [Object]
158
+ #
159
+ # rubocop:disable Style/GuardClause
160
+ def from_left
161
+ if block_given?
162
+ yield(value)
163
+ else
164
+ fail "Expected left value, got #{inspect}"
165
+ end
166
+ end
167
+ # rubocop:enable Style/GuardClause
168
+
169
+ # Unwrap value from right
170
+ #
171
+ # @return [Object]
172
+ def from_right
173
+ value
174
+ end
175
+
176
+ # Map over left value
177
+ #
178
+ # @return [Either::Right<Object>]
179
+ def lmap(&block)
180
+ require_block(&block)
181
+ end
182
+
183
+ # Evaluate right side of branch
184
+ #
185
+ # @param [#call] _left
186
+ # @param [#call] right
187
+ def either(_left, right)
188
+ right.call(value)
189
+ end
190
+ end # Right
191
+ end # Either
192
+ end # Mutant