mutant 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +9 -0
  3. data/Gemfile +4 -6
  4. data/Gemfile.devtools +65 -0
  5. data/Rakefile +2 -2
  6. data/config/devtools.yml +2 -0
  7. data/config/flay.yml +1 -1
  8. data/config/rubocop.yml +8 -9
  9. data/lib/mutant.rb +26 -3
  10. data/lib/mutant/cli/builder.rb +0 -11
  11. data/lib/mutant/constants.rb +12 -18
  12. data/lib/mutant/loader.rb +7 -16
  13. data/lib/mutant/mutation.rb +1 -1
  14. data/lib/mutant/mutator/node/binary.rb +58 -0
  15. data/lib/mutant/mutator/node/{while.rb → conditional_loop.rb} +2 -2
  16. data/lib/mutant/mutator/node/generic.rb +2 -1
  17. data/lib/mutant/node_helpers.rb +1 -1
  18. data/lib/mutant/version.rb +1 -1
  19. data/lib/mutant/zombifier.rb +2 -1
  20. data/mutant.gemspec +4 -3
  21. data/spec/integration/mutant/test_mutator_handles_types_spec.rb +1 -0
  22. data/spec/spec_helper.rb +1 -1
  23. data/spec/unit/mutant/cli/classifier/method_spec.rb +1 -1
  24. data/spec/unit/mutant/cli/classifier/namespace/flat_spec.rb +2 -2
  25. data/spec/unit/mutant/cli/classifier/namespace/recursive_spec.rb +2 -2
  26. data/spec/unit/mutant/differ_spec.rb +42 -0
  27. data/spec/unit/mutant/killer/{rspec/class_methods/new_spec.rb → rspec_spec.rb} +0 -0
  28. data/spec/unit/mutant/loader/{eval/class_methods/run_spec.rb → eval_spec.rb} +2 -2
  29. data/spec/unit/mutant/matcher/chain_spec.rb +57 -0
  30. data/spec/unit/mutant/matcher/method/instance_spec.rb +155 -0
  31. data/spec/unit/mutant/matcher/method/{singleton/each_spec.rb → singleton_spec.rb} +0 -0
  32. data/spec/unit/mutant/matcher/methods/{instance/each_spec.rb → instance_spec.rb} +0 -0
  33. data/spec/unit/mutant/matcher/methods/{singleton/each_spec.rb → singleton_spec.rb} +0 -0
  34. data/spec/unit/mutant/matcher/{namespace/each_spec.rb → namespace_spec.rb} +0 -0
  35. data/spec/unit/mutant/mutator/node/{and_asgn/mutation_spec.rb → and_asgn_spec.rb} +0 -0
  36. data/spec/unit/mutant/mutator/node/{begin/mutation_spec.rb → begin_spec.rb} +0 -0
  37. data/spec/unit/mutant/mutator/node/{connective/binary/mutation_spec.rb → binary_spec.rb} +1 -1
  38. data/spec/unit/mutant/mutator/node/{block_pass/mutation_spec.rb → block_pass_spec.rb} +0 -0
  39. data/spec/unit/mutant/mutator/node/{block/mutation_spec.rb → block_spec.rb} +0 -0
  40. data/spec/unit/mutant/mutator/node/{blockarg/mutation_spec.rb → blockarg_spec.rb} +0 -0
  41. data/spec/unit/mutant/mutator/node/{case/mutation_spec.rb → case_spec.rb} +0 -0
  42. data/spec/unit/mutant/mutator/node/{cbase/mutation_spec.rb → cbase_spec.rb} +0 -0
  43. data/spec/unit/mutant/mutator/node/conditional_loop_spec.rb +42 -0
  44. data/spec/unit/mutant/mutator/node/{const/mutation_spec.rb → const_spec.rb} +0 -0
  45. data/spec/unit/mutant/mutator/node/{define/mutation_spec.rb → define_spec.rb} +0 -0
  46. data/spec/unit/mutant/mutator/node/{defined_predicate/mutation_spec.rb → defined_spec.rb} +0 -0
  47. data/spec/unit/mutant/mutator/node/{dstr/mutation_spec.rb → dstr_spec.rb} +0 -0
  48. data/spec/unit/mutant/mutator/node/{dsym/mutation_spec.rb → dsym_spec.rb} +0 -0
  49. data/spec/unit/mutant/mutator/node/{ensure/mutation_spec.rb → ensure_spec.rb} +0 -0
  50. data/spec/unit/mutant/mutator/node/{if/mutation_spec.rb → if_spec.rb} +0 -0
  51. data/spec/unit/mutant/mutator/node/{kwbegin/mutation_spec.rb → kwbegin_spec.rb} +0 -0
  52. data/spec/unit/mutant/mutator/node/literal/{boolean/mutation_spec.rb → boolean_spec.rb} +0 -0
  53. data/spec/unit/mutant/mutator/node/{masgn/mutation_spec.rb → masgn_spec.rb} +0 -0
  54. data/spec/unit/mutant/mutator/node/{match_current_line/mutation_spec.rb → match_current_line_spec.rb} +1 -1
  55. data/spec/unit/mutant/mutator/node/named_value/{access/mutation_spec.rb → access_spec.rb} +0 -0
  56. data/spec/unit/mutant/mutator/node/named_value/{constant_assignment/mutation_spec.rb → constant_assignment_spec.rb} +0 -0
  57. data/spec/unit/mutant/mutator/node/named_value/{variable_assignment/mutation_spec.rb → variable_assignment_spec.rb} +0 -0
  58. data/spec/unit/mutant/mutator/node/{nthref/mutation_spec.rb → nthref_spec.rb} +0 -0
  59. data/spec/unit/mutant/mutator/node/{op_assgn/mutation_spec.rb → op_assgn_spec.rb} +0 -0
  60. data/spec/unit/mutant/mutator/node/{or_asgn/mutation_spec.rb → or_asgn_spec.rb} +0 -0
  61. data/spec/unit/mutant/mutator/node/{redo/mutation_spec.rb → redo_spec.rb} +0 -0
  62. data/spec/unit/mutant/mutator/node/{rescue/mutation_spec.rb → rescue_spec.rb} +0 -0
  63. data/spec/unit/mutant/mutator/node/{restarg/mutation_spec.rb → restarg_spec.rb} +0 -0
  64. data/spec/unit/mutant/mutator/node/{return/mutation_spec.rb → return_spec.rb} +0 -0
  65. data/spec/unit/mutant/mutator/node/{send/mutation_spec.rb → send_spec.rb} +0 -0
  66. data/spec/unit/mutant/mutator/node/{super/mutation_spec.rb → super_spec.rb} +0 -0
  67. data/spec/unit/mutant/mutator/node/{yield/mutation_spec.rb → yield_spec.rb} +0 -0
  68. data/spec/unit/mutant/mutator_spec.rb +29 -0
  69. data/spec/unit/mutant/runner/config_spec.rb +88 -0
  70. data/spec/unit/mutant/runner/{subject/success_predicate_spec.rb → subject_spec.rb} +0 -0
  71. data/spec/unit/mutant_spec.rb +43 -0
  72. data/test_app/Gemfile.devtools +65 -0
  73. metadata +119 -119
  74. data/lib/mutant/mutator/node/connective/binary.rb +0 -61
  75. data/lib/mutant/support/method_object.rb +0 -34
  76. data/spec/unit/mutant/class_methods/singleton_subclass_instance_spec.rb +0 -41
  77. data/spec/unit/mutant/differ/class_methods/build_spec.rb +0 -14
  78. data/spec/unit/mutant/differ/class_methods/colorize_line_spec.rb +0 -27
  79. data/spec/unit/mutant/matcher/chain/each_spec.rb +0 -43
  80. data/spec/unit/mutant/matcher/chain/matchers_spec.rb +0 -14
  81. data/spec/unit/mutant/matcher/each_spec.rb +0 -21
  82. data/spec/unit/mutant/matcher/method/instance/class_methods/build_spec.rb +0 -42
  83. data/spec/unit/mutant/matcher/method/instance/each_spec.rb +0 -114
  84. data/spec/unit/mutant/mutator/each_spec.rb +0 -27
  85. data/spec/unit/mutant/mutator/emit_new_spec.rb +0 -59
  86. data/spec/unit/mutant/mutator/emit_spec.rb +0 -55
  87. data/spec/unit/mutant/mutator/node/while/mutation_spec.rb +0 -24
  88. data/spec/unit/mutant/node_helpers/n_not_spec.rb +0 -14
  89. data/spec/unit/mutant/runner/config/subjects_spec.rb +0 -52
  90. data/spec/unit/mutant/runner/config/success_predicate_spec.rb +0 -57
