mutant 0.9.8 → 0.9.13
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 +5 -2
- data/lib/mutant/ast.rb +0 -9
- data/lib/mutant/ast/find_metaclass_containing.rb +48 -0
- data/lib/mutant/ast/meta/send.rb +0 -6
- data/lib/mutant/bootstrap.rb +14 -37
- data/lib/mutant/cli.rb +11 -49
- data/lib/mutant/config.rb +0 -8
- data/lib/mutant/context.rb +0 -3
- data/lib/mutant/env.rb +0 -6
- data/lib/mutant/expression/method.rb +6 -6
- data/lib/mutant/expression/methods.rb +6 -6
- data/lib/mutant/expression/parser.rb +0 -6
- data/lib/mutant/integration.rb +0 -18
- data/lib/mutant/isolation.rb +1 -1
- data/lib/mutant/isolation/fork.rb +2 -24
- data/lib/mutant/isolation/none.rb +1 -1
- data/lib/mutant/license.rb +11 -0
- data/lib/mutant/matcher.rb +0 -14
- data/lib/mutant/matcher/config.rb +2 -11
- data/lib/mutant/matcher/method.rb +0 -31
- data/lib/mutant/matcher/method/instance.rb +0 -8
- data/lib/mutant/matcher/method/metaclass.rb +86 -0
- data/lib/mutant/matcher/method/singleton.rb +0 -25
- data/lib/mutant/matcher/methods.rb +17 -28
- data/lib/mutant/matcher/namespace.rb +0 -10
- data/lib/mutant/matcher/scope.rb +2 -4
- data/lib/mutant/meta/example/dsl.rb +0 -21
- data/lib/mutant/meta/example/verification.rb +0 -20
- data/lib/mutant/minitest/coverage.rb +53 -0
- data/lib/mutant/mutation.rb +0 -3
- data/lib/mutant/mutator.rb +1 -29
- data/lib/mutant/mutator/node.rb +1 -66
- data/lib/mutant/mutator/node/and_asgn.rb +0 -3
- data/lib/mutant/mutator/node/argument.rb +0 -15
- data/lib/mutant/mutator/node/arguments.rb +0 -20
- data/lib/mutant/mutator/node/begin.rb +0 -3
- data/lib/mutant/mutator/node/binary.rb +0 -23
- data/lib/mutant/mutator/node/block.rb +0 -15
- data/lib/mutant/mutator/node/block_pass.rb +29 -0
- data/lib/mutant/mutator/node/break.rb +0 -3
- data/lib/mutant/mutator/node/case.rb +0 -9
- data/lib/mutant/mutator/node/class.rb +0 -3
- data/lib/mutant/mutator/node/conditional_loop.rb +0 -3
- data/lib/mutant/mutator/node/const.rb +0 -3
- data/lib/mutant/mutator/node/define.rb +0 -11
- data/lib/mutant/mutator/node/defined.rb +0 -3
- data/lib/mutant/mutator/node/dstr.rb +0 -3
- data/lib/mutant/mutator/node/dsym.rb +0 -3
- data/lib/mutant/mutator/node/generic.rb +0 -3
- data/lib/mutant/mutator/node/if.rb +0 -12
- data/lib/mutant/mutator/node/index.rb +0 -27
- data/lib/mutant/mutator/node/kwbegin.rb +0 -3
- data/lib/mutant/mutator/node/literal.rb +0 -3
- data/lib/mutant/mutator/node/literal/array.rb +0 -6
- data/lib/mutant/mutator/node/literal/boolean.rb +0 -4
- data/lib/mutant/mutator/node/literal/float.rb +0 -9
- data/lib/mutant/mutator/node/literal/hash.rb +0 -9
- data/lib/mutant/mutator/node/literal/integer.rb +0 -9
- data/lib/mutant/mutator/node/literal/nil.rb +0 -3
- data/lib/mutant/mutator/node/literal/range.rb +4 -7
- data/lib/mutant/mutator/node/literal/regex.rb +0 -6
- data/lib/mutant/mutator/node/literal/string.rb +0 -3
- data/lib/mutant/mutator/node/literal/symbol.rb +0 -3
- data/lib/mutant/mutator/node/masgn.rb +0 -3
- data/lib/mutant/mutator/node/match_current_line.rb +0 -3
- data/lib/mutant/mutator/node/mlhs.rb +0 -3
- data/lib/mutant/mutator/node/named_value/access.rb +2 -14
- data/lib/mutant/mutator/node/named_value/constant_assignment.rb +0 -9
- data/lib/mutant/mutator/node/named_value/variable_assignment.rb +0 -6
- data/lib/mutant/mutator/node/next.rb +0 -3
- data/lib/mutant/mutator/node/noop.rb +1 -4
- data/lib/mutant/mutator/node/nthref.rb +0 -3
- data/lib/mutant/mutator/node/op_asgn.rb +0 -3
- data/lib/mutant/mutator/node/or_asgn.rb +0 -3
- data/lib/mutant/mutator/node/procarg_zero.rb +0 -3
- data/lib/mutant/mutator/node/regopt.rb +0 -6
- data/lib/mutant/mutator/node/resbody.rb +0 -6
- data/lib/mutant/mutator/node/rescue.rb +2 -19
- data/lib/mutant/mutator/node/return.rb +0 -3
- data/lib/mutant/mutator/node/sclass.rb +20 -0
- data/lib/mutant/mutator/node/send.rb +26 -61
- data/lib/mutant/mutator/node/send/attribute_assignment.rb +0 -9
- data/lib/mutant/mutator/node/send/binary.rb +0 -11
- data/lib/mutant/mutator/node/send/conditional.rb +0 -3
- data/lib/mutant/mutator/node/splat.rb +0 -3
- data/lib/mutant/mutator/node/super.rb +0 -3
- data/lib/mutant/mutator/node/when.rb +0 -19
- data/lib/mutant/mutator/node/yield.rb +0 -3
- data/lib/mutant/mutator/node/zsuper.rb +0 -3
- data/lib/mutant/mutator/util/array.rb +0 -6
- data/lib/mutant/mutator/util/symbol.rb +0 -3
- data/lib/mutant/parallel.rb +0 -13
- data/lib/mutant/parallel/driver.rb +0 -10
- data/lib/mutant/parallel/worker.rb +0 -22
- data/lib/mutant/reporter/cli.rb +0 -5
- data/lib/mutant/reporter/cli/format.rb +0 -9
- data/lib/mutant/reporter/cli/printer.rb +2 -42
- data/lib/mutant/reporter/cli/printer/env_progress.rb +0 -15
- data/lib/mutant/reporter/cli/printer/isolation_result.rb +9 -21
- data/lib/mutant/reporter/cli/printer/mutation_progress_result.rb +0 -5
- data/lib/mutant/reporter/cli/printer/mutation_result.rb +1 -22
- data/lib/mutant/reporter/cli/printer/status_progressive.rb +0 -8
- data/lib/mutant/reporter/cli/printer/subject_progress.rb +0 -9
- data/lib/mutant/repository/diff.rb +1 -13
- data/lib/mutant/repository/diff/ranges.rb +0 -11
- data/lib/mutant/result.rb +0 -3
- data/lib/mutant/runner.rb +0 -18
- data/lib/mutant/runner/sink.rb +0 -5
- data/lib/mutant/subject.rb +0 -8
- data/lib/mutant/subject/method.rb +0 -3
- data/lib/mutant/subject/method/instance.rb +40 -6
- data/lib/mutant/subject/method/metaclass.rb +30 -0
- data/lib/mutant/transform.rb +0 -92
- data/lib/mutant/version.rb +1 -1
- data/lib/mutant/warnings.rb +0 -6
- data/lib/mutant/zombifier.rb +2 -34
- metadata +61 -333
- data/.github/workflows/ci.yml +0 -121
- data/.gitignore +0 -38
- data/.rspec +0 -5
- data/.rubocop.yml +0 -7
- data/Changelog.md +0 -75
- data/Gemfile +0 -7
- data/Gemfile.lock +0 -167
- data/Gemfile.shared +0 -10
- data/README.md +0 -138
- data/Rakefile +0 -5
- data/config/devtools.yml +0 -2
- data/config/reek.yml +0 -138
- 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 -43
- data/lib/mutant/diff.rb +0 -114
- data/meta/and.rb +0 -15
- data/meta/and_asgn.rb +0 -14
- data/meta/array.rb +0 -30
- data/meta/begin.rb +0 -23
- data/meta/block.rb +0 -202
- data/meta/block_pass.rb +0 -8
- data/meta/blockarg.rb +0 -10
- data/meta/break.rb +0 -10
- data/meta/case.rb +0 -223
- data/meta/casgn.rb +0 -28
- 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 -10
- data/meta/date.rb +0 -59
- data/meta/def.rb +0 -203
- data/meta/defined.rb +0 -9
- data/meta/dstr.rb +0 -13
- data/meta/dsym.rb +0 -14
- data/meta/ensure.rb +0 -9
- data/meta/false.rb +0 -8
- data/meta/file.rb +0 -5
- data/meta/float.rb +0 -37
- data/meta/gvar.rb +0 -7
- data/meta/gvasgn.rb +0 -10
- data/meta/hash.rb +0 -24
- data/meta/if.rb +0 -77
- 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 -23
- data/meta/kwarg.rb +0 -10
- data/meta/kwbegin.rb +0 -9
- 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 -25
- data/meta/masgn.rb +0 -7
- data/meta/match_current_line.rb +0 -15
- data/meta/next.rb +0 -11
- data/meta/nil.rb +0 -5
- data/meta/nthref.rb +0 -14
- data/meta/op_assgn.rb +0 -17
- data/meta/or.rb +0 -15
- data/meta/or_asgn.rb +0 -50
- data/meta/range.rb +0 -39
- data/meta/redo.rb +0 -5
- data/meta/regexp.rb +0 -81
- data/meta/regopt.rb +0 -10
- data/meta/rescue.rb +0 -90
- data/meta/return.rb +0 -16
- data/meta/self.rb +0 -7
- data/meta/send.rb +0 -604
- data/meta/str.rb +0 -7
- data/meta/super.rb +0 -27
- data/meta/sym.rb +0 -8
- data/meta/true.rb +0 -8
- data/meta/until.rb +0 -17
- data/meta/while.rb +0 -26
- data/meta/yield.rb +0 -10
- data/mutant-minitest.gemspec +0 -22
- data/mutant-rspec.gemspec +0 -22
- data/mutant.gemspec +0 -41
- 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/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 -61
- 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 -293
- 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/singleton_spec.rb +0 -90
- data/spec/unit/mutant/matcher/methods/instance_spec.rb +0 -54
- data/spec/unit/mutant/matcher/methods/singleton_spec.rb +0 -51
- data/spec/unit/mutant/matcher/namespace_spec.rb +0 -37
- data/spec/unit/mutant/matcher/null_spec.rb +0 -12
- data/spec/unit/mutant/matcher/scope_spec.rb +0 -35
- 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 -52
- 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/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 -109
- data/test_app/lib/test_app/literal.rb +0 -35
- 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
@@ -27,16 +27,10 @@ module Mutant
|
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
# method matcher class
|
31
|
-
#
|
32
|
-
# @return [Class:Matcher::Method]
|
33
30
|
def matcher
|
34
31
|
self.class::MATCHER
|
35
32
|
end
|
36
33
|
|
37
|
-
# Available methods scope
|
38
|
-
#
|
39
|
-
# @return [Enumerable<Method, UnboundMethod>]
|
40
34
|
def methods
|
41
35
|
candidate_names.each_with_object([]) do |name, methods|
|
42
36
|
method = access(name)
|
@@ -45,9 +39,6 @@ module Mutant
|
|
45
39
|
end
|
46
40
|
memoize :methods
|
47
41
|
|
48
|
-
# Candidate method names on target scope
|
49
|
-
#
|
50
|
-
# @return [Enumerable<Symbol>]
|
51
42
|
def candidate_names
|
52
43
|
CANDIDATE_NAMES
|
53
44
|
.map(&candidate_scope.method(:public_send))
|
@@ -55,10 +46,8 @@ module Mutant
|
|
55
46
|
.sort
|
56
47
|
end
|
57
48
|
|
58
|
-
# Candidate scope
|
59
|
-
#
|
60
|
-
# @return [Class, Module]
|
61
49
|
abstract_method :candidate_scope
|
50
|
+
private :candidate_scope
|
62
51
|
|
63
52
|
# Matcher for singleton methods
|
64
53
|
class Singleton < self
|
@@ -66,18 +55,10 @@ module Mutant
|
|
66
55
|
|
67
56
|
private
|
68
57
|
|
69
|
-
# Method object on scope
|
70
|
-
#
|
71
|
-
# @param [Symbol] method_name
|
72
|
-
#
|
73
|
-
# @return [Method]
|
74
58
|
def access(method_name)
|
75
59
|
scope.method(method_name)
|
76
60
|
end
|
77
61
|
|
78
|
-
# Candidate scope
|
79
|
-
#
|
80
|
-
# @return [Class]
|
81
62
|
def candidate_scope
|
82
63
|
scope.singleton_class
|
83
64
|
end
|
@@ -85,24 +66,32 @@ module Mutant
|
|
85
66
|
|
86
67
|
end # Singleton
|
87
68
|
|
69
|
+
# Matcher for metaclass methods
|
70
|
+
class Metaclass < self
|
71
|
+
MATCHER = Matcher::Method::Metaclass
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def access(method_name)
|
76
|
+
scope.method(method_name)
|
77
|
+
end
|
78
|
+
|
79
|
+
def candidate_scope
|
80
|
+
scope.singleton_class
|
81
|
+
end
|
82
|
+
memoize :candidate_scope, freezer: :noop
|
83
|
+
end # Metaclass
|
84
|
+
|
88
85
|
# Matcher for instance methods
|
89
86
|
class Instance < self
|
90
87
|
MATCHER = Matcher::Method::Instance
|
91
88
|
|
92
89
|
private
|
93
90
|
|
94
|
-
# Method object on scope
|
95
|
-
#
|
96
|
-
# @param [Symbol] method_name
|
97
|
-
#
|
98
|
-
# @return [UnboundMethod]
|
99
91
|
def access(method_name)
|
100
92
|
scope.instance_method(method_name)
|
101
93
|
end
|
102
94
|
|
103
|
-
# Candidate scope
|
104
|
-
#
|
105
|
-
# @return [Class, Module]
|
106
95
|
def candidate_scope
|
107
96
|
scope
|
108
97
|
end
|
@@ -19,22 +19,12 @@ module Mutant
|
|
19
19
|
|
20
20
|
private
|
21
21
|
|
22
|
-
# The matched scopes
|
23
|
-
#
|
24
|
-
# @param [Env] env
|
25
|
-
#
|
26
|
-
# @return [Enumerable<Scope>]
|
27
22
|
def matched_scopes(env)
|
28
23
|
env
|
29
24
|
.matchable_scopes
|
30
25
|
.select(&method(:match?))
|
31
26
|
end
|
32
27
|
|
33
|
-
# Test scope if matches expression
|
34
|
-
#
|
35
|
-
# @param [Scope] scope
|
36
|
-
#
|
37
|
-
# @return [Boolean]
|
38
28
|
def match?(scope)
|
39
29
|
expression.prefix?(scope.expression)
|
40
30
|
end
|
data/lib/mutant/matcher/scope.rb
CHANGED
@@ -13,7 +13,8 @@ module Mutant
|
|
13
13
|
|
14
14
|
MATCHERS = [
|
15
15
|
Matcher::Methods::Singleton,
|
16
|
-
Matcher::Methods::Instance
|
16
|
+
Matcher::Methods::Instance,
|
17
|
+
Matcher::Methods::Metaclass
|
17
18
|
].freeze
|
18
19
|
|
19
20
|
private_constant(*constants(false))
|
@@ -29,9 +30,6 @@ module Mutant
|
|
29
30
|
|
30
31
|
private
|
31
32
|
|
32
|
-
# Effective matchers
|
33
|
-
#
|
34
|
-
# @return [Enumerable<Matcher>]
|
35
33
|
def effective_matchers
|
36
34
|
MATCHERS.map { |matcher| matcher.new(scope) }
|
37
35
|
end
|
@@ -49,21 +49,11 @@ module Mutant
|
|
49
49
|
|
50
50
|
private
|
51
51
|
|
52
|
-
# Set original source
|
53
|
-
#
|
54
|
-
# @param [String,Parser::AST::Node] input
|
55
|
-
#
|
56
|
-
# @return [undefined]
|
57
52
|
def source(input)
|
58
53
|
fail 'source already defined' if @node
|
59
54
|
@node = node(input)
|
60
55
|
end
|
61
56
|
|
62
|
-
# Add expected mutation
|
63
|
-
#
|
64
|
-
# @param [String,Parser::AST::Node] input
|
65
|
-
#
|
66
|
-
# @return [undefined]
|
67
57
|
def mutation(input)
|
68
58
|
node = node(input)
|
69
59
|
if @expected.include?(node)
|
@@ -72,22 +62,11 @@ module Mutant
|
|
72
62
|
@expected << node
|
73
63
|
end
|
74
64
|
|
75
|
-
# Add singleton mutations
|
76
|
-
#
|
77
|
-
# @return [undefined]
|
78
65
|
def singleton_mutations
|
79
66
|
mutation('nil')
|
80
67
|
mutation('self')
|
81
68
|
end
|
82
69
|
|
83
|
-
# Helper method to coerce input to node
|
84
|
-
#
|
85
|
-
# @param [String,Parser::AST::Node] input
|
86
|
-
#
|
87
|
-
# @return [Parser::AST::Node]
|
88
|
-
#
|
89
|
-
# @raise [RuntimeError]
|
90
|
-
# in case input cannot be coerced
|
91
70
|
def node(input)
|
92
71
|
case input
|
93
72
|
when String
|
@@ -35,9 +35,6 @@ module Mutant
|
|
35
35
|
|
36
36
|
private
|
37
37
|
|
38
|
-
# Unexpected mutations
|
39
|
-
#
|
40
|
-
# @return [Array<Mutation>]
|
41
38
|
def unexpected
|
42
39
|
mutations.reject do |mutation|
|
43
40
|
example.expected.include?(mutation.node)
|
@@ -45,9 +42,6 @@ module Mutant
|
|
45
42
|
end
|
46
43
|
memoize :unexpected
|
47
44
|
|
48
|
-
# Missing mutations
|
49
|
-
#
|
50
|
-
# @return [Array<Mutation>]
|
51
45
|
def missing
|
52
46
|
(example.expected - mutations.map(&:node)).map do |node|
|
53
47
|
Mutation::Evil.new(self, node)
|
@@ -55,9 +49,6 @@ module Mutant
|
|
55
49
|
end
|
56
50
|
memoize :missing
|
57
51
|
|
58
|
-
# Mutations that generated invalid syntax
|
59
|
-
#
|
60
|
-
# @return [Enumerable<Mutation>]
|
61
52
|
def invalid_syntax
|
62
53
|
mutations.reject do |mutation|
|
63
54
|
::Parser::CurrentRuby.parse(mutation.source)
|
@@ -66,19 +57,11 @@ module Mutant
|
|
66
57
|
end
|
67
58
|
memoize :invalid_syntax
|
68
59
|
|
69
|
-
# Mutations with no diff to original
|
70
|
-
#
|
71
|
-
# @return [Enumerable<Mutation>]
|
72
60
|
def no_diffs
|
73
61
|
mutations.select { |mutation| mutation.source.eql?(example.source) }
|
74
62
|
end
|
75
63
|
memoize :no_diffs
|
76
64
|
|
77
|
-
# Mutation report
|
78
|
-
#
|
79
|
-
# @param [Array<Mutation>] mutations
|
80
|
-
#
|
81
|
-
# @return [Array<Hash>]
|
82
65
|
def format_mutations(mutations)
|
83
66
|
mutations.map do |mutation|
|
84
67
|
{
|
@@ -88,9 +71,6 @@ module Mutant
|
|
88
71
|
end
|
89
72
|
end
|
90
73
|
|
91
|
-
# No diff mutation report
|
92
|
-
#
|
93
|
-
# @return [Array, nil]
|
94
74
|
def no_diff_report
|
95
75
|
no_diffs.map do |mutation|
|
96
76
|
{
|
@@ -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)
|
data/lib/mutant/mutation.rb
CHANGED
data/lib/mutant/mutator.rb
CHANGED
@@ -18,9 +18,6 @@ module Mutant
|
|
18
18
|
self::REGISTRY.lookup(node.type).call(node, parent)
|
19
19
|
end
|
20
20
|
|
21
|
-
# Register node class handler
|
22
|
-
#
|
23
|
-
# @return [undefined]
|
24
21
|
def self.handle(*types)
|
25
22
|
types.each do |type|
|
26
23
|
self::REGISTRY.register(type, self)
|
@@ -35,13 +32,6 @@ module Mutant
|
|
35
32
|
|
36
33
|
private
|
37
34
|
|
38
|
-
# Initialize object
|
39
|
-
#
|
40
|
-
# @param [Object] input
|
41
|
-
# @param [Object] parent
|
42
|
-
# @param [#call(node)] block
|
43
|
-
#
|
44
|
-
# @return [undefined]
|
45
35
|
def initialize(_input, _parent = nil)
|
46
36
|
super
|
47
37
|
|
@@ -50,41 +40,23 @@ module Mutant
|
|
50
40
|
dispatch
|
51
41
|
end
|
52
42
|
|
53
|
-
# Test if generated object is not guarded from emitting
|
54
|
-
#
|
55
|
-
# @param [Object] object
|
56
|
-
#
|
57
|
-
# @return [Boolean]
|
58
43
|
def new?(object)
|
59
44
|
!object.eql?(input)
|
60
45
|
end
|
61
46
|
|
62
|
-
# Dispatch node generations
|
63
|
-
#
|
64
|
-
# @return [undefined]
|
65
47
|
abstract_method :dispatch
|
48
|
+
private :dispatch
|
66
49
|
|
67
|
-
# Emit generated mutation if object is not equivalent to input
|
68
|
-
#
|
69
|
-
# @param [Object] object
|
70
|
-
#
|
71
|
-
# @return [undefined]
|
72
50
|
def emit(object)
|
73
51
|
return unless new?(object)
|
74
52
|
|
75
53
|
output << object
|
76
54
|
end
|
77
55
|
|
78
|
-
# Run input with mutator
|
79
|
-
#
|
80
|
-
# @return [undefined]
|
81
56
|
def run(mutator)
|
82
57
|
mutator.call(input).each(&method(:emit))
|
83
58
|
end
|
84
59
|
|
85
|
-
# Shortcut to create a new unfrozen duplicate of input
|
86
|
-
#
|
87
|
-
# @return [Object]
|
88
60
|
def dup_input
|
89
61
|
input.dup
|
90
62
|
end
|
data/lib/mutant/mutator/node.rb
CHANGED
@@ -34,21 +34,9 @@ module Mutant
|
|
34
34
|
|
35
35
|
private
|
36
36
|
|
37
|
-
|
38
|
-
#
|
39
|
-
# @return [Parser::AST::Node]
|
40
|
-
alias_method :node, :input
|
41
|
-
|
42
|
-
# Duplicate of original
|
43
|
-
#
|
44
|
-
# @return [Parser::AST::Node]
|
37
|
+
alias_method :node, :input
|
45
38
|
alias_method :dup_node, :dup_input
|
46
39
|
|
47
|
-
# Dispatch on child index
|
48
|
-
#
|
49
|
-
# @param [Integer] index
|
50
|
-
#
|
51
|
-
# @return [undefined]
|
52
40
|
def mutate_child(index, &block)
|
53
41
|
block ||= TAUTOLOGY
|
54
42
|
Mutator.mutate(children.fetch(index), self).each do |mutation|
|
@@ -57,108 +45,55 @@ module Mutant
|
|
57
45
|
end
|
58
46
|
end
|
59
47
|
|
60
|
-
# Emit delete child mutation
|
61
|
-
#
|
62
|
-
# @param [Integer] index
|
63
|
-
#
|
64
|
-
# @return [undefined]
|
65
48
|
def delete_child(index)
|
66
49
|
dup_children = children.dup
|
67
50
|
dup_children.delete_at(index)
|
68
51
|
emit_type(*dup_children)
|
69
52
|
end
|
70
53
|
|
71
|
-
# Emit updated child
|
72
|
-
#
|
73
|
-
# @param [Integer] index
|
74
|
-
# @param [Parser::AST::Node] node
|
75
|
-
#
|
76
|
-
# @return [undefined]
|
77
54
|
def emit_child_update(index, node)
|
78
55
|
new_children = children.dup
|
79
56
|
new_children[index] = node
|
80
57
|
emit_type(*new_children)
|
81
58
|
end
|
82
59
|
|
83
|
-
# Emit a new AST node with same class as wrapped node
|
84
|
-
#
|
85
|
-
# @param [Array<Parser::AST::Node>] children
|
86
|
-
#
|
87
|
-
# @return [undefined]
|
88
60
|
def emit_type(*children)
|
89
61
|
emit(::Parser::AST::Node.new(node.type, children))
|
90
62
|
end
|
91
63
|
|
92
|
-
# Emit propagation if node can stand alone
|
93
|
-
#
|
94
|
-
# @return [undefined]
|
95
64
|
def emit_propagation(node)
|
96
65
|
emit(node) unless AST::Types::NOT_STANDALONE.include?(node.type)
|
97
66
|
end
|
98
67
|
|
99
|
-
# Emit singleton literals
|
100
|
-
#
|
101
|
-
# @return [undefined]
|
102
68
|
def emit_singletons
|
103
69
|
emit_nil
|
104
70
|
emit_self
|
105
71
|
end
|
106
72
|
|
107
|
-
# Emit a literal self
|
108
|
-
#
|
109
|
-
# @return [undefined]
|
110
73
|
def emit_self
|
111
74
|
emit(N_SELF)
|
112
75
|
end
|
113
76
|
|
114
|
-
# Emit a literal nil
|
115
|
-
#
|
116
|
-
# @return [undefined]
|
117
77
|
def emit_nil
|
118
78
|
emit(N_NIL) unless left_assignment?
|
119
79
|
end
|
120
80
|
|
121
|
-
# Parent node
|
122
|
-
#
|
123
|
-
# @return [Parser::AST::Node] node
|
124
|
-
# if parent with node is present
|
125
|
-
#
|
126
|
-
# @return [nil]
|
127
|
-
# otherwise
|
128
81
|
def parent_node
|
129
82
|
parent&.node
|
130
83
|
end
|
131
84
|
|
132
|
-
# Parent type
|
133
|
-
#
|
134
|
-
# @return [Symbol] type
|
135
|
-
# if parent with type is present
|
136
|
-
#
|
137
|
-
# @return [nil]
|
138
|
-
# otherwise
|
139
85
|
def parent_type
|
140
86
|
parent_node&.type
|
141
87
|
end
|
142
88
|
|
143
|
-
# Test if the node is the left of an or_asgn or op_asgn
|
144
|
-
#
|
145
|
-
# @return [Boolean]
|
146
89
|
def left_assignment?
|
147
90
|
AST::Types::OP_ASSIGN.include?(parent_type) && parent.node.children.first.equal?(node)
|
148
91
|
end
|
149
92
|
|
150
|
-
# Children indices
|
151
|
-
#
|
152
|
-
# @param [Range] range
|
153
|
-
#
|
154
|
-
# @return [Enumerable<Integer>]
|
155
93
|
def children_indices(range)
|
156
94
|
range.begin.upto(children.length + range.end)
|
157
95
|
end
|
158
96
|
|
159
|
-
# Emit single child mutation
|
160
|
-
#
|
161
|
-
# @return [undefined]
|
162
97
|
def mutate_single_child
|
163
98
|
children.each_with_index do |child, index|
|
164
99
|
mutate_child(index)
|