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
data/spec/support/ruby_vm.rb
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MutantSpec
|
4
|
-
# Not a real VM, just kidding. It connects the require / eval triggers
|
5
|
-
# require semantics Zombifier relies on in a way we can avoid having to
|
6
|
-
# mock around everywhere to test every detail.
|
7
|
-
class RubyVM
|
8
|
-
include Concord::Public.new(:expected_events)
|
9
|
-
|
10
|
-
# An event being observed by the VM handlers
|
11
|
-
class EventObservation
|
12
|
-
include Concord::Public.new(:type, :payload)
|
13
|
-
end # EventObservation
|
14
|
-
|
15
|
-
# An event being expected, can advance the VM
|
16
|
-
class EventExpectation
|
17
|
-
include AbstractType, Anima.new(
|
18
|
-
:expected_payload,
|
19
|
-
:trigger_requires,
|
20
|
-
:return_value
|
21
|
-
)
|
22
|
-
|
23
|
-
DEFAULTS = IceNine.deep_freeze(trigger_requires: [])
|
24
|
-
|
25
|
-
def initialize(attributes)
|
26
|
-
super(DEFAULTS.merge(attributes))
|
27
|
-
end
|
28
|
-
|
29
|
-
def handle(vm, observation) # rubocop:disable Naming/MethodParameterName
|
30
|
-
unless match?(observation)
|
31
|
-
fail "Unexpected event observation: #{observation.inspect}, expected #{inspect}"
|
32
|
-
end
|
33
|
-
|
34
|
-
trigger_requires.each(&vm.method(:require))
|
35
|
-
|
36
|
-
self
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def match?(observation)
|
42
|
-
observation.type.eql?(self.class) && observation.payload.eql?(expected_payload)
|
43
|
-
end
|
44
|
-
|
45
|
-
# Expectation and advance on require calls
|
46
|
-
class Require < self
|
47
|
-
end # Require
|
48
|
-
|
49
|
-
# Expectation and advance on eval calls
|
50
|
-
class Eval < self
|
51
|
-
end # Eval
|
52
|
-
end # EventExpectation
|
53
|
-
|
54
|
-
# A fake implementation of Kernel#require
|
55
|
-
def require(logical_name)
|
56
|
-
handle_event(EventObservation.new(EventExpectation::Require, logical_name: logical_name))
|
57
|
-
end
|
58
|
-
|
59
|
-
# A fake implementation of Kernel#eval
|
60
|
-
def eval(source, binding, location)
|
61
|
-
handle_event(
|
62
|
-
EventObservation.new(
|
63
|
-
EventExpectation::Eval,
|
64
|
-
binding: binding,
|
65
|
-
source: source,
|
66
|
-
source_location: location
|
67
|
-
)
|
68
|
-
)
|
69
|
-
end
|
70
|
-
|
71
|
-
# Test if VM events where fully processed
|
72
|
-
def done?
|
73
|
-
expected_events.empty?
|
74
|
-
end
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
def handle_event(observation)
|
79
|
-
fail "Unexpected event: #{observation.type} / #{observation.payload}" if expected_events.empty?
|
80
|
-
|
81
|
-
expected_events.slice!(0).handle(self, observation).return_value
|
82
|
-
end
|
83
|
-
end # RubyVM
|
84
|
-
end # MutantSpec
|
@@ -1,169 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# rubocop:disable Metrics/ModuleLength
|
4
|
-
module SharedContext
|
5
|
-
# Prepend an anonymous module with the new `with` method
|
6
|
-
#
|
7
|
-
# Using an anonymous module eliminates warnings where `setup_shared_context`
|
8
|
-
# is used and one of the shared methods is immediately redefined.
|
9
|
-
def with(name, &block)
|
10
|
-
new_definition =
|
11
|
-
Module.new do
|
12
|
-
define_method(name) do
|
13
|
-
super().with(instance_eval(&block))
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
prepend(new_definition)
|
18
|
-
end
|
19
|
-
|
20
|
-
def it_reports(expected_content)
|
21
|
-
it 'writes expected report to output' do
|
22
|
-
described_class.call(output, reportable)
|
23
|
-
output.rewind
|
24
|
-
expect(output.read).to eql(expected_content)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# rubocop:disable Metrics/MethodLength
|
29
|
-
# rubocop:disable Metrics/AbcSize
|
30
|
-
def setup_shared_context
|
31
|
-
let(:mutation_a) { Mutant::Mutation::Evil.new(subject_a, mutation_a_node) }
|
32
|
-
let(:mutation_a_node) { s(:false) }
|
33
|
-
let(:mutation_b) { Mutant::Mutation::Evil.new(subject_a, mutation_b_node) }
|
34
|
-
let(:mutation_b_node) { s(:nil) }
|
35
|
-
let(:mutations) { [mutation_a, mutation_b] }
|
36
|
-
let(:output) { StringIO.new }
|
37
|
-
let(:subject_a_node) { s(:true) }
|
38
|
-
let(:test_a) { instance_double(Mutant::Test, identification: 'test-a') }
|
39
|
-
let(:subjects) { [subject_a] }
|
40
|
-
|
41
|
-
let(:job_a) do
|
42
|
-
Mutant::Parallel::Source::Job.new(
|
43
|
-
index: 0,
|
44
|
-
payload: mutation_a
|
45
|
-
)
|
46
|
-
end
|
47
|
-
|
48
|
-
let(:job_b) do
|
49
|
-
Mutant::Parallel::Source::Job.new(
|
50
|
-
index: 1,
|
51
|
-
payload: mutation_b
|
52
|
-
)
|
53
|
-
end
|
54
|
-
|
55
|
-
let(:env) do
|
56
|
-
instance_double(
|
57
|
-
Mutant::Env,
|
58
|
-
amount_mutations: mutations.length,
|
59
|
-
amount_selected_tests: selections.values.flatten.to_set.length,
|
60
|
-
amount_subjects: subjects.length,
|
61
|
-
amount_total_tests: integration.all_tests.length,
|
62
|
-
config: config,
|
63
|
-
integration: integration,
|
64
|
-
mutations: mutations,
|
65
|
-
selected_tests: [test_a].to_set,
|
66
|
-
selections: selections,
|
67
|
-
subjects: subjects,
|
68
|
-
test_subject_ratio: Rational(1)
|
69
|
-
)
|
70
|
-
end
|
71
|
-
|
72
|
-
let(:selections) do
|
73
|
-
{ subject_a => [test_a] }
|
74
|
-
end
|
75
|
-
|
76
|
-
let(:integration) do
|
77
|
-
instance_double(
|
78
|
-
Mutant::Integration,
|
79
|
-
all_tests: [test_a]
|
80
|
-
)
|
81
|
-
end
|
82
|
-
|
83
|
-
let(:status) do
|
84
|
-
Mutant::Parallel::Status.new(
|
85
|
-
active_jobs: [].to_set,
|
86
|
-
payload: env_result,
|
87
|
-
done: true
|
88
|
-
)
|
89
|
-
end
|
90
|
-
|
91
|
-
let(:config) do
|
92
|
-
Mutant::Config::DEFAULT.with(
|
93
|
-
jobs: 1,
|
94
|
-
reporter: Mutant::Reporter::Null.new
|
95
|
-
)
|
96
|
-
end
|
97
|
-
|
98
|
-
let(:subject_a) do
|
99
|
-
instance_double(
|
100
|
-
Mutant::Subject,
|
101
|
-
node: subject_a_node,
|
102
|
-
source: Unparser.unparse(subject_a_node),
|
103
|
-
identification: 'subject-a'
|
104
|
-
)
|
105
|
-
end
|
106
|
-
|
107
|
-
before do
|
108
|
-
allow(subject_a).to receive(:mutations).and_return([mutation_a, mutation_b])
|
109
|
-
end
|
110
|
-
|
111
|
-
let(:env_result) do
|
112
|
-
Mutant::Result::Env.new(
|
113
|
-
env: env,
|
114
|
-
runtime: 4.0,
|
115
|
-
subject_results: [subject_a_result]
|
116
|
-
)
|
117
|
-
end
|
118
|
-
|
119
|
-
let(:mutation_a_result) do
|
120
|
-
Mutant::Result::Mutation.new(
|
121
|
-
mutation: mutation_a,
|
122
|
-
isolation_result: mutation_a_isolation_result,
|
123
|
-
runtime: 1.0
|
124
|
-
)
|
125
|
-
end
|
126
|
-
|
127
|
-
let(:mutation_b_result) do
|
128
|
-
Mutant::Result::Mutation.new(
|
129
|
-
isolation_result: mutation_b_isolation_result,
|
130
|
-
mutation: mutation_b,
|
131
|
-
runtime: 1.0
|
132
|
-
)
|
133
|
-
end
|
134
|
-
|
135
|
-
let(:mutation_a_isolation_result) do
|
136
|
-
Mutant::Isolation::Result::Success.new(mutation_a_test_result)
|
137
|
-
end
|
138
|
-
|
139
|
-
let(:mutation_a_test_result) do
|
140
|
-
Mutant::Result::Test.new(
|
141
|
-
tests: [test_a],
|
142
|
-
passed: false,
|
143
|
-
runtime: 1.0,
|
144
|
-
output: 'mutation a test result output'
|
145
|
-
)
|
146
|
-
end
|
147
|
-
|
148
|
-
let(:mutation_b_test_result) do
|
149
|
-
Mutant::Result::Test.new(
|
150
|
-
tests: [test_a],
|
151
|
-
passed: false,
|
152
|
-
runtime: 1.0,
|
153
|
-
output: 'mutation b test result output'
|
154
|
-
)
|
155
|
-
end
|
156
|
-
|
157
|
-
let(:mutation_b_isolation_result) do
|
158
|
-
Mutant::Isolation::Result::Success.new(mutation_b_test_result)
|
159
|
-
end
|
160
|
-
|
161
|
-
let(:subject_a_result) do
|
162
|
-
Mutant::Result::Subject.new(
|
163
|
-
subject: subject_a,
|
164
|
-
tests: [test_a],
|
165
|
-
mutation_results: [mutation_a_result, mutation_b_result]
|
166
|
-
)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end # SharedContext
|
data/spec/support/test_app.rb
DELETED
data/spec/support/warnings.yml
DELETED
@@ -1,6 +0,0 @@
|
|
1
|
-
---
|
2
|
-
- "lib/mutant/subject/method/instance.rb:9: warning: undefining `initialize' may cause serious problems"
|
3
|
-
- 'lib/parallel.rb:222: warning: shadowing outer local variable - args'
|
4
|
-
- 'lib/parallel.rb:227: warning: shadowing outer local variable - args'
|
5
|
-
- 'lib/parser/lexer.rb:10836: warning: assigned but unused variable - testEof'
|
6
|
-
- 'lib/regexp_parser/scanner.rb:1146: warning: assigned but unused variable - testEof'
|
data/spec/support/xspec.rb
DELETED
@@ -1,183 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module XSpec
|
4
|
-
class MessageReaction
|
5
|
-
include Concord.new(:event_list)
|
6
|
-
|
7
|
-
TERMINATE_EVENTS = IceNine.deep_freeze(%i[return exception].to_set)
|
8
|
-
VALID_EVENTS = IceNine.deep_freeze(%i[return execute exception yields].to_set)
|
9
|
-
|
10
|
-
private_constant(*constants(false))
|
11
|
-
|
12
|
-
def call(observation)
|
13
|
-
event_list.map do |event, object|
|
14
|
-
__send__(event, observation, object)
|
15
|
-
end.last
|
16
|
-
end
|
17
|
-
|
18
|
-
# Parse events into reaction
|
19
|
-
#
|
20
|
-
# @param [Array{Symbol,Object}, Hash{Symbol,Object}]
|
21
|
-
#
|
22
|
-
# @return [MessageReaction]
|
23
|
-
def self.parse(events)
|
24
|
-
event_list = events.to_a
|
25
|
-
assert_valid(event_list)
|
26
|
-
new(event_list)
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def return(_event, value)
|
32
|
-
value
|
33
|
-
end
|
34
|
-
|
35
|
-
def execute(_event, block)
|
36
|
-
block.call
|
37
|
-
end
|
38
|
-
|
39
|
-
def exception(_event, exception)
|
40
|
-
fail exception
|
41
|
-
end
|
42
|
-
|
43
|
-
def yields(observation, yields)
|
44
|
-
block = observation.block or fail 'No block passed where expected'
|
45
|
-
|
46
|
-
validate_block_arity(observation, yields)
|
47
|
-
|
48
|
-
block.call(*yields)
|
49
|
-
end
|
50
|
-
|
51
|
-
def validate_block_arity(observation, yields)
|
52
|
-
expected, observed = yields.length, observation.block.arity
|
53
|
-
|
54
|
-
# block allows anything we can skip the check
|
55
|
-
return if observed.equal?(-1)
|
56
|
-
fail 'Optargs currently not supported' if observed < -1
|
57
|
-
block_arity_mismatch(observation, expected, observed) unless expected.equal?(observed)
|
58
|
-
end
|
59
|
-
|
60
|
-
def block_arity_mismatch(observation, expected, observed)
|
61
|
-
fail "block arity mismatch, expected #{expected} observed #{observed}\nobservation:\n#{observation.inspect}"
|
62
|
-
end
|
63
|
-
|
64
|
-
alias_method :yields_return, :yields
|
65
|
-
|
66
|
-
def self.assert_valid(event_list)
|
67
|
-
assert_not_empty(event_list)
|
68
|
-
assert_valid_events(event_list)
|
69
|
-
assert_total(event_list)
|
70
|
-
end
|
71
|
-
private_class_method :assert_valid
|
72
|
-
|
73
|
-
def self.assert_valid_events(event_list)
|
74
|
-
event_list.map(&:first).each do |event|
|
75
|
-
fail "Invalid event: #{event}" unless VALID_EVENTS.include?(event)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
private_class_method :assert_valid_events
|
79
|
-
|
80
|
-
def self.assert_not_empty(event_list)
|
81
|
-
fail 'no events' if event_list.empty?
|
82
|
-
end
|
83
|
-
private_class_method :assert_not_empty
|
84
|
-
|
85
|
-
def self.assert_total(event_list)
|
86
|
-
return unless event_list[0..-2].map(&:first).any?(&TERMINATE_EVENTS.method(:include?))
|
87
|
-
|
88
|
-
fail "Reaction not total: #{event_list}"
|
89
|
-
end
|
90
|
-
private_class_method :assert_total
|
91
|
-
end # MessageReaction
|
92
|
-
|
93
|
-
class MessageExpectation
|
94
|
-
include Anima.new(:receiver, :selector, :arguments, :reaction)
|
95
|
-
|
96
|
-
# rubocop:disable Metrics/ParameterLists
|
97
|
-
def self.parse(receiver:, selector:, arguments: [], reaction: nil)
|
98
|
-
new(
|
99
|
-
receiver: receiver,
|
100
|
-
selector: selector,
|
101
|
-
arguments: arguments,
|
102
|
-
reaction: MessageReaction.parse(reaction || { return: nil })
|
103
|
-
)
|
104
|
-
end
|
105
|
-
|
106
|
-
def call(observation)
|
107
|
-
Verifier.new(self, observation).call
|
108
|
-
end
|
109
|
-
|
110
|
-
class Verifier
|
111
|
-
include Concord.new(:expectation, :observation)
|
112
|
-
|
113
|
-
VERIFIED_ATTRIBUTES = IceNine.deep_freeze(%i[receiver selector arguments])
|
114
|
-
|
115
|
-
def call
|
116
|
-
VERIFIED_ATTRIBUTES.each(&method(:assert_expected_attribute))
|
117
|
-
|
118
|
-
expectation.reaction.call(observation)
|
119
|
-
end
|
120
|
-
|
121
|
-
private
|
122
|
-
|
123
|
-
def assert_expected_attribute(name)
|
124
|
-
error("#{name} mismatch") unless observation.public_send(name).eql?(expectation.public_send(name))
|
125
|
-
end
|
126
|
-
|
127
|
-
def error(message)
|
128
|
-
fail "#{message},\n observation:\n #{observation.inspect}\n expectation:\n #{expectation.inspect}"
|
129
|
-
end
|
130
|
-
|
131
|
-
def trigger_exception
|
132
|
-
exception = expectation.exception
|
133
|
-
fail exception if exception
|
134
|
-
end
|
135
|
-
|
136
|
-
end # Verifier
|
137
|
-
end # MessageExpectation
|
138
|
-
|
139
|
-
class MessageObservation
|
140
|
-
include Anima.new(:receiver, :selector, :arguments, :block)
|
141
|
-
end # MessageObservation
|
142
|
-
|
143
|
-
class ExpectationVerifier
|
144
|
-
include Concord.new(:expectations)
|
145
|
-
|
146
|
-
def call(observation)
|
147
|
-
expectation = expectations.shift or fail "No expected message but observed #{observation.inspect}"
|
148
|
-
expectation.call(observation)
|
149
|
-
end
|
150
|
-
|
151
|
-
def assert_done
|
152
|
-
expectations.empty? or fail "unconsumed expectations:\n#{expectations.map(&:inspect).join("\n")}"
|
153
|
-
end
|
154
|
-
|
155
|
-
# rubocop:disable Metrics/MethodLength
|
156
|
-
def self.verify(rspec_context, expectations)
|
157
|
-
verifier = new(expectations)
|
158
|
-
|
159
|
-
hooks = expectations
|
160
|
-
.map { |expectation| [expectation.receiver, expectation.selector] }
|
161
|
-
.to_set
|
162
|
-
|
163
|
-
hooks.each do |receiver, selector|
|
164
|
-
rspec_context.instance_eval do
|
165
|
-
allow(receiver).to receive(selector) do |*arguments, &block|
|
166
|
-
verifier.call(
|
167
|
-
MessageObservation.new(
|
168
|
-
receiver: receiver,
|
169
|
-
selector: selector,
|
170
|
-
arguments: arguments,
|
171
|
-
block: block
|
172
|
-
)
|
173
|
-
)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
yield
|
179
|
-
|
180
|
-
verifier.assert_done
|
181
|
-
end
|
182
|
-
end # ExpectationVerifier
|
183
|
-
end # XSpec
|