mutant 0.9.9 → 0.9.14
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.
- checksums.yaml +4 -4
- data/lib/mutant.rb +2 -4
- data/lib/mutant/bootstrap.rb +14 -1
- data/lib/mutant/cli.rb +6 -0
- data/lib/mutant/isolation.rb +1 -1
- data/lib/mutant/isolation/fork.rb +2 -2
- data/lib/mutant/isolation/none.rb +1 -1
- data/lib/mutant/matcher/config.rb +2 -0
- data/lib/mutant/meta/example.rb +16 -4
- data/lib/mutant/meta/example/dsl.rb +33 -16
- data/lib/mutant/meta/example/verification.rb +70 -28
- data/lib/mutant/minitest/coverage.rb +53 -0
- data/lib/mutant/mutator/node.rb +2 -2
- data/lib/mutant/mutator/node/block_pass.rb +29 -0
- data/lib/mutant/mutator/node/{dstr.rb → dynamic_literal.rb} +7 -5
- data/lib/mutant/mutator/node/index.rb +4 -4
- data/lib/mutant/mutator/node/literal/range.rb +4 -1
- data/lib/mutant/mutator/node/noop.rb +1 -1
- data/lib/mutant/mutator/node/op_asgn.rb +15 -1
- data/lib/mutant/mutator/node/send.rb +25 -1
- data/lib/mutant/mutator/node/send/attribute_assignment.rb +1 -0
- data/lib/mutant/reporter/cli/printer.rb +2 -2
- data/lib/mutant/reporter/cli/printer/isolation_result.rb +9 -3
- data/lib/mutant/reporter/cli/printer/mutation_result.rb +1 -1
- data/lib/mutant/subject/method/instance.rb +41 -2
- data/lib/mutant/version.rb +1 -1
- metadata +59 -347
- data/.github/workflows/ci.yml +0 -121
- data/.gitignore +0 -38
- data/.rspec +0 -5
- data/.rubocop.yml +0 -7
- data/Changelog.md +0 -81
- data/Gemfile +0 -7
- data/Gemfile.lock +0 -167
- data/Gemfile.shared +0 -10
- data/README.md +0 -178
- data/Rakefile +0 -5
- data/config/devtools.yml +0 -2
- data/config/reek.yml +0 -139
- data/config/rubocop.yml +0 -205
- data/config/yardstick.yml +0 -2
- data/docs/commercial-support.md +0 -14
- data/docs/concurrency.md +0 -39
- data/docs/incremental.md +0 -76
- data/docs/known-problems.md +0 -30
- data/docs/limitations.md +0 -50
- data/docs/mutant-minitest.md +0 -149
- data/docs/mutant-rspec.md +0 -130
- data/docs/nomenclature.md +0 -82
- data/docs/reading-reports.md +0 -74
- data/lib/mutant/color.rb +0 -40
- data/lib/mutant/diff.rb +0 -97
- data/lib/mutant/mutator/node/dsym.rb +0 -22
- data/meta/and.rb +0 -13
- data/meta/and_asgn.rb +0 -14
- data/meta/array.rb +0 -27
- data/meta/begin.rb +0 -20
- data/meta/block.rb +0 -199
- data/meta/block_pass.rb +0 -8
- data/meta/blockarg.rb +0 -10
- data/meta/break.rb +0 -9
- data/meta/case.rb +0 -217
- data/meta/casgn.rb +0 -25
- data/meta/cbase.rb +0 -8
- data/meta/class.rb +0 -12
- data/meta/const.rb +0 -17
- data/meta/csend.rb +0 -10
- data/meta/cvar.rb +0 -7
- data/meta/cvasgn.rb +0 -9
- data/meta/date.rb +0 -59
- data/meta/def.rb +0 -196
- data/meta/defined.rb +0 -9
- data/meta/dstr.rb +0 -13
- data/meta/dsym.rb +0 -14
- data/meta/ensure.rb +0 -8
- data/meta/false.rb +0 -7
- data/meta/file.rb +0 -5
- data/meta/float.rb +0 -37
- data/meta/gvar.rb +0 -7
- data/meta/gvasgn.rb +0 -9
- data/meta/hash.rb +0 -20
- data/meta/if.rb +0 -72
- data/meta/index.rb +0 -133
- data/meta/indexasgn.rb +0 -31
- data/meta/int.rb +0 -18
- data/meta/ivar.rb +0 -8
- data/meta/ivasgn.rb +0 -22
- data/meta/kwarg.rb +0 -10
- data/meta/kwbegin.rb +0 -8
- data/meta/kwoptarg.rb +0 -13
- data/meta/lambda.rb +0 -23
- data/meta/line.rb +0 -5
- data/meta/lvar.rb +0 -16
- data/meta/lvasgn.rb +0 -24
- data/meta/masgn.rb +0 -7
- data/meta/match_current_line.rb +0 -14
- data/meta/next.rb +0 -10
- data/meta/nil.rb +0 -5
- data/meta/nthref.rb +0 -14
- data/meta/op_assgn.rb +0 -17
- data/meta/or.rb +0 -13
- data/meta/or_asgn.rb +0 -50
- data/meta/range.rb +0 -39
- data/meta/redo.rb +0 -5
- data/meta/regexp.rb +0 -80
- data/meta/regopt.rb +0 -10
- data/meta/rescue.rb +0 -84
- data/meta/return.rb +0 -16
- data/meta/sclass.rb +0 -12
- data/meta/self.rb +0 -7
- data/meta/send.rb +0 -600
- data/meta/str.rb +0 -7
- data/meta/super.rb +0 -27
- data/meta/sym.rb +0 -8
- data/meta/true.rb +0 -7
- data/meta/until.rb +0 -16
- data/meta/while.rb +0 -24
- data/meta/yield.rb +0 -9
- data/mutant-minitest.gemspec +0 -22
- data/mutant-rspec.gemspec +0 -22
- data/mutant.gemspec +0 -41
- data/mutant.sh +0 -12
- data/mutant.yml +0 -6
- data/spec/integration/mutant/corpus_spec.rb +0 -15
- data/spec/integration/mutant/isolation/fork_spec.rb +0 -28
- data/spec/integration/mutant/minitest_spec.rb +0 -11
- data/spec/integration/mutant/null_spec.rb +0 -16
- data/spec/integration/mutant/rspec_spec.rb +0 -15
- data/spec/integration/mutant/test_mutator_handles_types_spec.rb +0 -9
- data/spec/integrations.yml +0 -63
- data/spec/shared/base_behavior.rb +0 -45
- data/spec/shared/framework_integration_behavior.rb +0 -70
- data/spec/shared/method_matcher_behavior.rb +0 -47
- data/spec/spec_helper.rb +0 -75
- data/spec/support/corpus.rb +0 -318
- data/spec/support/file_system.rb +0 -62
- data/spec/support/ice_nine_config.rb +0 -10
- data/spec/support/ruby_vm.rb +0 -84
- data/spec/support/shared_context.rb +0 -169
- data/spec/support/test_app.rb +0 -7
- data/spec/support/warnings.yml +0 -6
- data/spec/support/xspec.rb +0 -183
- data/spec/unit/mutant/ast/find_metaclass_containing_spec.rb +0 -64
- data/spec/unit/mutant/ast/meta/optarg_spec.rb +0 -24
- data/spec/unit/mutant/ast/meta/send/proc_predicate_spec.rb +0 -30
- data/spec/unit/mutant/ast/meta/send/receiver_possible_top_level_const_predicate_spec.rb +0 -39
- data/spec/unit/mutant/ast/meta/send_spec.rb +0 -42
- data/spec/unit/mutant/ast/named_children_spec.rb +0 -89
- data/spec/unit/mutant/ast/sexp_spec.rb +0 -38
- data/spec/unit/mutant/ast_spec.rb +0 -57
- data/spec/unit/mutant/bootstrap_spec.rb +0 -216
- data/spec/unit/mutant/cli_spec.rb +0 -305
- data/spec/unit/mutant/clock_monotonic_spec.rb +0 -52
- data/spec/unit/mutant/config_spec.rb +0 -126
- data/spec/unit/mutant/context_spec.rb +0 -111
- data/spec/unit/mutant/diff_spec.rb +0 -189
- data/spec/unit/mutant/env_spec.rb +0 -229
- data/spec/unit/mutant/expression/method_spec.rb +0 -62
- data/spec/unit/mutant/expression/methods_spec.rb +0 -66
- data/spec/unit/mutant/expression/namespace/exact_spec.rb +0 -28
- data/spec/unit/mutant/expression/namespace/recursive_spec.rb +0 -66
- data/spec/unit/mutant/expression/parser_spec.rb +0 -65
- data/spec/unit/mutant/expression_spec.rb +0 -45
- data/spec/unit/mutant/integration/rspec_spec.rb +0 -201
- data/spec/unit/mutant/integration_spec.rb +0 -150
- data/spec/unit/mutant/isolation/fork_spec.rb +0 -309
- data/spec/unit/mutant/isolation/none_spec.rb +0 -23
- data/spec/unit/mutant/isolation/result_spec.rb +0 -73
- data/spec/unit/mutant/license_spec.rb +0 -305
- data/spec/unit/mutant/loader_spec.rb +0 -79
- data/spec/unit/mutant/matcher/chain_spec.rb +0 -26
- data/spec/unit/mutant/matcher/compiler_spec.rb +0 -0
- data/spec/unit/mutant/matcher/config_spec.rb +0 -47
- data/spec/unit/mutant/matcher/filter_spec.rb +0 -22
- data/spec/unit/mutant/matcher/method/instance_spec.rb +0 -164
- data/spec/unit/mutant/matcher/method/metaclass_spec.rb +0 -108
- data/spec/unit/mutant/matcher/method/singleton_spec.rb +0 -90
- data/spec/unit/mutant/matcher/methods/instance_spec.rb +0 -54
- data/spec/unit/mutant/matcher/methods/metaclass_spec.rb +0 -62
- data/spec/unit/mutant/matcher/methods/singleton_spec.rb +0 -51
- data/spec/unit/mutant/matcher/namespace_spec.rb +0 -39
- data/spec/unit/mutant/matcher/null_spec.rb +0 -12
- data/spec/unit/mutant/matcher/scope_spec.rb +0 -45
- data/spec/unit/mutant/matcher/static_spec.rb +0 -13
- data/spec/unit/mutant/matcher_spec.rb +0 -102
- data/spec/unit/mutant/meta/example/dsl_spec.rb +0 -108
- data/spec/unit/mutant/meta/example/verification_spec.rb +0 -154
- data/spec/unit/mutant/meta/example_spec.rb +0 -34
- data/spec/unit/mutant/mutation_spec.rb +0 -140
- data/spec/unit/mutant/mutator/node_spec.rb +0 -47
- data/spec/unit/mutant/mutator_spec.rb +0 -21
- data/spec/unit/mutant/parallel/driver_spec.rb +0 -126
- data/spec/unit/mutant/parallel/source/array_spec.rb +0 -57
- data/spec/unit/mutant/parallel/worker_spec.rb +0 -206
- data/spec/unit/mutant/parallel_spec.rb +0 -115
- data/spec/unit/mutant/parser_spec.rb +0 -26
- data/spec/unit/mutant/range_spec.rb +0 -141
- data/spec/unit/mutant/registry_spec.rb +0 -74
- data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +0 -17
- data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +0 -85
- data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +0 -45
- data/spec/unit/mutant/reporter/cli/printer/isolation_result_spec.rb +0 -132
- data/spec/unit/mutant/reporter/cli/printer/mutation_progress_result_spec.rb +0 -25
- data/spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb +0 -153
- data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +0 -45
- data/spec/unit/mutant/reporter/cli/printer/subject_progress_spec.rb +0 -36
- data/spec/unit/mutant/reporter/cli/printer/subject_result_spec.rb +0 -44
- data/spec/unit/mutant/reporter/cli/printer/test_result_spec.rb +0 -16
- data/spec/unit/mutant/reporter/cli/printer_spec.rb +0 -163
- data/spec/unit/mutant/reporter/cli_spec.rb +0 -137
- data/spec/unit/mutant/reporter/null_spec.rb +0 -14
- data/spec/unit/mutant/reporter/sequence_spec.rb +0 -31
- data/spec/unit/mutant/repository/diff/ranges_spec.rb +0 -180
- data/spec/unit/mutant/repository/diff_spec.rb +0 -122
- data/spec/unit/mutant/repository/subject_filter_spec.rb +0 -30
- data/spec/unit/mutant/require_highjack_spec.rb +0 -73
- data/spec/unit/mutant/result/class_methods_spec.rb +0 -51
- data/spec/unit/mutant/result/env_spec.rb +0 -161
- data/spec/unit/mutant/result/mutation_spec.rb +0 -70
- data/spec/unit/mutant/result/subject_spec.rb +0 -111
- data/spec/unit/mutant/result/test_spec.rb +0 -14
- data/spec/unit/mutant/result_spec.rb +0 -33
- data/spec/unit/mutant/runner/sink_spec.rb +0 -174
- data/spec/unit/mutant/runner_spec.rb +0 -121
- data/spec/unit/mutant/selector/expression_spec.rb +0 -62
- data/spec/unit/mutant/selector/null_spec.rb +0 -17
- data/spec/unit/mutant/subject/method/instance_spec.rb +0 -181
- data/spec/unit/mutant/subject/method/metaclass_spec.rb +0 -63
- data/spec/unit/mutant/subject/method/singleton_spec.rb +0 -61
- data/spec/unit/mutant/subject_spec.rb +0 -93
- data/spec/unit/mutant/transform/array_spec.rb +0 -92
- data/spec/unit/mutant/transform/bool_spec.rb +0 -63
- data/spec/unit/mutant/transform/error_spec.rb +0 -132
- data/spec/unit/mutant/transform/exception_spec.rb +0 -44
- data/spec/unit/mutant/transform/hash_spec.rb +0 -236
- data/spec/unit/mutant/transform/index_spec.rb +0 -92
- data/spec/unit/mutant/transform/named_spec.rb +0 -49
- data/spec/unit/mutant/transform/primitive_spec.rb +0 -56
- data/spec/unit/mutant/transform/sequence_spec.rb +0 -98
- data/spec/unit/mutant/util/one_spec.rb +0 -22
- data/spec/unit/mutant/warnings_spec.rb +0 -89
- data/spec/unit/mutant/world_spec.rb +0 -63
- data/spec/unit/mutant/zombifier_spec.rb +0 -122
- data/test_app/.rspec +0 -1
- data/test_app/Gemfile.minitest +0 -4
- data/test_app/Gemfile.rspec3.8 +0 -7
- data/test_app/lib/test_app.rb +0 -110
- data/test_app/lib/test_app/literal.rb +0 -35
- data/test_app/lib/test_app/metaclasses.rb +0 -108
- data/test_app/spec/spec_helper.rb +0 -9
- data/test_app/spec/unit/test_app/literal_spec.rb +0 -20
- data/test_app/test/unit/test_app/literal_test.rb +0 -16
@@ -1,64 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Mutant::AST::FindMetaclassContaining do
|
4
|
-
describe '#call' do
|
5
|
-
subject { described_class.call(ast, node) }
|
6
|
-
|
7
|
-
let(:metaclass_node) { s(:sclass, s(:self), method_node) }
|
8
|
-
let(:method_node) { s(:def, 'test', s(:nil)) }
|
9
|
-
|
10
|
-
let(:ast) { metaclass_node }
|
11
|
-
let(:node) { method_node }
|
12
|
-
|
13
|
-
context 'when called without ast' do
|
14
|
-
let(:ast) { nil }
|
15
|
-
|
16
|
-
it { expect { subject }.to raise_error }
|
17
|
-
end
|
18
|
-
|
19
|
-
context 'when called without node' do
|
20
|
-
let(:node) { nil }
|
21
|
-
|
22
|
-
it { is_expected.to be nil }
|
23
|
-
end
|
24
|
-
|
25
|
-
context 'when called with ast which contains a duplicate of the node' do
|
26
|
-
let(:node) { s(:def, 'test', s(:nil)) }
|
27
|
-
|
28
|
-
shared_examples_for 'unfooled by the duplicate node' do
|
29
|
-
it { is_expected.to be nil }
|
30
|
-
|
31
|
-
# if we changed method_node or node without altering the other to match,
|
32
|
-
# the above example would provide a false positive. by ensuring node and
|
33
|
-
# method_node are eq but not equal, we ensure the usefulness of the
|
34
|
-
# above example.
|
35
|
-
it { expect(node).to eq(method_node) }
|
36
|
-
it { expect(node).not_to be method_node }
|
37
|
-
end
|
38
|
-
|
39
|
-
it_behaves_like 'unfooled by the duplicate node'
|
40
|
-
|
41
|
-
context 'when the node is in a begin block' do
|
42
|
-
let(:metaclass_node) { s(:sclass, s(:self), s(:begin, method_node)) }
|
43
|
-
|
44
|
-
it_behaves_like 'unfooled by the duplicate node'
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
context 'when called with ast containing the node' do
|
49
|
-
it { is_expected.to be metaclass_node }
|
50
|
-
|
51
|
-
context 'inside a begin block' do
|
52
|
-
let(:metaclass_node) { s(:sclass, s(:self), s(:begin, method_node)) }
|
53
|
-
|
54
|
-
it { is_expected.to be metaclass_node }
|
55
|
-
end
|
56
|
-
|
57
|
-
context 'inside a different class' do
|
58
|
-
let(:metaclass_node) { s(:sclass, s(:self), s(:class, :MyClass, nil, method_node)) }
|
59
|
-
|
60
|
-
it { is_expected.to be nil }
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Mutant::AST::Meta::Optarg do
|
4
|
-
subject(:object) { described_class.new(node) }
|
5
|
-
|
6
|
-
let(:node) { s(:optarg, name, value) }
|
7
|
-
let(:name) { :foo }
|
8
|
-
let(:value) { s(:sym, :bar) }
|
9
|
-
|
10
|
-
its(:name) { should be(:foo) }
|
11
|
-
its(:default_value) { should eql(s(:sym, :bar)) }
|
12
|
-
|
13
|
-
describe '#used?' do
|
14
|
-
subject { object.used? }
|
15
|
-
|
16
|
-
it { should be true }
|
17
|
-
|
18
|
-
context 'when name is prefixed with an underscore' do
|
19
|
-
let(:name) { :_foo }
|
20
|
-
it { should be false }
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Mutant::AST::Meta::Send, '#proc?' do
|
4
|
-
subject { described_class.new(node).proc? }
|
5
|
-
|
6
|
-
shared_context 'proc send' do |source|
|
7
|
-
let(:node) { Unparser.parse(source).children.first }
|
8
|
-
end
|
9
|
-
|
10
|
-
shared_examples 'proc definition' do |*args|
|
11
|
-
include_context 'proc send', *args
|
12
|
-
|
13
|
-
it { should be(true) }
|
14
|
-
end
|
15
|
-
|
16
|
-
shared_examples 'not a proc definition' do |*args|
|
17
|
-
include_context 'proc send', *args
|
18
|
-
|
19
|
-
it { should be_falsey }
|
20
|
-
end
|
21
|
-
|
22
|
-
it_behaves_like 'proc definition', 'proc { }'
|
23
|
-
it_behaves_like 'proc definition', 'Proc.new { }'
|
24
|
-
it_behaves_like 'not a proc definition', 'new { }'
|
25
|
-
it_behaves_like 'not a proc definition', 'foo.proc { }'
|
26
|
-
it_behaves_like 'not a proc definition', 'Proc.blah { }'
|
27
|
-
it_behaves_like 'not a proc definition', 'Proc().new { }'
|
28
|
-
it_behaves_like 'not a proc definition', 'Foo.new { }'
|
29
|
-
it_behaves_like 'not a proc definition', 'blah { }'
|
30
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Mutant::AST::Meta::Send, '#receiver_possible_top_level_const?' do
|
4
|
-
subject { described_class.new(node).receiver_possible_top_level_const? }
|
5
|
-
|
6
|
-
def parse(source)
|
7
|
-
Unparser.parse(source)
|
8
|
-
end
|
9
|
-
|
10
|
-
context 'when implicit top level const' do
|
11
|
-
let(:node) { parse('Foo.bar') }
|
12
|
-
|
13
|
-
it { should be true }
|
14
|
-
end
|
15
|
-
|
16
|
-
context 'when cbase' do
|
17
|
-
let(:node) { parse('::Foo.bar') }
|
18
|
-
|
19
|
-
it { should be true }
|
20
|
-
end
|
21
|
-
|
22
|
-
context 'when nested const' do
|
23
|
-
let(:node) { parse('Baz::Foo.bar') }
|
24
|
-
|
25
|
-
it { should be false }
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'when no receiver' do
|
29
|
-
let(:node) { parse('bar') }
|
30
|
-
|
31
|
-
it { should be false }
|
32
|
-
end
|
33
|
-
|
34
|
-
context 'when send receiver' do
|
35
|
-
let(:node) { parse('foo.bar') }
|
36
|
-
|
37
|
-
it { should be false }
|
38
|
-
end
|
39
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Mutant::AST::Meta::Send do
|
4
|
-
let(:object) { described_class.new(node) }
|
5
|
-
|
6
|
-
def parse(source)
|
7
|
-
Unparser.parse(source)
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:method_call) { parse('foo.bar(baz)') }
|
11
|
-
let(:attribute_read) { parse('foo.bar') }
|
12
|
-
let(:attribute_assignment) { parse('foo.bar = baz') }
|
13
|
-
let(:binary_method_operator) { parse('foo == bar') }
|
14
|
-
|
15
|
-
class Expectation
|
16
|
-
include Adamantium, Anima.new(:name, :attribute_assignment, :binary_method_operator)
|
17
|
-
|
18
|
-
ALL = [
|
19
|
-
[:method_call, false, false],
|
20
|
-
[:attribute_read, false, false],
|
21
|
-
[:attribute_assignment, true, false],
|
22
|
-
[:binary_method_operator, false, true]
|
23
|
-
].map do |values|
|
24
|
-
new(Hash[anima.attribute_names.zip(values)])
|
25
|
-
end.freeze
|
26
|
-
end # Expectation
|
27
|
-
|
28
|
-
# Rspec should have a build in for this kind of "n-dimensional assertion with context"
|
29
|
-
(Expectation.anima.attribute_names - %i[name]).each do |name|
|
30
|
-
describe "##{name}?" do
|
31
|
-
subject { object.public_send(:"#{name}?") }
|
32
|
-
|
33
|
-
Expectation::ALL.each do |expectation|
|
34
|
-
context "on #{expectation.name}" do
|
35
|
-
let(:node) { public_send(expectation.name) }
|
36
|
-
|
37
|
-
it { should be(expectation.public_send(name)) }
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,89 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Mutant::AST::NamedChildren do
|
4
|
-
describe '.included' do
|
5
|
-
let(:klass) do
|
6
|
-
Class.new do
|
7
|
-
include Mutant::AST::NamedChildren, Concord.new(:node)
|
8
|
-
|
9
|
-
children :foo, :bar
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def publish
|
14
|
-
klass.class_eval do
|
15
|
-
public :foo, :bar
|
16
|
-
|
17
|
-
public :remaining_children, :remaining_children_indices, :remaining_children_with_index
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
let(:instance) { klass.new(node) }
|
22
|
-
|
23
|
-
let(:node_foo) { s(:foo) }
|
24
|
-
let(:node_bar) { s(:bar) }
|
25
|
-
let(:node_baz) { s(:baz) }
|
26
|
-
|
27
|
-
let(:node) { s(:node, node_foo, node_bar, node_baz) }
|
28
|
-
|
29
|
-
describe 'generated methods' do
|
30
|
-
specify 'are private by default' do
|
31
|
-
%i[
|
32
|
-
foo
|
33
|
-
bar
|
34
|
-
remaining_children
|
35
|
-
remaining_children_indices
|
36
|
-
remaining_children_with_index
|
37
|
-
].each do |name|
|
38
|
-
expect(klass.private_instance_methods.include?(name)).to be(true)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe '#remaining_children' do
|
43
|
-
it 'returns remaining unnamed children' do
|
44
|
-
publish
|
45
|
-
expect(instance.remaining_children).to eql([node_baz])
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe '#remaining_children_indices' do
|
50
|
-
it 'returns remaining unnamed children indices' do
|
51
|
-
publish
|
52
|
-
expect(instance.remaining_children_indices).to eql([2])
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe '#remaining_children_with_index' do
|
57
|
-
it 'returns remaining unnamed children indices' do
|
58
|
-
publish
|
59
|
-
expect(instance.remaining_children_with_index).to eql([[node_baz, 2]])
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
describe '#foo' do
|
64
|
-
it 'returns named child foo' do
|
65
|
-
publish
|
66
|
-
expect(instance.foo).to be(node_foo)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe '#bar' do
|
71
|
-
context 'when node is present' do
|
72
|
-
it 'returns named child bar' do
|
73
|
-
publish
|
74
|
-
expect(instance.bar).to be(node_bar)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context 'when node is NOT present' do
|
79
|
-
let(:node) { s(:node, node_foo) }
|
80
|
-
|
81
|
-
it 'returns nil' do
|
82
|
-
publish
|
83
|
-
expect(instance.bar).to be(nil)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Mutant::AST::Sexp do
|
4
|
-
let(:object) do
|
5
|
-
Class.new do
|
6
|
-
include Mutant::AST::Sexp
|
7
|
-
|
8
|
-
public :n_not
|
9
|
-
public :s
|
10
|
-
end.new
|
11
|
-
end
|
12
|
-
|
13
|
-
describe '#n_not' do
|
14
|
-
subject { object.n_not(node) }
|
15
|
-
|
16
|
-
let(:node) { s(:true) }
|
17
|
-
|
18
|
-
it 'returns negated ast' do
|
19
|
-
expect(subject).to eql(s(:send, s(:true), :!))
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe '#s' do
|
24
|
-
subject { object.s(*arguments) }
|
25
|
-
|
26
|
-
context 'with single argument' do
|
27
|
-
let(:arguments) { %i[foo] }
|
28
|
-
|
29
|
-
it { should eql(Parser::AST::Node.new(:foo)) }
|
30
|
-
end
|
31
|
-
|
32
|
-
context 'with single multiple arguments' do
|
33
|
-
let(:arguments) { %i[foo bar baz] }
|
34
|
-
|
35
|
-
it { should eql(Parser::AST::Node.new(:foo, %i[bar baz])) }
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Mutant::AST do
|
4
|
-
let(:object) { described_class }
|
5
|
-
|
6
|
-
describe '.find_last_path' do
|
7
|
-
subject { object.find_last_path(root, &block) }
|
8
|
-
|
9
|
-
let(:root) { s(:root, parent) }
|
10
|
-
let(:child_a) { s(:child_a) }
|
11
|
-
let(:child_b) { s(:child_b) }
|
12
|
-
let(:parent) { s(:parent, child_a, child_b) }
|
13
|
-
|
14
|
-
def path
|
15
|
-
subject.map(&:type)
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'when no node matches' do
|
19
|
-
let(:block) { ->(_) { false } }
|
20
|
-
|
21
|
-
it { should eql([]) }
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'when called without block' do
|
25
|
-
let(:block) { nil }
|
26
|
-
|
27
|
-
it 'raises error' do
|
28
|
-
expect { subject }.to raise_error(ArgumentError, 'block expected')
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
context 'on non Parser::AST::Node child' do
|
33
|
-
let(:block) { ->(node) { fail if node.equal?(child_a) } }
|
34
|
-
let(:child_a) { AST::Node.new(:foo) }
|
35
|
-
|
36
|
-
it 'does not yield that node' do
|
37
|
-
expect(path).to eql([])
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
context 'when one node matches' do
|
42
|
-
let(:block) { ->(node) { node.equal?(child_a) } }
|
43
|
-
|
44
|
-
it 'returns the full path' do
|
45
|
-
expect(path).to eql(%i[root parent child_a])
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context 'when two nodes match' do
|
50
|
-
let(:block) { ->(node) { node.equal?(child_a) || node.equal?(child_b) } }
|
51
|
-
|
52
|
-
it 'returns the last full path' do
|
53
|
-
expect(path).to eql(%i[root parent child_b])
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,216 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Mutant::Bootstrap do
|
4
|
-
let(:integration) { instance_double(Mutant::Integration) }
|
5
|
-
let(:integration_name) { instance_double(String) }
|
6
|
-
let(:integration_result) { Mutant::Either::Right.new(integration) }
|
7
|
-
let(:kernel) { instance_double(Object, 'kernel') }
|
8
|
-
let(:load_path) { %w[original] }
|
9
|
-
let(:matcher_config) { Mutant::Matcher::Config::DEFAULT }
|
10
|
-
let(:object_space) { class_double(ObjectSpace) }
|
11
|
-
let(:object_space_modules) { [] }
|
12
|
-
let(:warnings) { instance_double(Mutant::Warnings) }
|
13
|
-
|
14
|
-
let(:world) do
|
15
|
-
instance_double(
|
16
|
-
Mutant::World,
|
17
|
-
kernel: kernel,
|
18
|
-
load_path: load_path,
|
19
|
-
object_space: object_space,
|
20
|
-
pathname: Pathname,
|
21
|
-
warnings: warnings
|
22
|
-
)
|
23
|
-
end
|
24
|
-
|
25
|
-
let(:config) do
|
26
|
-
Mutant::Config::DEFAULT.with(
|
27
|
-
includes: [],
|
28
|
-
integration: integration,
|
29
|
-
jobs: 1,
|
30
|
-
matcher: matcher_config,
|
31
|
-
reporter: instance_double(Mutant::Reporter),
|
32
|
-
requires: []
|
33
|
-
)
|
34
|
-
end
|
35
|
-
|
36
|
-
let(:expected_env) do
|
37
|
-
env_with_scopes.with(
|
38
|
-
integration: integration,
|
39
|
-
selector: Mutant::Selector::Expression.new(integration)
|
40
|
-
)
|
41
|
-
end
|
42
|
-
|
43
|
-
let(:env_empty) do
|
44
|
-
Mutant::Env.empty(world, config)
|
45
|
-
end
|
46
|
-
|
47
|
-
let(:env_with_scopes) { env_empty }
|
48
|
-
|
49
|
-
shared_examples 'expected warning' do
|
50
|
-
let(:warns) { [] }
|
51
|
-
|
52
|
-
before do
|
53
|
-
allow(config.reporter).to receive(:warn, &warns.method(:<<))
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'warns with expected warning' do
|
57
|
-
expect { apply }.to change(warns, :to_a).from([]).to([expected_warning])
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
shared_examples_for 'bootstrap call' do
|
62
|
-
it 'returns expected env' do
|
63
|
-
expect(apply).to eql(Mutant::Either::Right.new(expected_env))
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'performs IO in expected sequence' do
|
67
|
-
apply
|
68
|
-
|
69
|
-
expect(object_space)
|
70
|
-
.to have_received(:each_object)
|
71
|
-
.ordered
|
72
|
-
|
73
|
-
expect(Mutant::Integration)
|
74
|
-
.to have_received(:setup)
|
75
|
-
.with(env_with_scopes)
|
76
|
-
.ordered
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
before do
|
81
|
-
allow(Mutant::Integration).to receive_messages(setup: integration_result)
|
82
|
-
|
83
|
-
allow(object_space).to receive(:each_object) do |argument|
|
84
|
-
expect(argument).to be(Module)
|
85
|
-
object_space_modules.each
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
describe '.apply' do
|
90
|
-
def apply
|
91
|
-
described_class.apply(world, config)
|
92
|
-
end
|
93
|
-
|
94
|
-
context 'when Module#name calls result in exceptions' do
|
95
|
-
let(:object_space_modules) { [invalid_class] }
|
96
|
-
|
97
|
-
let(:expected_warning) do
|
98
|
-
"Object#name from: #{invalid_class} raised an error: " \
|
99
|
-
"RuntimeError. #{Mutant::Env::SEMANTICS_MESSAGE}"
|
100
|
-
end
|
101
|
-
|
102
|
-
# Not really a class, but does not leak a "wrong" class
|
103
|
-
# into later specs.
|
104
|
-
let(:invalid_class) do
|
105
|
-
Object.new.tap do |object|
|
106
|
-
def object.name
|
107
|
-
fail
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
include_examples 'expected warning'
|
113
|
-
include_examples 'bootstrap call'
|
114
|
-
end
|
115
|
-
|
116
|
-
context 'when Module#name calls return nil' do
|
117
|
-
let(:anonymous_class) { Class.new }
|
118
|
-
let(:object_space_modules) { [anonymous_class] }
|
119
|
-
|
120
|
-
include_examples 'bootstrap call'
|
121
|
-
end
|
122
|
-
|
123
|
-
context 'when requires are configured' do
|
124
|
-
let(:config) { super().with(requires: %w[foo bar]) }
|
125
|
-
let(:requires) { [] }
|
126
|
-
|
127
|
-
before do
|
128
|
-
allow(kernel).to receive(:require, &requires.method(:<<))
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'executes requires' do
|
132
|
-
expect { apply }.to change(requires, :to_a).from([]).to(%w[foo bar])
|
133
|
-
end
|
134
|
-
|
135
|
-
include_examples 'bootstrap call'
|
136
|
-
end
|
137
|
-
|
138
|
-
context 'when includes are configured' do
|
139
|
-
let(:config) { super().with(includes: %w[foo bar]) }
|
140
|
-
|
141
|
-
it 'appends to load path' do
|
142
|
-
expect { apply }
|
143
|
-
.to change(load_path, :to_a)
|
144
|
-
.from(load_path.dup)
|
145
|
-
.to(%w[original foo bar])
|
146
|
-
end
|
147
|
-
|
148
|
-
include_examples 'bootstrap call'
|
149
|
-
end
|
150
|
-
|
151
|
-
context 'when Module#name does not return a String or nil' do
|
152
|
-
let(:object_space_modules) { [invalid_class] }
|
153
|
-
|
154
|
-
let(:invalid_class) do
|
155
|
-
# intentionally an object to not actually pollute object space
|
156
|
-
Object.new.tap do |object|
|
157
|
-
def object.name
|
158
|
-
Object
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
let(:expected_warning) do
|
164
|
-
"Object#name from: #{invalid_class} " \
|
165
|
-
"returned Object. #{Mutant::Env::SEMANTICS_MESSAGE}"
|
166
|
-
end
|
167
|
-
|
168
|
-
include_examples 'expected warning'
|
169
|
-
include_examples 'bootstrap call'
|
170
|
-
end
|
171
|
-
|
172
|
-
context 'when object name cannot be parsed as expression' do
|
173
|
-
let(:object_space_modules) { [invalid_class] }
|
174
|
-
|
175
|
-
let(:invalid_class) do
|
176
|
-
# intentionally an object to not actually pollute object space
|
177
|
-
Object.new.tap do |object|
|
178
|
-
def object.name
|
179
|
-
'invalid expression'
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
include_examples 'bootstrap call'
|
185
|
-
end
|
186
|
-
|
187
|
-
context 'when scope matches expression' do
|
188
|
-
let(:object_space_modules) { [TestApp::Literal, TestApp::Empty] }
|
189
|
-
let(:match_expressions) { object_space_modules.map(&:name).map(&method(:parse_expression)) }
|
190
|
-
|
191
|
-
let(:matcher_config) do
|
192
|
-
super().with(match_expressions: match_expressions)
|
193
|
-
end
|
194
|
-
|
195
|
-
let(:env_with_scopes) do
|
196
|
-
env_empty.with(
|
197
|
-
matchable_scopes: [
|
198
|
-
Mutant::Scope.new(TestApp::Empty, match_expressions.last),
|
199
|
-
Mutant::Scope.new(TestApp::Literal, match_expressions.first)
|
200
|
-
]
|
201
|
-
)
|
202
|
-
end
|
203
|
-
|
204
|
-
let(:expected_env) do
|
205
|
-
subjects = Mutant::Matcher::Scope.new(TestApp::Literal).call(env_empty)
|
206
|
-
|
207
|
-
super().with(
|
208
|
-
mutations: subjects.flat_map(&:mutations),
|
209
|
-
subjects: subjects
|
210
|
-
)
|
211
|
-
end
|
212
|
-
|
213
|
-
include_examples 'bootstrap call'
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|