mutant 0.8.20 → 0.8.21

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