@@ -18,12 +18,13 @@ Gem::Specification.new do |gem|
18
18
  gem.extra_rdoc_files = %w[TODO LICENSE]
19
19
  gem.executables = %w[mutant]
20
20
 
21
- gem.add_runtime_dependency('parser', '~> 2.0.0')
21
+ gem.add_runtime_dependency('parser', '~> 2.1.0')
22
+ gem.add_runtime_dependency('procto', '~> 0.0.2')
22
23
  gem.add_runtime_dependency('abstract_type', '~> 0.0.7')
23
- gem.add_runtime_dependency('unparser', '~> 0.1.4')
24
+ gem.add_runtime_dependency('unparser', '~> 0.1.6')
24
25
  gem.add_runtime_dependency('ice_nine', '~> 0.9')
25
26
  gem.add_runtime_dependency('descendants_tracker', '~> 0.0.1')
26
- gem.add_runtime_dependency('adamantium', '~> 0.1.0')
27
+ gem.add_runtime_dependency('adamantium', '~> 0.1')
27
28
  gem.add_runtime_dependency('equalizer', '~> 0.0.7')
28
29
  gem.add_runtime_dependency('inflecto', '~> 0.0.2')
29
30
  gem.add_runtime_dependency('anima', '~> 0.1.1')
@@ -3,6 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Mutant do
6
+
6
7
  specify 'mutant should not crash for any node parser can generate' do
