mutant 0.11.9 → 0.11.12

Sign up to get free protection for your applications and to get access to all the features.
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