mutant 0.11.9 → 0.11.12

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mutant/ast/pattern/lexer.rb +171 -0
  3. data/lib/mutant/ast/pattern/parser.rb +194 -0
  4. data/lib/mutant/ast/pattern/source.rb +39 -0
  5. data/lib/mutant/ast/pattern/token.rb +15 -0
  6. data/lib/mutant/ast/pattern.rb +125 -0
  7. data/lib/mutant/ast/structure.rb +890 -0
  8. data/lib/mutant/bootstrap.rb +8 -7
  9. data/lib/mutant/cli/command/environment.rb +5 -3
  10. data/lib/mutant/cli/command/util.rb +17 -2
  11. data/lib/mutant/config.rb +76 -40
  12. data/lib/mutant/env.rb +1 -1
  13. data/lib/mutant/license/subscription/opensource.rb +1 -1
  14. data/lib/mutant/matcher/method.rb +8 -1
  15. data/lib/mutant/meta/example.rb +4 -1
  16. data/lib/mutant/mutation/config.rb +36 -0
  17. data/lib/mutant/mutator/node/arguments.rb +1 -1
  18. data/lib/mutant/mutator/node/begin.rb +2 -1
  19. data/lib/mutant/mutator/node/define.rb +5 -2
  20. data/lib/mutant/mutator/node/kwargs.rb +2 -2
  21. data/lib/mutant/mutator/node/literal/regex.rb +1 -1
  22. data/lib/mutant/mutator/node/literal/symbol.rb +2 -2
  23. data/lib/mutant/mutator/node/named_value/constant_assignment.rb +1 -1
  24. data/lib/mutant/mutator/node/named_value/variable_assignment.rb +2 -2
  25. data/lib/mutant/mutator/node/regexp/capture_group.rb +3 -5
  26. data/lib/mutant/mutator/node/regexp/named_group.rb +5 -5
  27. data/lib/mutant/mutator/node/resbody.rb +0 -10
  28. data/lib/mutant/mutator/node.rb +47 -1
  29. data/lib/mutant/mutator/util/array.rb +0 -17
  30. data/lib/mutant/mutator.rb +2 -26
  31. data/lib/mutant/parallel/driver.rb +18 -2
  32. data/lib/mutant/reporter/cli/printer/config.rb +1 -1
  33. data/lib/mutant/runner.rb +4 -0
  34. data/lib/mutant/subject/config.rb +5 -4
  35. data/lib/mutant/subject.rb +4 -1
  36. data/lib/mutant/transform.rb +14 -0
  37. data/lib/mutant/version.rb +1 -1
  38. data/lib/mutant/world.rb +1 -0
  39. data/lib/mutant.rb +9 -1
  40. metadata +9 -2
@@ -3,33 +3,13 @@
3
3
  module Mutant
4
4
  # Generator for mutations
5
5
  class Mutator
6
-
7
- REGISTRY = Registry.new(->(_) { Node::Generic })
8
-
9
6
  include(
10
7
  Adamantium,
11
- Concord.new(:input, :parent),
12
8
  AbstractType,
9
+ Anima.new(:input, :parent),
13
10
  Procto
14
11
  )
15
12
 
16
- # Lookup and invoke dedicated AST mutator
17
- #
18
- # @param node [Parser::AST::Node]
19
- # @param parent [nil,Mutant::Mutator::Node]
20
- #
21
- # @return [Set<Parser::AST::Node>]
22
- def self.mutate(node, parent = nil)
23
- self::REGISTRY.lookup(node.type).call(node, parent)
24
- end
25
-
26
- def self.handle(*types)
27
- types.each do |type|
28
- self::REGISTRY.register(type, self)
29
- end
30
- end
31
- private_class_method :handle
32
-
33
13
  # Return output
34
14
  #
35
15
  # @return [Set<Parser::AST::Node>]
@@ -39,7 +19,7 @@ module Mutant
39
19
 
40
20
  private
41
21
 
42
- def initialize(_input, _parent = nil)
22
+ def initialize(_attributes)
43
23
  super
44
24
 
45
25
  @output = Set.new
@@ -60,10 +40,6 @@ module Mutant
60
40
  output << object
61
41
  end
62
42
 
63
- def run(mutator)
64
- mutator.call(input).each(&method(:emit))
65
- end
66
-
67
43
  def dup_input