7
8
  Mutant::NODE_TYPES.each do |type|
8
9
  Mutant::Mutator::Registry.lookup(Mutant::NodeHelpers.s(type))
@@ -22,7 +22,7 @@ if ENV['COVERAGE'] == 'true'
22
22
  end
23
23
 
24
24
  require 'equalizer'
25
- require 'triage/spec_helper'
25
+ require 'devtools/spec_helper'
26
26
  require 'mutant'
27
27
 
28
28
  $LOAD_PATH << File.join(TestApp.root, 'lib')
@@ -11,7 +11,7 @@ describe Mutant::CLI::Classifier::Method, '#each' do
11
11
  let(:unknown_method) { '::TestApp::Literal#unknown' }
12
12
 
13
13
  context 'with a block' do
14
- subject { object.each { } }
14
+ subject { object.each {} }
15
15
 
16
16
  context 'with an instance method name' do
17
17
  let(:input) { instance_method }
@@ -9,7 +9,7 @@ describe Mutant::CLI::Classifier::Namespace::Flat, '#each' do
9
9
  let(:unknown_namespace) { '::TestApp::Object' }
10
10
 
11
11
  context 'with a block' do
12
- subject { object.each { } }
12
+ subject { object.each {} }
13
13
 
14
14
  context 'with a known namespace' do
15
15
  let(:input) { known_namespace }
@@ -51,7 +51,7 @@ describe Mutant::CLI::Classifier::Namespace::Flat, '#each' do
51
51
  let(:input) { unknown_namespace }
52
52
 
53
53
  it 'raises an exception when #each is called' do
54
- expect { subject.each { } }.to raise_error(NameError)
54
+ expect { subject.each {} }.to raise_error(NameError)
55
55
  end
56
56
  end
57
57
  end
@@ -9,7 +9,7 @@ describe Mutant::CLI::Classifier::Namespace::Recursive, '#each' do
9
9
  let(:unknown_namespace) { '::TestApp::Object' }
10
10
 
11
11
  context 'with a block' do
12
- subject { object.each { } }
12
+ subject { object.each {} }
13
13
 
14
14
  context 'with a known namespace' do
15
15
  let(:input) { known_namespace }
@@ -51,7 +51,7 @@ describe Mutant::CLI::Classifier::Namespace::Recursive, '#each' do
51
51
  let(:input) { unknown_namespace }
52
52
 
53
53
  it 'raises an exception when #each is called' do
54
- expect { subject.each { } }.to raise_error(NameError)
54
+ expect { subject.each {} }.to raise_error(NameError)
55
55
  end
56
56
  end
57
57
  end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Mutant::Differ do
