mutant 0.3.1 → 0.3.2

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 (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