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
@@ -18,7 +18,7 @@ module Mutant
18
18
  #
19
19
  # @return [AST::Node]
20
20
  def call(path)
21
- @cache[path] ||= ::Parser::CurrentRuby.parse(path.read)
21
+ @cache[path] ||= Unparser.parse(path.read)
22
22
  end
23
23
 
24
24
  end # Parser
@@ -11,44 +11,46 @@ module Mutant
11
11
 
12
12
  delegate :mutation, :test_result
13
13
 
14
- DIFF_ERROR_MESSAGE =
15
- 'BUG: Mutation NOT resulted in exactly one diff hunk. Please report a reproduction!'.freeze
16
-
17
14
  MAP = {
18
15
  Mutant::Mutation::Evil => :evil_details,
19
16
  Mutant::Mutation::Neutral => :neutral_details,
20
17
  Mutant::Mutation::Noop => :noop_details
21
18
  }.freeze
22
19
 
23
- NEUTRAL_MESSAGE =
24
- "--- Neutral failure ---\n" \
25
- "Original code was inserted unmutated. And the test did NOT PASS.\n" \
26
- "Your tests do not pass initially or you found a bug in mutant / unparser.\n" \
27
- "Subject AST:\n" \
28
- "%s\n" \
29
- "Unparsed Source:\n" \
30
- "%s\n" \
31
- "Test Result:\n".freeze
32
-
33
- NO_DIFF_MESSAGE =
34
- "--- Internal failure ---\n" \
35
- "BUG: Mutation NOT resulted in exactly one diff hunk. Please report a reproduction!\n" \
36
- "Original unparsed source:\n" \
37
- "%s\n" \
38
- "Original AST:\n" \
39
- "%s\n" \
40
- "Mutated unparsed source:\n" \
41
- "%s\n" \
42
- "Mutated AST:\n" \
43
- "%s\n".freeze
44
-
45
- NOOP_MESSAGE =
46
- "---- Noop failure -----\n" \
47
- "No code was inserted. And the test did NOT PASS.\n" \
48
- "This is typically a problem of your specs not passing unmutated.\n" \
49
- "Test Result:\n".freeze
50
-
51
- FOOTER = '-----------------------'.freeze
20
+ NEUTRAL_MESSAGE = <<~'MESSAGE'
21
+ --- Neutral failure ---
22
+ Original code was inserted unmutated. And the test did NOT PASS.
23
+ Your tests do not pass initially or you found a bug in mutant / unparser.
24
+ Subject AST:
25
+ %s
26
+ Unparsed Source:
27
+ %s
28
+ Test Result:
29
+ MESSAGE
30
+
31
+ NO_DIFF_MESSAGE = <<~'MESSAGE'
32
+ --- Internal failure ---
33
+ BUG: A generted mutation did not result in exactly one diff hunk!
34
+ This is an invariant violation by the mutation generation engine.
35
+ Please report a reproduction to https://github.com/mbj/mutant
36
+ Original unparsed source:
37
+ %s
38
+ Original AST:
39
+ %s
40
+ Mutated unparsed source:
41
+ %s
42
+ Mutated AST:
43
+ %s
44
+ MESSAGE
45
+
46
+ NOOP_MESSAGE = <<~'MESSAGE'
47
+ ---- Noop failure -----
48
+ No code was inserted. And the test did NOT PASS.
49
+ This is typically a problem of your specs not passing unmutated.
50
+ Test Result:
51
+ MESSAGE
52
+
53
+ FOOTER = '-----------------------'
52
54
 
53
55
  # Run report printer
54
56
  #
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Mutant
4
4
  # Current mutant version
5
- VERSION = '0.8.20'.freeze
5
+ VERSION = '0.8.21'.freeze
6
6
  end # Mutant
@@ -5,7 +5,7 @@ module Mutant
5
5
  class WarningFilter
6
6
  include Equalizer.new(:target)
7
7
 
8
- WARNING_PATTERN = /\A(?:.+):(?:\d+): warning: (?:.+)\n\z/
8
+ WARNING_PATTERN = /\A(?:.+):(?:\d+): warning: (?:.+)\n\z/.freeze
9
9
 