6
+ let(:object) { described_class }
7
+
8
+ describe '.build' do
9
+
10
+ subject { object.build(old_string, new_string) }
11
+
12
+ let(:old_string) { "foo\nbar" }
13
+ let(:new_string) { "bar\nbaz" }
14
+
15
+ it { should eql(Mutant::Differ.new(%w(foo bar), %w(bar baz))) }
16
+
17
+ end
18
+
19
+ describe '.colorize_line' do
20
+ let(:object) { described_class }
21
+
22
+ subject { object.colorize_line(line) }
23
+
24
+ context 'line beginning with "+"' do
25
+ let(:line) { '+line' }
26
+
27
+ it { should eql(Mutant::Color::GREEN.format(line)) }
28
+ end
29
+
30
+ context 'line beginning with "-"' do
31
+ let(:line) { '-line' }
32
+
33
+ it { should eql(Mutant::Color::RED.format(line)) }
34
+ end
35
+
36
+ context 'line beginning in other char' do
37
+ let(:line) { ' line' }
38
+
39
+ it { should eql(line) }
40
+ end
41
+ end
42
+ end
@@ -2,9 +2,9 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Mutant::Loader::Eval, '.run' do
5
+ describe Mutant::Loader::Eval, '.call' do
6
6
 
7
- subject { object.run(node, mutation_subject) }
7
+ subject { object.call(node, mutation_subject) }
8
8
 
9
9
  let(:object) { described_class }
10
10
  let(:path) { __FILE__ }
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Mutant::Matcher::Chain do
6
+
7
+ let(:object) { described_class.new(matchers) }
8
+
9
+ describe '#each' do
10
+ subject { object.each { |entry| yields << entry } }
11
+
12
+ let(:matchers) { [matcher_a, matcher_b] }
13
+
14
+ let(:matcher_a) { double('Matcher A') }
15
+ let(:matcher_b) { double('Matcher B') }
16
+
17
+ let(:subject_a) { double('Subject A') }
18
+ let(:subject_b) { double('Subject B') }
19
+
20
+ before do
21
+ matcher_a.stub(:each).and_yield(subject_a).and_return(matcher_a)
22
+ matcher_b.stub(:each).and_yield(subject_b).and_return(matcher_b)
23
+ end
24
+
25
+ # it_should_behave_like 'an #each method'
26
+ context 'with no block' do
27
+ subject { object.each }
28
+
29
+ it { should be_instance_of(to_enum.class) }
30
+
31
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
32
+ pending 'FIX RBX rspec? BUG HERE'
33
+ else
34
+ it 'yields the expected values' do
35
+ subject.to_a.should eql(object.to_a)
36
+ end
37
+ end
38
+ end
39
+
40
+ let(:yields) { [] }
41
+
42
+ it 'should yield subjects' do
43
+ expect { subject }.to change { yields }.from([]).to([subject_a, subject_b])
44
+ end
45
+ end
46
+
47
+ describe '#matchers' do
48
+ subject { object.matchers }
49
+
50
+ let(:matchers) { double('Matchers') }
51
+
52
+ it { should be(matchers) }
53
+
54
+ it_should_behave_like 'an idempotent method'
55
+ end
56
+
57
+ end
@@ -0,0 +1,155 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Mutant::Matcher::Method::Instance do
6
+
7
+ let(:cache) { Fixtures::AST_CACHE }
8
+
9
+ describe '#each' do
10
+ subject { object.each { |subject| yields << subject } }
11
+
12
+ let(:object) { described_class.new(cache, scope, method) }
13
+ let(:method) { scope.instance_method(method_name) }
14
+ let(:yields) { [] }
15
+ let(:namespace) { self.class }
16
+ let(:scope) { self.class::Foo }
17
+ let(:type) { :def }
18
+ let(:method_name) { :bar }
19
+ let(:method_arity) { 0 }
20
+
21
+ def name
22
+ node.children[0]
23
+ end
24
+
25
+ def arguments
26
+ node.children[1]
27
+ end
28
+
29
+ context 'when method is defined once' do
30
+ let(:base) { __LINE__ }
31
+ class self::Foo
32
+ def bar; end
33
+ end
34
+
35
+ let(:method_line) { 2 }
36
+
37
+ it_should_behave_like 'a method matcher'
38
+ end
39
+
40
+ context 'when method is defined multiple times' do
41
+ context 'on differend lines' do
42
+ let(:base) { __LINE__ }
43
+ class self::Foo
44
+ def bar
45
+ end
46
+
47
+ def bar(arg)
48
+ end
49
+ end
50
+
51
+ let(:method_line) { 5 }
52
+ let(:method_arity) { 1 }
53
+
54
+ it_should_behave_like 'a method matcher'
55
+ end
56
+
57
+ context 'on the same line' do
58
+ let(:base) { __LINE__ }
59
+ class self::Foo
60
+ def bar; end; def bar(arg); end
61
+ end
62
+
63
+ let(:method_line) { 2 }
64
+ let(:method_arity) { 1 }
65
+
66
+ it_should_behave_like 'a method matcher'
67
+ end
68
+
69
+ context 'on the same line with differend scope' do
70
+ let(:base) { __LINE__ }
71
+ class self::Foo
72
+ def self.bar; end; def bar(arg); end
73
+ end
74
+
75
+ let(:method_line) { 2 }
76
+ let(:method_arity) { 1 }
77
+
78
+ it_should_behave_like 'a method matcher'
79
+ end
80
+
81
+ context 'when nested' do
82
+ let(:pattern) { 'Foo::Bar#baz' }
83
+
84
+ context 'in class' do
85
+ let(:base) { __LINE__ }
86
+ class self::Foo
87
+ class Bar
88
+ def baz
89
+ end
90
+ end
91
+ end
92
+
93
+ let(:method_line) { 3 }
94
+ let(:method_name) { :baz }
95
+ let(:scope) { self.class::Foo::Bar }
96
+
97
+ it_should_behave_like 'a method matcher'
98
+ end
99
+
100
+ context 'in module' do
101
+ let(:base) { __LINE__ }
102
+ module self::Foo
103
+ class Bar
104
+ def baz
105
+ end
106
+ end
107
+ end
108
+
109
+ let(:method_line) { 3 }
110
+ let(:method_name) { :baz }
111
+ let(:scope) { self.class::Foo::Bar }
112
+
113
+ it_should_behave_like 'a method matcher'
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ describe '.build' do
120
+ let(:object) { described_class }
121
+
122
+ subject { object.build(cache, scope, method) }
123
+
124
+ let(:scope) do
125
+ Class.new do
126
+ include Adamantium
127
+
128
+ def foo
129
+ end
130
+ memoize :foo
131
+
132
+ def bar
133
+ end
134
+ end
135
+ end
136
+
137
+ let(:method) do
138
+ scope.instance_method(method_name)
139
+ end
140
+
141
+ context 'with adamantium infected scope' do
142
+ context 'with unmemoized method' do
143
+ let(:method_name) { :bar }
144
+
145
+ it { should eql(described_class.new(cache, scope, method)) }
146
+ end
147
+
148
+ context 'with memoized method' do
149
+ let(:method_name) { :foo }
150
+
151
+ it { should eql(described_class::Memoized.new(cache, scope, method)) }
152
+ end
153
+ end
154
+ end
155
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Mutant::Mutator::Node::Connective::Binary, 'mutations' do
5
+ describe Mutant::Mutator::Node::Binary, 'mutations' do
6
6
  context 'and' do
