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
@@ -1,61 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Mutant
4
- class Mutator
5
- class Node
6
- module Connective
7
-
8
- # Mutation emitter to handle binary connectives
9
- class Binary < Node
10
-
11
- INVERSE = {
12
- and: :or,
13
- or: :and
14
- }.freeze
15
-
16
- handle(*INVERSE.keys)
17
-
18
- children :left, :right
19
-
20
- private
21
-
22
- # Emit mutations
23
- #
24
- # @return [undefined]
25
- #
26
- # @api private
27
- #
28
- def dispatch
29
- emit_nil
30
- emit(left)
31
- emit(right)
32
- mutate_operator
33
- mutate_operands
34
- end
35
-
36
- # Emit operator mutations
37
- #
38
- # @return [undefined]
39
- #
40
- # @api private
41
- #
42
- def mutate_operator
43
- emit(s(INVERSE.fetch(node.type), left, right))
44
- end
45
-
46
- # Emit condition mutations
47
- #
48
- # @return [undefined]
49
- #
50
- # @api private
51
- #
52
- def mutate_operands
53
- emit(s(node.type, n_not(left), right))
54
- emit(n_not(node))
55
- end
56
-
57
- end # Binary
58
- end # Connective
59
- end # Node
60
- end # Mutator
61
- end # Mutant
@@ -1,34 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Mutant
4
- # A mixing to create method object semantics
5
- module MethodObject
6
-
7
- # Hook called when descendant is extended
8
- #
9
- # @param [Module|Class] descendant
10
- #
11
- # @return [undefined]
12
- #
13
- # @api private
14
- #
15
- def self.extended(descendant)
16
- descendant.class_eval do
17
- private_class_method :new
18
- end
19
- end
20
-
21
- # Run the method object
22
- #
23
- # Not aliased to prevent problems from inheritance
24
- #
25
- # @return [Objecct]
26
- #
27
- # @api private
28
- #
29
- def run(*args)
30
- new(*args)
31
- end
32
-
33
- end # MethodObject
34
- end # Mutant
@@ -1,41 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe Mutant, '.singleton_subclass_instance' do
6
- let(:object) { described_class }
7
-
8
- subject { object.singleton_subclass_instance(name, superclass, &block) }
9
-
10
- before do
11
- subject
12
- end
13
-
14
- let(:name) { 'Test' }
15
- let(:block) { proc { def foo; end } }
16
- let(:superclass) { Class.new }
17
-
18
- let(:generated) { superclass.const_get(:Test) }
19
-
20
- it_should_behave_like 'a command method'
21
-
22
- it 'sets expected name' do
23
- name = generated.class.name
24
- name.should eql("::#{self.name}")
25
- name.should be_frozen
26
- end
27
-
28
- it 'stores instance of subclass' do
29
- generated.should be_kind_of(superclass)
30
- end
31
-
32
- it 'evaluates the context of proc inside subclass' do
33
- generated.should respond_to(:foo)
34
- end
35
-
36
- it 'generates nice #inspect' do
37
- inspect = generated.inspect
38
- inspect.should eql("::#{self.name}")
39
- inspect.should be_frozen
40
- end
41
- end
@@ -1,14 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe Mutant::Differ, '.build' do
6
- let(:object) { described_class }
7
-
8
- subject { object.build(old_string, new_string) }
9
-
10
- let(:old_string) { "foo\nbar" }
11
- let(:new_string) { "bar\nbaz" }
12
-
13
- it { should eql(Mutant::Differ.new(%w(foo bar), %w(bar baz))) }
14
- end
@@ -1,27 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe Mutant::Differ, '.colorize_line' do
6
- let(:object) { described_class }
7
-
8
- subject { object.colorize_line(line) }
9
-
10
- context 'line beginning with "+"' do
11
- let(:line) { '+line' }
12
-
13
- it { should eql(Mutant::Color::GREEN.format(line)) }
14
- end
15
-
16
- context 'line beginning with "-"' do
17
- let(:line) { '-line' }
18
-
19
- it { should eql(Mutant::Color::RED.format(line)) }
20
- end
21
-
22
- context 'line beginning in other char' do
23
- let(:line) { ' line' }
24
-
25
- it { should eql(line) }
26
- end
27
- end
@@ -1,43 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe Mutant::Matcher::Chain, '#each' do
6
- subject { object.each { |entry| yields << entry } }
7
-
8
- let(:object) { described_class.new(matchers) }
9
-
10
- let(:matchers) { [matcher_a, matcher_b] }
11
-
12
- let(:matcher_a) { double('Matcher A') }
13
- let(:matcher_b) { double('Matcher B') }
14
-
15
- let(:subject_a) { double('Subject A') }
16
- let(:subject_b) { double('Subject B') }
17
-
18
- before do
19
- matcher_a.stub(:each).and_yield(subject_a).and_return(matcher_a)
20
- matcher_b.stub(:each).and_yield(subject_b).and_return(matcher_b)
21
- end
22
-
23
- # it_should_behave_like 'an #each method'
24
- context 'with no block' do
25
- subject { object.each }
26
-
27
- it { should be_instance_of(to_enum.class) }
28
-
29
- if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
30
- pending 'FIX RBX rspec? BUG HERE'
31
- else
32
- it 'yields the expected values' do
33
- subject.to_a.should eql(object.to_a)
34
- end
35
- end
36
- end
37
-
38
- let(:yields) { [] }
39
-
40
- it 'should yield subjects' do
41
- expect { subject }.to change { yields }.from([]).to([subject_a, subject_b])
42
- end
43
- end
@@ -1,14 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe Mutant::Matcher::Chain, '#matchers' do
6
- subject { object.matchers }
7
-
8
- let(:object) { described_class.new(matchers) }
9
- let(:matchers) { double('Matchers') }
10
-
11
- it { should be(matchers) }
12
-
13
- it_should_behave_like 'an idempotent method'
14
- end
@@ -1,21 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- # This spec is only present to ensure 100% test coverage.
6
- # The code should not be triggered on runtime.
7
-
8
- describe Mutant::Matcher, '#each' do
9
- subject { object.send(:each) }
10
-
11
- let(:object) { described_class.allocate }
12
-
13
- it 'should raise error' do
14
- expect do
15
- subject
16
- end.to raise_error(
17
- NotImplementedError,
18
- 'Mutant::Matcher#each is not implemented'
19
- )
20
- end
21
- end
@@ -1,42 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe Mutant::Matcher::Method::Instance, '.build' do
6
- let(:object) { described_class }
7
-
8
- subject { object.build(cache, scope, method) }
9
-
10
- let(:cache) { double }
11
-
12
- let(:scope) do
13
- Class.new do
14
- include Adamantium
15
-
16
- def foo
17
- end
18
- memoize :foo
19
-
20
- def bar
21
- end
22
- end
23
- end
24
-
25
- let(:method) do
26
- scope.instance_method(method_name)
27
- end
28
-
29
- context 'with adamantium infected scope' do
30
- context 'with unmemoized method' do
31
- let(:method_name) { :bar }
32
-
33
- it { should eql(described_class.new(cache, scope, method)) }
34
- end
35
-
36
- context 'with memoized method' do
37
- let(:method_name) { :foo }
38
-
39
- it { should eql(described_class::Memoized.new(cache, scope, method)) }
40
- end
41
- end
42
- end
@@ -1,114 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe Mutant::Matcher::Method::Instance, '#each' do
6
- subject { object.each { |subject| yields << subject } }
7
-
8
- let(:cache) { Fixtures::AST_CACHE }
9
- let(:object) { described_class.new(cache, scope, method) }
10
- let(:method) { scope.instance_method(method_name) }
11
- let(:yields) { [] }
12
- let(:namespace) { self.class }
13
- let(:scope) { self.class::Foo }
14
- let(:type) { :def }
15
- let(:method_name) { :bar }
16
- let(:method_arity) { 0 }
17
-
18
- def name
19
- node.children[0]
20
- end
21
-
22
- def arguments
23
- node.children[1]
24
- end
25
-
26
- context 'when method is defined once' do
27
- let(:base) { __LINE__ }
28
- class self::Foo
29
- def bar; end
30
- end
31
-
32
- let(:method_line) { 2 }
33
-
34
- it_should_behave_like 'a method matcher'
35
- end
36
-
37
- context 'when method is defined multiple times' do
38
- context 'on differend lines' do
39
- let(:base) { __LINE__ }
40
- class self::Foo
41
- def bar
42
- end
43
-
44
- def bar(arg)
45
- end
46
- end
47
-
48
- let(:method_line) { 5 }
49
- let(:method_arity) { 1 }
50
-
51
- it_should_behave_like 'a method matcher'
52
- end
53
-
54
- context 'on the same line' do
55
- let(:base) { __LINE__ }
56
- class self::Foo
57
- def bar; end; def bar(arg); end
58
- end
59
-
60
- let(:method_line) { 2 }
61
- let(:method_arity) { 1 }
62
-
63
- it_should_behave_like 'a method matcher'
64
- end
65
-
66
- context 'on the same line with differend scope' do
67
- let(:base) { __LINE__ }
68
- class self::Foo
69
- def self.bar; end; def bar(arg); end
70
- end
71
-
72
- let(:method_line) { 2 }
73
- let(:method_arity) { 1 }
74
-
75
- it_should_behave_like 'a method matcher'
76
- end
77
-
78
- context 'when nested' do
79
- let(:pattern) { 'Foo::Bar#baz' }
80
-
81
- context 'in class' do
82
- let(:base) { __LINE__ }
83
- class self::Foo
84
- class Bar
85
- def baz
86
- end
87
- end
88
- end
89
-
90
- let(:method_line) { 3 }
91
- let(:method_name) { :baz }
92
- let(:scope) { self.class::Foo::Bar }
93
-
94
- it_should_behave_like 'a method matcher'
95
- end
96
-
97
- context 'in module' do
98
- let(:base) { __LINE__ }
99
- module self::Foo
100
- class Bar
101
- def baz
102
- end
103
- end
104
- end
105
-
106
- let(:method_line) { 3 }
107
- let(:method_name) { :baz }
108
- let(:scope) { self.class::Foo::Bar }
109
-
110
- it_should_behave_like 'a method matcher'
111
- end
112
- end
113
- end
114
- end
@@ -1,27 +0,0 @@
1
- # encoding: utf-8
2
-
3
- # This file is the sandbox for new mutations.
4
- # Once finished mutation test will be moved to class specfic
5
- # file.
6
-
7
- require 'spec_helper'
8
-
9
- describe Mutant::Mutator, '.each' do
10
-
11
- pending 'interpolated string literal (DynamicString)' do
12
- let(:source) { '"foo#{1}bar"' }
13
-
14
- let(:random_string) { 'this-is-random' }
15
-
16
- let(:mutations) do
17
- mutations = []
18
- mutations << 'nil'
19
- end
20
-
21
- before do
22
- Mutant::Random.stub(hex_string: random_string)
23
- end
24
-
25
- it_should_behave_like 'a mutator'
26
- end
27
- end