10
10
  # Initialize object
11
11
  #
@@ -115,7 +115,7 @@ module Mutant
115
115
  #
116
116
  # @return [Parser::AST::Node]
117
117
  def namespaced_node(source_path)
118
- s(:module, s(:const, nil, namespace), ::Parser::CurrentRuby.parse(source_path.read))
118
+ s(:module, s(:const, nil, namespace), Unparser.parse(source_path.read))
119
119
  end
120
120
 
121
121
  end # Zombifier
@@ -24,8 +24,8 @@ Mutant::Meta::Example.add :block do
24
24
  mutation 'foo { |a, b| raise }'
25
25
  mutation 'foo { |a, _b| }'
26
26
  mutation 'foo { |_a, b| }'
27
- mutation 'foo { |a| }'
28
- mutation 'foo { |b| }'
27
+ mutation 'foo { |a, | }'
28
+ mutation 'foo { |b, | }'
29
29
  mutation 'foo { || }'
30
30
  end
31
31
 
@@ -39,7 +39,7 @@ Mutant::Meta::Example.add :block do
39
39
  mutation 'foo { |(a), c| }'
40
40
  mutation 'foo { |(b), c| }'
41
41
  mutation 'foo { |(a, b)| }'
42
- mutation 'foo { |c| }'
42
+ mutation 'foo { |c, | }'
43
43
  mutation 'foo { |(_a, b), c| }'
44
44
  mutation 'foo { |(a, _b), c| }'
45
45
  mutation 'foo { |(a, b), _c| }'
@@ -61,6 +61,25 @@ Mutant::Meta::Example.add :block do
61
61
  mutation 'foo {}'
62
62
  end
63
63
 
64
+ Mutant::Meta::Example.add :block do
65
+ source 'foo { |_a| }'
66
+
67
+ singleton_mutations
68
+ mutation 'foo { || }'
69
+ mutation 'foo { |_a| raise }'
70
+ mutation 'foo'
71
+ end
72
+
73
+ Mutant::Meta::Example.add :block do
74
+ source 'foo { |a| }'
75
+
76
+ singleton_mutations
77
+ mutation 'foo { || }'
78
+ mutation 'foo { |a| raise }'
79
+ mutation 'foo { |_a| }'
80
+ mutation 'foo'
81
+ end
82
+
64
83
  Mutant::Meta::Example.add :block do
65
84
  source 'foo { |(a)| }'