7
7
  let(:source) { 'true and false' }
8
8
 
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Mutant::Mutator::Node::ConditionalLoop do
6
+
7
+ context 'with while statement' do
8
+ let(:source) { 'while true; foo; bar; end' }
9
+
10
+ let(:mutations) do
11
+ mutations = []
12
+ mutations << 'while true; bar; end'
13
+ mutations << 'while true; foo; end'
14
+ mutations << 'while true; end'
15
+ mutations << 'while false; foo; bar; end'
16
+ mutations << 'while nil; foo; bar; end'
17
+ mutations << 'while true; foo; nil; end'
18
+ mutations << 'while true; nil; bar; end'
19
+ mutations << 'nil'
20
+ end
21
+
22
+ it_should_behave_like 'a mutator'
23
+ end
24
+
25
+ context 'with until statement' do
26
+ let(:source) { 'until true; foo; bar; end' }
27
+
28
+ let(:mutations) do
29
+ mutations = []
30
+ mutations << 'until true; bar; end'
31
+ mutations << 'until true; foo; end'
32
+ mutations << 'until true; end'
33
+ mutations << 'until false; foo; bar; end'
34
+ mutations << 'until nil; foo; bar; end'
35
+ mutations << 'until true; foo; nil; end'
36
+ mutations << 'until true; nil; bar; end'
37
+ mutations << 'nil'
38
+ end
39
+
40
+ it_should_behave_like 'a mutator'
41
+ end
42
+ end