68
44
  input.dup
69
45
  end
@@ -4,7 +4,7 @@ module Mutant
4
4
  module Parallel
5
5
  # Driver for parallelized execution
6
6
  class Driver
7
- include Adamantium, Anima.new(
7
+ include Anima.new(
8
8
  :threads,
9
9
  :var_active_jobs,
10
10
  :var_final,
@@ -16,6 +16,11 @@ module Mutant
16
16
 
17
17
  private(*anima.attribute_names)
18
18
 
19
+ def initialize(**attributes)
20
+ @alive = true
21
+ super
22
+ end
23
+
19
24
  # Wait for computation to finish, with timeout
20
25
  #
21
26
  # @param [Float] timeout
@@ -23,11 +28,22 @@ module Mutant
23
28
  # @return [Variable::Result<Sink#status>]
24
29
  # current status
25
30
  def wait_timeout(timeout)
26
- var_final.take_timeout(timeout)
31
+ var_final.take_timeout(timeout) if @alive
27
32
 
28
33
  finalize(status)
29
34
  end
30
35
 
36
+ # Stop parallel computation
37
+ #
38
+ # This will cause all work to be immediately stopped.
39
+ #
40
+ # @return [self]
41
+ def stop
42
+ @alive = false
43
+ threads.each(&:kill)
44
+ self
45
+ end
46
+
31
47
  private
32
48
 
33
49
  def finalize(status)
@@ -20,7 +20,7 @@ module Mutant
20
20
  info 'Jobs: %s', object.jobs || 'auto'
21
21
  info 'Includes: %s', object.includes
22
22
  info 'Requires: %s', object.requires
23
- info 'MutationTimeout: %0.9g', object.mutation_timeout if object.mutation_timeout
23
+ info 'MutationTimeout: %0.9g', object.mutation.timeout if object.mutation.timeout
24
24
  end
25
25
  # rubocop:enable Metrics/AbcSize
26
26
 
data/lib/mutant/runner.rb CHANGED
@@ -25,6 +25,10 @@ module Mutant
25
25
  private_class_method :run_mutation_analysis
26
26
 
27
27
  def self.run_driver(reporter, driver)
28
+ Signal.trap('INT') do
29
+ driver.stop
30
+ end
31
+
28
32
  loop do
29
33
  status = driver.wait_timeout(reporter.delay)
30
34
  break status.payload if status.done?
@@ -3,16 +3,17 @@
3
3
  module Mutant
4
4
  class Subject
5
5
  class Config
6
- include Adamantium, Anima.new(:inline_disable)
6
+ include Adamantium, Anima.new(:inline_disable, :mutation)
7
7
 
8
- DEFAULT = new(inline_disable: false)
8
+ DEFAULT = new(inline_disable: false, mutation: Mutation::Config::DEFAULT)
9
9
 
10
10
  DISABLE_REGEXP = /(\s|^)mutant:disable(?:\s|$)/.freeze
11
11
  SYNTAX_REGEXP = /\A(?:#|=begin\n)/.freeze
12
12
 
13
- def self.parse(comments)
13
+ def self.parse(comments:, mutation:)
14
14
  new(
15
- inline_disable: comments.any? { |comment| DISABLE_REGEXP.match?(comment_body(comment)) }
15
+ inline_disable: comments.any? { |comment| DISABLE_REGEXP.match?(comment_body(comment)) },
16
+ mutation: mutation
16
17
  )
17
18
  end
18
19
 
@@ -12,7 +12,10 @@ module Mutant
12
12
  # @return [undefined]
13
13
  def mutations
14
14
  [neutral_mutation].concat(
15
- Mutator.mutate(node).map do |mutant|
15
+ Mutator::Node.mutate(
16
+ config: config.mutation,
17
+ node: node
18
+ ).map do |mutant|
16
19
  Mutation::Evil.new(self, wrap_node(mutant))
17
20
  end
18
21
  )
@@ -421,6 +421,20 @@ module Mutant
421
421
  end
422
422
  end # Sequence
423
423
 
424
+ # Always successful transformation
425
+ class Success < self
426
+ include Concord.new(:block)
427
+
428
+ # Apply transformation to input
429
+ #
430
+ # @param [Object]
431
+ #
432
+ # @return [Either<Error, Object>]
433
+ def call(input)
434
+ success(block.call(input))
435
+ end
436
+ end # Sequence
437
+
424
438
  # Generic exception transformer
425
439
  class Exception < self
426
440
  include Concord.new(:error_class, :block)
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Mutant
4
4
  # Current mutant version
5
- VERSION = '0.11.9'
5
+ VERSION = '0.11.12'
6
6
  end # Mutant
data/lib/mutant/world.rb CHANGED
@@ -18,6 +18,7 @@ module Mutant
18
18
  :open3,
19
19
  :pathname,
20
20
  :process,
21
+ :random,
21
22
  :stderr,
22
23
  :stdout,
23
24
  :thread,
data/lib/mutant.rb CHANGED
@@ -76,6 +76,12 @@ require 'mutant/ast/meta/const'
76
76
  require 'mutant/ast/meta/symbol'
77
77
  require 'mutant/ast/meta/optarg'
78
78
  require 'mutant/ast/meta/resbody'
79
+ require 'mutant/ast/pattern'
80
+ require 'mutant/ast/pattern/lexer'
81
+ require 'mutant/ast/pattern/parser'
82
+ require 'mutant/ast/pattern/source'
83
+ require 'mutant/ast/pattern/token'
84
+ require 'mutant/ast/structure'
79
85
  require 'mutant/parser'
80
86
  require 'mutant/isolation'
81
87
  require 'mutant/isolation/exception'
@@ -87,6 +93,7 @@ require 'mutant/parallel/source'
87
93
  require 'mutant/parallel/worker'
88
94
  require 'mutant/require_highjack'
89
95
  require 'mutant/mutation'
96
+ require 'mutant/mutation/config'
90
97
  require 'mutant/mutator'
91
98
  require 'mutant/mutator/util'
92
99
  require 'mutant/mutator/util/array'
@@ -256,6 +263,7 @@ module Mutant
256
263
  open3: Open3,
257
264
  pathname: Pathname,
258
265
  process: Process,
266
+ random: Random,
259
267
  stderr: $stderr,
260
268
  stdout: $stdout,
261
269
  thread: Thread,
@@ -281,7 +289,7 @@ module Mutant
281
289
  isolation: Mutant::Isolation::Fork.new(WORLD),
282
290
  jobs: nil,
283
291
  matcher: Matcher::Config::DEFAULT,
284
- mutation_timeout: nil,
292
+ mutation: Mutation::Config::DEFAULT,
285
293
  reporter: Reporter::CLI.build(WORLD.stdout),
286
294
  requires: EMPTY_ARRAY,
287
295
  zombie: false
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.9
4
+ version: 0.11.12
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-05-01 00:00:00.000000000 Z
11
+ date: 2022-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diff-lcs
@@ -179,6 +179,11 @@ files:
179
179
  - lib/mutant/ast/named_children.rb
180
180
  - lib/mutant/ast/node_predicates.rb
181
181
  - lib/mutant/ast/nodes.rb
182
+ - lib/mutant/ast/pattern.rb
183
+ - lib/mutant/ast/pattern/lexer.rb
184
+ - lib/mutant/ast/pattern/parser.rb
185
+ - lib/mutant/ast/pattern/source.rb
186
+ - lib/mutant/ast/pattern/token.rb
182
187
  - lib/mutant/ast/regexp.rb
183
188
  - lib/mutant/ast/regexp/transformer.rb
184
189
  - lib/mutant/ast/regexp/transformer/direct.rb
@@ -189,6 +194,7 @@ files:
189
194
  - lib/mutant/ast/regexp/transformer/root.rb
190
195
  - lib/mutant/ast/regexp/transformer/text.rb
191
196
  - lib/mutant/ast/sexp.rb
197
+ - lib/mutant/ast/structure.rb
192
198
  - lib/mutant/ast/types.rb
193
199
  - lib/mutant/bootstrap.rb
194
200
  - lib/mutant/cli.rb
@@ -243,6 +249,7 @@ files:
243
249
  - lib/mutant/meta/example/dsl.rb
244
250
  - lib/mutant/meta/example/verification.rb
245
251
  - lib/mutant/mutation.rb
252
+ - lib/mutant/mutation/config.rb
246
253
  - lib/mutant/mutator.rb
247
254
  - lib/mutant/mutator/node.rb
248
255
  - lib/mutant/mutator/node/and_asgn.rb