66
85
 
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ Mutant::Meta::Example.add :index do
4
+ source 'self.foo[]'
5
+
6
+ singleton_mutations
7
+ mutation 'self.foo'
8
+ mutation 'self.foo.at()'
9
+ mutation 'self.foo.fetch()'
10
+ mutation 'self.foo.key?()'
11
+ mutation 'self[]'
12
+ mutation 'foo[]'
13
+ end
14
+
15
+ Mutant::Meta::Example.add :index do
16
+ source 'foo[1]'
17
+
18
+ singleton_mutations
19
+ mutation '1'
20
+ mutation 'foo'
21
+ mutation 'foo[]'
22
+ mutation 'foo.at(1)'
23
+ mutation 'foo.fetch(1)'
24
+ mutation 'foo.key?(1)'
25
+ mutation 'self[1]'
26
+ mutation 'foo[0]'
27
+ mutation 'foo[2]'
28
+ mutation 'foo[-1]'
29
+ mutation 'foo[nil]'
30
+ mutation 'foo[self]'
31
+ end
32
+
33
+ Mutant::Meta::Example.add :index do
34
+ source 'foo[n..-2]'
35
+
36
+ singleton_mutations
37
+ mutation 'n..-2'
38
+ mutation 'foo'
39
+ mutation 'foo[]'
40
+ mutation 'foo.at(n..-2)'
41
+ mutation 'foo.fetch(n..-2)'
42
+ mutation 'foo.key?(n..-2)'
43
+ mutation 'self[n..-2]'
44
+ mutation 'foo[nil]'
45
+ mutation 'foo[self]'
46
+ mutation 'foo[n..nil]'
47
+ mutation 'foo[n..self]'
48
+ mutation 'foo[n..-1]'
49
+ mutation 'foo[n..2]'
50
+ mutation 'foo[n..0]'
51
+ mutation 'foo[n..1]'
52
+ mutation 'foo[n..-3]'
53
+ mutation 'foo[n...-2]'
54
+ mutation 'foo[nil..-2]'
55
+ mutation 'foo[self..-2]'
56
+ end
57
+
58
+ Mutant::Meta::Example.add :index do
59
+ source 'foo[n...-1]'
60
+
61
+ singleton_mutations
62
+ mutation 'n...-1'
63
+ mutation 'foo'
64
+ mutation 'foo[]'
65
+ mutation 'foo.at(n...-1)'
66
+ mutation 'foo.fetch(n...-1)'
67
+ mutation 'foo.key?(n...-1)'
68
+ mutation 'self[n...-1]'
69
+ mutation 'foo[nil]'
70
+ mutation 'foo[self]'
71
+ mutation 'foo[n...nil]'
72
+ mutation 'foo[n...self]'
73
+ mutation 'foo[n..-1]'
74
+ mutation 'foo[n...0]'
75
+ mutation 'foo[n...1]'
76
+ mutation 'foo[n...-2]'
77
+ mutation 'foo[nil...-1]'
78
+ mutation 'foo[self...-1]'
79
+ end
80
+
81
+ Mutant::Meta::Example.add :index do
82
+ source 'foo[n..-1]'
83
+
84
+ singleton_mutations
85
+ mutation 'n..-1'
86
+ mutation 'foo'
87
+ mutation 'foo[]'
88
+ mutation 'foo.at(n..-1)'
89
+ mutation 'foo.fetch(n..-1)'
90
+ mutation 'foo.key?(n..-1)'
91
+ mutation 'self[n..-1]'
92
+ mutation 'foo[nil]'
93
+ mutation 'foo[self]'
94
+ mutation 'foo[n..nil]'
95
+ mutation 'foo[n..self]'
96
+ mutation 'foo[n..0]'
97
+ mutation 'foo[n..1]'
98
+ mutation 'foo[n..-2]'
99
+ mutation 'foo[n...-1]'
100
+ mutation 'foo[nil..-1]'
101
+ mutation 'foo[self..-1]'
102
+ mutation 'foo.drop(n)'
103
+ end
104
+
105
+ Mutant::Meta::Example.add :index do
106
+ source 'self[foo]'
107
+
108
+ singleton_mutations
109
+ mutation 'self[self]'
110
+ mutation 'self[nil]'
111
+ mutation 'self[]'
112
+ mutation 'self.at(foo)'
113
+ mutation 'self.fetch(foo)'
114
+ mutation 'self.key?(foo)'
115
+ mutation 'foo'
116
+ end
117
+
118
+ Mutant::Meta::Example.add :index do
119
+ source 'foo[*bar]'
120
+
121
+ singleton_mutations
122
+ mutation 'foo'
123
+ mutation 'foo[]'
124
+ mutation 'foo.at(*bar)'
125
+ mutation 'foo.fetch(*bar)'
126
+ mutation 'foo.key?(*bar)'
127
+ mutation 'foo[nil]'
128
+ mutation 'foo[self]'
129
+ mutation 'foo[bar]'
130
+ mutation 'foo[*self]'
131
+ mutation 'foo[*nil]'
132
+ mutation 'self[*bar]'
133
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ Mutant::Meta::Example.add :indexasgn do
4
+ source 'foo[bar] = baz'
5
+
6
+ singleton_mutations
7
+ mutation 'self[bar] = baz'
8
+ mutation 'foo'
9
+ mutation 'foo[bar]'
10
+ mutation 'foo.at(bar)'
11
+ mutation 'foo.fetch(bar)'
12
+ mutation 'foo.key?(bar)'
13
+ mutation 'foo[bar] = self'
14
+ mutation 'foo[bar] = nil'
15
+ mutation 'foo[nil] = baz'
16
+ mutation 'foo[self] = baz'
17
+ mutation 'foo[] = baz'
18
+ mutation 'baz'
19
+ mutation 'bar'
20
+ end
21
+
22
+ Mutant::Meta::Example.add :indexasgn, :op_asgn do
23
+ source 'self[foo] += bar'
24
+
25
+ singleton_mutations
26
+ mutation 'self[] += bar'
27
+ mutation 'self[nil] += bar'
28
+ mutation 'self[self] += bar'
29
+ mutation 'self[foo] += nil'
30
+ mutation 'self[foo] += self'
31
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ Mutant::Meta::Example.add :block, :lambda do
4
+ source '->() {}'
5
+
6
+ singleton_mutations
7
+
8
+ mutation '->() { raise }'
9
+ end
@@ -80,10 +80,3 @@ Pathname
80
80
  .glob(Pathname.new(__dir__).join('regexp', '*.rb'))
