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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e92dbf6cbb84cf8d3d5354fc5994cb1ad7cb1fb1364b1927aa89abeedcd0cef
|
4
|
+
data.tar.gz: 5c49178b6766424d6ded707a100ebad86cf9c5403a53b2c2c750baf69b4d636f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e786a6ed55abf722515f3b4b9c08200dac35557e48c27430ae5683471ededf67d1fcb17ff4e5f57f1881765d10f3a8b00ef2993f163a1cceb93531d4b75a37e3
|
7
|
+
data.tar.gz: 2a5840a2ecc0ca7c9c6156e8c4596b21808aaf8418ecf134fff9ada56a6c20e94b5ece60a0ebf0b321f1ed51ff0e5c92d26069bcb9473f61276973c46780eb5d
|
data/lib/mutant.rb
CHANGED
@@ -90,8 +90,7 @@ require 'mutant/mutator/node/arguments'
|
|
90
90
|
require 'mutant/mutator/node/begin'
|
91
91
|
require 'mutant/mutator/node/binary'
|
92
92
|
require 'mutant/mutator/node/const'
|
93
|
-
require 'mutant/mutator/node/
|
94
|
-
require 'mutant/mutator/node/dsym'
|
93
|
+
require 'mutant/mutator/node/dynamic_literal'
|
95
94
|
require 'mutant/mutator/node/kwbegin'
|
96
95
|
require 'mutant/mutator/node/named_value/access'
|
97
96
|
require 'mutant/mutator/node/named_value/constant_assignment'
|
@@ -120,6 +119,7 @@ require 'mutant/mutator/node/nthref'
|
|
120
119
|
require 'mutant/mutator/node/masgn'
|
121
120
|
require 'mutant/mutator/node/return'
|
122
121
|
require 'mutant/mutator/node/block'
|
122
|
+
require 'mutant/mutator/node/block_pass'
|
123
123
|
require 'mutant/mutator/node/if'
|
124
124
|
require 'mutant/mutator/node/case'
|
125
125
|
require 'mutant/mutator/node/splat'
|
@@ -165,8 +165,6 @@ require 'mutant/selector/expression'
|
|
165
165
|
require 'mutant/selector/null'
|
166
166
|
require 'mutant/config'
|
167
167
|
require 'mutant/cli'
|
168
|
-
require 'mutant/color'
|
169
|
-
require 'mutant/diff'
|
170
168
|
require 'mutant/runner'
|
171
169
|
require 'mutant/runner/sink'
|
172
170
|
require 'mutant/result'
|
data/lib/mutant/bootstrap.rb
CHANGED
@@ -36,7 +36,7 @@ module Mutant
|
|
36
36
|
.tap(&method(:infect))
|
37
37
|
.with(matchable_scopes: matchable_scopes(world, config))
|
38
38
|
|
39
|
-
subjects = Matcher.from_config(env.config.matcher).call(env)
|
39
|
+
subjects = start_subject(env, Matcher.from_config(env.config.matcher).call(env))
|
40
40
|
|
41
41
|
Integration.setup(env).fmap do |integration|
|
42
42
|
env.with(
|
@@ -49,6 +49,19 @@ module Mutant
|
|
49
49
|
end
|
50
50
|
# rubocop:enable Metrics/MethodLength
|
51
51
|
|
52
|
+
def self.start_subject(env, subjects)
|
53
|
+
start_expressions = env.config.matcher.start_expressions
|
54
|
+
|
55
|
+
return subjects if start_expressions.empty?
|
56
|
+
|
57
|
+
subjects.drop_while do |subject|
|
58
|
+
start_expressions.none? do |expression|
|
59
|
+
expression.prefix?(subject.expression)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
private_class_method :start_subject
|
64
|
+
|
52
65
|
def self.infect(env)
|
53
66
|
config, world = env.config, env.world
|
54
67
|
|
data/lib/mutant/cli.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module Mutant
|
4
4
|
# Commandline parser / runner
|
5
|
+
#
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
5
7
|
class CLI
|
6
8
|
include Concord.new(:world, :config)
|
7
9
|
|
@@ -126,6 +128,9 @@ module Mutant
|
|
126
128
|
opts.on('--ignore-subject EXPRESSION', 'Ignore subjects that match EXPRESSION as prefix') do |pattern|
|
127
129
|
add_matcher(:ignore_expressions, config.expression_parser.apply(pattern).from_right)
|
128
130
|
end
|
131
|
+
opts.on('--start-subject EXPRESSION', 'Start mutation testing at a specific subject') do |pattern|
|
132
|
+
add_matcher(:start_expressions, config.expression_parser.apply(pattern).from_right)
|
133
|
+
end
|
129
134
|
opts.on('--since REVISION', 'Only select subjects touched since REVISION') do |revision|
|
130
135
|
add_matcher(
|
131
136
|
:subject_filters,
|
@@ -165,4 +170,5 @@ module Mutant
|
|
165
170
|
with(matcher: config.matcher.add(attribute, value))
|
166
171
|
end
|
167
172
|
end # CLI
|
173
|
+
# rubocop:enable Metrics/ClassLength
|
168
174
|
end # Mutant
|
data/lib/mutant/isolation.rb
CHANGED
@@ -10,12 +10,12 @@ module Mutant
|
|
10
10
|
|
11
11
|
ATTRIBUTES = %i[block log_pipe result_pipe world].freeze
|
12
12
|
|
13
|
-
#
|
13
|
+
# Unsuccessful result as child exited nonzero
|
14
14
|
class ChildError < Result
|
15
15
|
include Concord::Public.new(:value, :log)
|
16
16
|
end # ChildError
|
17
17
|
|
18
|
-
#
|
18
|
+
# Unsuccessful result as fork failed
|
19
19
|
class ForkError < Result
|
20
20
|
include Equalizer.new
|
21
21
|
end # ForkError
|
@@ -7,6 +7,7 @@ module Mutant
|
|
7
7
|
include Adamantium, Anima.new(
|
8
8
|
:ignore_expressions,
|
9
9
|
:match_expressions,
|
10
|
+
:start_expressions,
|
10
11
|
:subject_filters
|
11
12
|
)
|
12
13
|
|
@@ -18,6 +19,7 @@ module Mutant
|
|
18
19
|
PRESENTATIONS = IceNine.deep_freeze(
|
19
20
|
ignore_expressions: :syntax,
|
20
21
|
match_expressions: :syntax,
|
22
|
+
start_expressions: :syntax,
|
21
23
|
subject_filters: :inspect
|
22
24
|
)
|
23
25
|
private_constant(*constants(false))
|
data/lib/mutant/meta/example.rb
CHANGED
@@ -3,7 +3,19 @@
|
|
3
3
|
module Mutant
|
4
4
|
module Meta
|
5
5
|
class Example
|
6
|
-
include Adamantium
|
6
|
+
include Adamantium
|
7
|
+
include Anima.new(
|
8
|
+
:expected,
|
9
|
+
:file,
|
10
|
+
:lvars,
|
11
|
+
:node,
|
12
|
+
:original_source,
|
13
|
+
:types
|
14
|
+
)
|
15
|
+
|
16
|
+
class Expected
|
17
|
+
include Anima.new(:original_source, :node)
|
18
|
+
end
|
7
19
|
|
8
20
|
# Verification instance for example
|
9
21
|
#
|
@@ -13,13 +25,13 @@ module Mutant
|
|
13
25
|
end
|
14
26
|
memoize :verification
|
15
27
|
|
16
|
-
#
|
28
|
+
# Original source as generated by unparser
|
17
29
|
#
|
18
30
|
# @return [String]
|
19
|
-
def
|
31
|
+
def original_source_generated
|
20
32
|
Unparser.unparse(node)
|
21
33
|
end
|
22
|
-
memoize :
|
34
|
+
memoize :original_source_generated
|
23
35
|
|
24
36
|
# Generated mutations on example source
|
25
37
|
#
|
@@ -25,10 +25,11 @@ module Mutant
|
|
25
25
|
#
|
26
26
|
# @return [undefined]
|
27
27
|
def initialize(file, types)
|
28
|
+
@expected = []
|
28
29
|
@file = file
|
30
|
+
@lvars = []
|
31
|
+
@source = nil
|
29
32
|
@types = types
|
30
|
-
@node = nil
|
31
|
-
@expected = []
|
32
33
|
end
|
33
34
|
|
34
35
|
# Example captured by DSL
|
@@ -38,28 +39,41 @@ module Mutant
|
|
38
39
|
# @raise [RuntimeError]
|
39
40
|
# in case example cannot be build
|
40
41
|
def example
|
41
|
-
fail 'source not defined' unless @
|
42
|
+
fail 'source not defined' unless @source
|
42
43
|
Example.new(
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
expected: @expected,
|
45
|
+
file: @file,
|
46
|
+
lvars: @lvars,
|
47
|
+
node: @node,
|
48
|
+
original_source: @source,
|
49
|
+
types: @types
|
47
50
|
)
|
48
51
|
end
|
49
52
|
|
53
|
+
# Declare a local variable
|
54
|
+
#
|
55
|
+
# @param [Symbol]
|
56
|
+
def declare_lvar(name)
|
57
|
+
@lvars << name
|
58
|
+
end
|
59
|
+
|
50
60
|
private
|
51
61
|
|
52
62
|
def source(input)
|
53
|
-
fail 'source already defined' if @
|
54
|
-
|
63
|
+
fail 'source already defined' if @source
|
64
|
+
|
65
|
+
@source = input
|
66
|
+
@node = node(input)
|
55
67
|
end
|
56
68
|
|
57
69
|
def mutation(input)
|
58
|
-
|
59
|
-
|
70
|
+
expected = Expected.new(original_source: input, node: node(input))
|
71
|
+
|
72
|
+
if @expected.include?(expected)
|
60
73
|
fail "Mutation for input: #{input.inspect} is already expected"
|
61
74
|
end
|
62
|
-
|
75
|
+
|
76
|
+
@expected << expected
|
63
77
|
end
|
64
78
|
|
65
79
|
def singleton_mutations
|
@@ -70,14 +84,17 @@ module Mutant
|
|
70
84
|
def node(input)
|
71
85
|
case input
|
72
86
|
when String
|
73
|
-
|
74
|
-
when ::Parser::AST::Node
|
75
|
-
input
|
87
|
+
parser.parse(Unparser.buffer(input))
|
76
88
|
else
|
77
|
-
fail "
|
89
|
+
fail "Unsupported input: #{input.inspect}"
|
78
90
|
end
|
79
91
|
end
|
80
92
|
|
93
|
+
def parser
|
94
|
+
Unparser.parser.tap do |parser|
|
95
|
+
@lvars.each(&parser.static_env.public_method(:declare))
|
96
|
+
end
|
97
|
+
end
|
81
98
|
end # DSL
|
82
99
|
end # Example
|
83
100
|
end # Meta
|
@@ -11,54 +11,96 @@ module Mutant
|
|
11
11
|
#
|
12
12
|
# @return [Boolean]
|
13
13
|
def success?
|
14
|
-
[
|
14
|
+
[
|
15
|
+
original_verification,
|
16
|
+
invalid,
|
17
|
+
missing,
|
18
|
+
no_diffs,
|
19
|
+
unexpected
|
20
|
+
].all?(&:empty?)
|
15
21
|
end
|
16
22
|
memoize :success?
|
17
23
|
|
18
|
-
# Error report
|
19
|
-
#
|
20
|
-
# @return [String]
|
21
24
|
def error_report
|
22
|
-
|
23
|
-
|
24
|
-
YAML.dump(
|
25
|
-
'file' => example.file,
|
26
|
-
'original_ast' => example.node.inspect,
|
27
|
-
'original_source' => example.source,
|
28
|
-
'missing' => format_mutations(missing),
|
29
|
-
'unexpected' => format_mutations(unexpected),
|
30
|
-
'invalid_syntax' => format_mutations(invalid_syntax),
|
31
|
-
'no_diff' => no_diff_report
|
32
|
-
)
|
25
|
+
reports.join("\n")
|
33
26
|
end
|
34
|
-
memoize :error_report
|
35
27
|
|
36
28
|
private
|
37
29
|
|
30
|
+
def reports
|
31
|
+
reports = [example.file]
|
32
|
+
reports.concat(original)
|
33
|
+
reports.concat(original_verification)
|
34
|
+
reports.concat(make_report('Missing mutations:', missing))
|
35
|
+
reports.concat(make_report('Unexpected mutations:', unexpected))
|
36
|
+
reports.concat(make_report('No-Diff mutations:', no_diffs))
|
37
|
+
reports.concat(invalid)
|
38
|
+
end
|
39
|
+
|
40
|
+
def make_report(label, mutations)
|
41
|
+
if mutations.any?
|
42
|
+
[label, mutations.map(&method(:report_mutation))]
|
43
|
+
else
|
44
|
+
[]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def report_mutation(mutation)
|
49
|
+
[
|
50
|
+
mutation.node.inspect,
|
51
|
+
mutation.source
|
52
|
+
]
|
53
|
+
end
|
54
|
+
|
55
|
+
def original
|
56
|
+
[
|
57
|
+
'Original:',
|
58
|
+
example.node,
|
59
|
+
example.original_source
|
60
|
+
]
|
61
|
+
end
|
62
|
+
|
63
|
+
def original_verification
|
64
|
+
validation = Unparser::Validation.from_string(example.original_source)
|
65
|
+
if validation.success?
|
66
|
+
[]
|
67
|
+
else
|
68
|
+
[
|
69
|
+
prefix('[original]', validation.report)
|
70
|
+
]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def prefix(prefix, string)
|
75
|
+
string.each_line.map do |line|
|
76
|
+
"#{prefix} #{line}"
|
77
|
+
end.join
|
78
|
+
end
|
79
|
+
|
80
|
+
def invalid
|
81
|
+
mutations.each_with_object([]) do |mutation, aggregate|
|
82
|
+
validation = Unparser::Validation.from_node(mutation.node)
|
83
|
+
aggregate << prefix('[invalid-mutation]', validation.report) unless validation.success?
|
84
|
+
end
|
85
|
+
end
|
86
|
+
memoize :invalid
|
87
|
+
|
38
88
|
def unexpected
|
39
89
|
mutations.reject do |mutation|
|
40
|
-
example.expected.
|
90
|
+
example.expected.any? { |expected| expected.node.eql?(mutation.node) }
|
41
91
|
end
|
42
92
|
end
|
43
93
|
memoize :unexpected
|
44
94
|
|
45
95
|
def missing
|
46
|
-
(example.expected - mutations.map(&:node)).map do |node|
|
47
|
-
Mutation::Evil.new(
|
96
|
+
(example.expected.map(&:node) - mutations.map(&:node)).map do |node|
|
97
|
+
Mutation::Evil.new(nil, node)
|
48
98
|
end
|
49
99
|
end
|
50
100
|
memoize :missing
|
51
101
|
|
52
|
-
def invalid_syntax
|
53
|
-
mutations.reject do |mutation|
|
54
|
-
::Parser::CurrentRuby.parse(mutation.source)
|
55
|
-
rescue ::Parser::SyntaxError # rubocop:disable Lint/SuppressedException
|
56
|
-
end
|
57
|
-
end
|
58
|
-
memoize :invalid_syntax
|
59
|
-
|
60
102
|
def no_diffs
|
61
|
-
mutations.select { |mutation| mutation.source.eql?(example.
|
103
|
+
mutations.select { |mutation| mutation.source.eql?(example.original_source_generated) }
|
62
104
|
end
|
63
105
|
memoize :no_diffs
|
64
106
|
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest'
|
4
|
+
|
5
|
+
module Mutant
|
6
|
+
module Minitest
|
7
|
+
module Coverage
|
8
|
+
# Setup coverage declaration for current class
|
9
|
+
#
|
10
|
+
# @param [String]
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
#
|
14
|
+
# class MyTest < MiniTest::Test
|
15
|
+
# cover 'MyCode*'
|
16
|
+
#
|
17
|
+
# def test_some_stuff
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# @api public
|
22
|
+
def cover(expression)
|
23
|
+
if defined?(@cover_expression)
|
24
|
+
fail "#{self} already declares to cover: #{@cover_expression.inspect}"
|
25
|
+
end
|
26
|
+
|
27
|
+
@cover_expression = expression
|
28
|
+
end
|
29
|
+
|
30
|
+
# Effective coverage expression
|
31
|
+
#
|
32
|
+
# @return [String, nil]
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
def resolve_cover_expression
|
36
|
+
return @cover_expression if defined?(@cover_expression)
|
37
|
+
|
38
|
+
try_superclass_cover_expression
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def try_superclass_cover_expression
|
44
|
+
return if superclass.equal?(::Minitest::Runnable)
|
45
|
+
|
46
|
+
superclass.resolve_cover_expression
|
47
|
+
end
|
48
|
+
|
49
|
+
end # Coverage
|
50
|
+
end # Minitest
|
51
|
+
end # Mutant
|
52
|
+
|
53
|
+
Minitest::Test.extend(Mutant::Minitest::Coverage)
|