81
81
  .sort
82
82
  .each(&Kernel.public_method(:require))
83
-
84
- # Re-register examples for all regular expression nodes for node_type `:regexp`
85
- Mutant::Meta::Example::ALL.each do |example|
86
- next unless example.node_type.to_s.start_with?('regexp_')
87
-
88
- Mutant::Meta::Example::ALL << example.with(node_type: :regexp)
89
- end
@@ -12,7 +12,7 @@ mutations = {
12
12
  mutations = mutations.merge(mutations.invert)
13
13
 
14
14
  mutations.each do |(source_type, source_mutation), (_, regexp_mutation)|
15
- Mutant::Meta::Example.add source_type do
15
+ Mutant::Meta::Example.add :regexp, source_type do
16
16
  source(source_mutation)
17
17
 
18
18
  singleton_mutations
@@ -353,20 +353,6 @@ Mutant::Meta::Example.add :send do
353
353
  mutation 'baz'
354
354
  end
355
355
 
356
- Mutant::Meta::Example.add :send do
357
- source 'foo[bar] = baz'
358
-
359
- singleton_mutations
360
- mutation 'foo'
361
- mutation 'foo[bar]'
362
- mutation 'foo[bar] = self'
363
- mutation 'foo[bar] = nil'
364
- mutation 'foo[nil] = baz'
365
- mutation 'foo[self] = baz'
366
- mutation 'foo[] = baz'
367
- mutation 'baz'
368
- end
369
-
370
356
  Mutant::Meta::Example.add :send do
371
357
  source 'foo(*bar)'
372
358
 
@@ -484,36 +470,6 @@ Mutant::Meta::Example.add :send do
484
470
  mutation 'self / foo'
485
471
  end
486
472
 
487
- Mutant::Meta::Example.add :send do
488
- source 'foo[1]'
489
-
490
- singleton_mutations
491
- mutation '1'
492
- mutation 'foo'
493
- mutation 'foo[]'
494
- mutation 'foo.at(1)'
495
- mutation 'foo.fetch(1)'
496
- mutation 'foo.key?(1)'
497
- mutation 'self[1]'
498
- mutation 'foo[0]'
499
- mutation 'foo[2]'
500
- mutation 'foo[-1]'
501
- mutation 'foo[nil]'
502
- mutation 'foo[self]'
503
- end
504
-
505
- Mutant::Meta::Example.add :send do
506
- source 'self.foo[]'
507
-
508
- singleton_mutations
509
- mutation 'self.foo'
510
- mutation 'self.foo.at()'
511
- mutation 'self.foo.fetch()'
512
- mutation 'self.foo.key?()'
513
- mutation 'self[]'
514
- mutation 'foo[]'
515
- end
516
-
517
473
  Mutant::Meta::Example.add :send do
518
474
  source 'foo(n..-1)'
519
475
 
@@ -532,108 +488,6 @@ Mutant::Meta::Example.add :send do
532
488
  mutation 'foo(n..-2)'
533
489
  end
534
490
 
535
- Mutant::Meta::Example.add :send do
536
- source 'foo[n..-2]'
537
-
538
- singleton_mutations
539
- mutation 'n..-2'
540
- mutation 'foo'
541
- mutation 'foo[]'
542
- mutation 'foo.at(n..-2)'
543
- mutation 'foo.fetch(n..-2)'
544
- mutation 'foo.key?(n..-2)'
545
- mutation 'self[n..-2]'
546
- mutation 'foo[nil]'
547
- mutation 'foo[self]'
548
- mutation 'foo[n..nil]'
549
- mutation 'foo[n..self]'
550
- mutation 'foo[n..-1]'
551
- mutation 'foo[n..2]'
552
- mutation 'foo[n..0]'
553
- mutation 'foo[n..1]'
554
- mutation 'foo[n..-3]'
555
- mutation 'foo[n...-2]'
556
- mutation 'foo[nil..-2]'
557
- mutation 'foo[self..-2]'
558
- end
559
-
560
- Mutant::Meta::Example.add :send do
561
- source 'foo[n...-1]'
562
-
563
- singleton_mutations
564
- mutation 'n...-1'
565
- mutation 'foo'
566
- mutation 'foo[]'
567
- mutation 'foo.at(n...-1)'
568
- mutation 'foo.fetch(n...-1)'
569
- mutation 'foo.key?(n...-1)'
570
- mutation 'self[n...-1]'
571
- mutation 'foo[nil]'
572
- mutation 'foo[self]'
573
- mutation 'foo[n...nil]'
574
- mutation 'foo[n...self]'
575
- mutation 'foo[n..-1]'
576
- mutation 'foo[n...0]'
577
- mutation 'foo[n...1]'
578
- mutation 'foo[n...-2]'
579
- mutation 'foo[nil...-1]'
580
- mutation 'foo[self...-1]'
581
- end
582
-
583
- Mutant::Meta::Example.add :send do
584
- source 'foo[n..-1]'
585
-
586
- singleton_mutations
587
- mutation 'n..-1'
588
- mutation 'foo'
589
- mutation 'foo[]'
590
- mutation 'foo.at(n..-1)'
591
- mutation 'foo.fetch(n..-1)'
592
- mutation 'foo.key?(n..-1)'
593
- mutation 'self[n..-1]'
594
- mutation 'foo[nil]'
595
- mutation 'foo[self]'
596
- mutation 'foo[n..nil]'
597
- mutation 'foo[n..self]'
598
- mutation 'foo[n..0]'
599
- mutation 'foo[n..1]'
600
- mutation 'foo[n..-2]'
601
- mutation 'foo[n...-1]'
602
- mutation 'foo[nil..-1]'
603
- mutation 'foo[self..-1]'
604
- mutation 'foo.drop(n)'
605
- end
606
-
607
- Mutant::Meta::Example.add :send do
608
- source 'self[foo]'
609
-
610
- singleton_mutations
611
- mutation 'self[self]'
612
- mutation 'self[nil]'
613
- mutation 'self[]'
614
- mutation 'self.at(foo)'
615
- mutation 'self.fetch(foo)'
616
- mutation 'self.key?(foo)'
617
- mutation 'foo'
618
- end
619
-
620
- Mutant::Meta::Example.add :send do
621
- source 'foo[*bar]'
622
-
623
- singleton_mutations
624
- mutation 'foo'
625
- mutation 'foo[]'
626
- mutation 'foo.at(*bar)'
627
- mutation 'foo.fetch(*bar)'
628
- mutation 'foo.key?(*bar)'
629
- mutation 'foo[nil]'
630
- mutation 'foo[self]'
631
- mutation 'foo[bar]'
632
- mutation 'foo[*self]'
633
- mutation 'foo[*nil]'
634
- mutation 'self[*bar]'
635
- end
636
-
637
491
  (Mutant::AST::Types::BINARY_METHOD_OPERATORS - %i[=~ <= >= < > == != eql?]).each do |operator|
638
492
  Mutant::Meta::Example.add :send do
639
493
  source "true #{operator} false"