mutant 0.9.7 → 0.9.12
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 +0 -36
- data/lib/mutant/cli.rb +5 -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 +0 -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 -74
- 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/registry.rb +2 -7
- 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 +0 -18
- 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/.circleci/config.yml +0 -53
- data/.gitignore +0 -38
- data/.rspec +0 -5
- data/.rubocop.yml +0 -7
- data/Changelog.md +0 -71
- data/Gemfile +0 -14
- data/Gemfile.lock +0 -167
- data/Gemfile.shared +0 -3
- 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 -47
- 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
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
|
@@ -73,9 +73,6 @@ module Mutant
|
|
73
73
|
|
74
74
|
private
|
75
75
|
|
76
|
-
# Start child process
|
77
|
-
#
|
78
|
-
# @return [Integer]
|
79
76
|
def start_child
|
80
77
|
world.process.fork do
|
81
78
|
Child.call(
|
@@ -87,12 +84,6 @@ module Mutant
|
|
87
84
|
end
|
88
85
|
end
|
89
86
|
|
90
|
-
# Read child result
|
91
|
-
#
|
92
|
-
# @param [Integer] pid
|
93
|
-
#
|
94
|
-
# @return [undefined]
|
95
|
-
#
|
96
87
|
# rubocop:disable Metrics/MethodLength
|
97
88
|
def read_child_result(pid)
|
98
89
|
result_fragments = []
|
@@ -115,11 +106,6 @@ module Mutant
|
|
115
106
|
end
|
116
107
|
# rubocop:enable Metrics/MethodLength
|
117
108
|
|
118
|
-
# Read fragments
|
119
|
-
#
|
120
|
-
# @param [Hash{FD => Array<String}] targets
|
121
|
-
#
|
122
|
-
# @return [undefined]
|
123
109
|
def read_fragments(targets)
|
124
110
|
until targets.empty?
|
125
111
|
ready, = world.io.select(targets.keys)
|
@@ -134,11 +120,6 @@ module Mutant
|
|
134
120
|
end
|
135
121
|
end
|
136
122
|
|
137
|
-
# Wait for child process
|
138
|
-
#
|
139
|
-
# @param [Integer] pid
|
140
|
-
#
|
141
|
-
# @return [undefined]
|
142
123
|
def wait_child(pid, log_fragments)
|
143
124
|
_pid, status = world.process.wait2(pid)
|
144
125
|
|
@@ -147,9 +128,6 @@ module Mutant
|
|
147
128
|
end
|
148
129
|
end
|
149
130
|
|
150
|
-
# Add a result
|
151
|
-
#
|
152
|
-
# @param [Result]
|
153
131
|
def add_result(result)
|
154
132
|
@result = defined?(@result) ? @result.add_error(result) : result
|
155
133
|
end
|
data/lib/mutant/license.rb
CHANGED
@@ -43,6 +43,8 @@ module Mutant
|
|
43
43
|
def self.load_mutant_license(world)
|
44
44
|
Either
|
45
45
|
.wrap_error(LoadError) { world.gem_method.call(NAME, VERSION) }
|
46
|
+
.lmap(&:message)
|
47
|
+
.lmap(&method(:check_for_rubygems_mutant_license))
|
46
48
|
.lmap(&method(:unlicensed))
|
47
49
|
end
|
48
50
|
|
@@ -50,6 +52,15 @@ module Mutant
|
|
50
52
|
"[Mutant-License-Error]: #{message}"
|
51
53
|
end
|
52
54
|
|
55
|
+
def self.check_for_rubygems_mutant_license(message)
|
56
|
+
if message.include?('already activated mutant-license-0.0.0')
|
57
|
+
'mutant-license gem from rubygems.org is a dummy'
|
58
|
+
else
|
59
|
+
message
|
60
|
+
end
|
61
|
+
end
|
62
|
+
private_class_method :check_for_rubygems_mutant_license
|
63
|
+
|
53
64
|
def self.license_path(world)
|
54
65
|
world
|
55
66
|
.pathname
|
data/lib/mutant/matcher.rb
CHANGED
@@ -25,25 +25,11 @@ module Mutant
|
|
25
25
|
)
|
26
26
|
end
|
27
27
|
|
28
|
-
# Test if subject is allowed do
|
29
|
-
#
|
30
|
-
# @param [Config] config
|
31
|
-
# @param [Subject] subject
|
32
|
-
#
|
33
|
-
# @return [Boolean]
|
34
28
|
def self.allowed_subject?(config, subject)
|
35
29
|
select_subject?(config, subject) && !ignore_subject?(config, subject)
|
36
30
|
end
|
37
31
|
private_class_method :allowed_subject?
|
38
32
|
|
39
|
-
# Predicate that tests for selected subject
|
40
|
-
#
|
41
|
-
# @param [Config] config
|
42
|
-
# @param [Subject] subject
|
43
|
-
#
|
44
|
-
# @return [Boolean]
|
45
|
-
#
|
46
|
-
# @api private
|
47
33
|
def self.select_subject?(config, subject)
|
48
34
|
config.subject_filters.all? { |filter| filter.call(subject) }
|
49
35
|
end
|
@@ -44,16 +44,10 @@ module Mutant
|
|
44
44
|
|
45
45
|
private
|
46
46
|
|
47
|
-
# Present attributes
|
48
|
-
#
|
49
|
-
# @return [Array<Symbol>]
|
50
47
|
def present_attributes
|
51
48
|
to_h.reject { |_key, value| value.empty? }.keys
|
52
49
|
end
|
53
50
|
|
54
|
-
# Formatted attributes
|
55
|
-
#
|
56
|
-
# @return [String]
|
57
51
|
def inspect_attributes
|
58
52
|
attributes = present_attributes
|
59
53
|
.map(&method(:format_attribute))
|
@@ -62,11 +56,6 @@ module Mutant
|
|
62
56
|
attributes.empty? ? EMPTY_ATTRIBUTES : attributes
|
63
57
|
end
|
64
58
|
|
65
|
-
# Format attribute
|
66
|
-
#
|
67
|
-
# @param [Symbol] attribute_name
|
68
|
-
#
|
69
|
-
# @return [String]
|
70
59
|
def format_attribute(attribute_name)
|
71
60
|
ATTRIBUTE_FORMAT %
|
72
61
|
[
|
@@ -49,9 +49,6 @@ module Mutant
|
|
49
49
|
|
50
50
|
private
|
51
51
|
|
52
|
-
# Test if method should be skipped
|
53
|
-
#
|
54
|
-
# @return [Truthy]
|
55
52
|
def skip?
|
56
53
|
location = source_location
|
57
54
|
if location.nil? || BLACKLIST.include?(location.first)
|
@@ -61,56 +58,31 @@ module Mutant
|
|
61
58
|
end
|
62
59
|
end
|
63
60
|
|
64
|
-
# Target method name
|
65
|
-
#
|
66
|
-
# @return [String]
|
67
61
|
def method_name
|
68
62
|
target_method.name
|
69
63
|
end
|
70
64
|
|
71
|
-
# Target context
|
72
|
-
#
|
73
|
-
# @return [Context]
|
74
65
|
def context
|
75
66
|
Context.new(scope, source_path)
|
76
67
|
end
|
77
68
|
|
78
|
-
# Root source node
|
79
|
-
#
|
80
|
-
# @return [Parser::AST::Node]
|
81
69
|
def ast
|
82
70
|
env.parser.call(source_path)
|
83
71
|
end
|
84
72
|
|
85
|
-
# Path to source
|
86
|
-
#
|
87
|
-
# @return [Pathname]
|
88
73
|
def source_path
|
89
74
|
env.world.pathname.new(source_location.first)
|
90
75
|
end
|
91
76
|
memoize :source_path
|
92
77
|
|
93
|
-
# Source file line
|
94
|
-
#
|
95
|
-
# @return [Integer]
|
96
78
|
def source_line
|
97
79
|
source_location.last
|
98
80
|
end
|
99
81
|
|
100
|
-
# Full source location
|
101
|
-
#
|
102
|
-
# @return [Array{String,Integer}]
|
103
82
|
def source_location
|
104
83
|
target_method.source_location
|
105
84
|
end
|
106
85
|
|
107
|
-
# Matched subject
|
108
|
-
#
|
109
|
-
# @return [Subject]
|
110
|
-
# if there is a matched node
|
111
|
-
#
|
112
|
-
# @return [nil]
|
113
|
-
# otherwise
|
114
86
|
def subject
|
115
87
|
node = matched_node_path.last || return
|
116
88
|
|
@@ -122,9 +94,6 @@ module Mutant
|
|
122
94
|
end
|
123
95
|
memoize :subject
|
124
96
|
|
125
|
-
# Matched node path
|
126
|
-
#
|
127
|
-
# @return [Array<Parser::AST::Node>]
|
128
97
|
def matched_node_path
|
129
98
|
AST.find_last_path(ast, &method(:match?))
|
130
99
|
end
|
@@ -33,11 +33,6 @@ module Mutant
|
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
-
# Check if node is matched
|
37
|
-
#
|
38
|
-
# @param [Parser::AST::Node] node
|
39
|
-
#
|
40
|
-
# @return [Boolean]
|
41
36
|
def match?(node)
|
42
37
|
n_def?(node) &&
|
43
38
|
node.location.line.equal?(source_line) &&
|
@@ -50,9 +45,6 @@ module Mutant
|
|
50
45
|
|
51
46
|
private
|
52
47
|
|
53
|
-
# Source location
|
54
|
-
#
|
55
|
-
# @return [Array{String,Integer}]
|
56
48
|
def source_location
|
57
49
|
scope
|
58
50
|
.unmemoized_instance_method(method_name)
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mutant
|
4
|
+
class Matcher
|
5
|
+
class Method
|
6
|
+
# Matcher for metaclass methods
|
7
|
+
# i.e. ones defined using class << self or class << CONSTANT. It might??
|
8
|
+
# work for methods defined like class << obj, but I don't think the
|
9
|
+
# plumbing will be in place in the subject for that to work
|
10
|
+
class Metaclass < self
|
11
|
+
|
12
|
+
# New singleton method matcher
|
13
|
+
#
|
14
|
+
# @param [Class, Module] scope
|
15
|
+
# @param [Symbol] method_name
|
16
|
+
#
|
17
|
+
# @return [Matcher::Method::Singleton]
|
18
|
+
def self.new(scope, method_name)
|
19
|
+
super(scope, method_name, Evaluator)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Metaclass method evaluator
|
23
|
+
class Evaluator < Evaluator
|
24
|
+
# Terminology note: the "receiver" is the `self` in `class << self`
|
25
|
+
SUBJECT_CLASS = Subject::Method::Metaclass
|
26
|
+
NAME_INDEX = 0
|
27
|
+
CONST_NAME_INDEX = 1
|
28
|
+
SCLASS_RECEIVER_INDEX = 0
|
29
|
+
RECEIVER_WARNING = 'Can only match :def inside :sclass on ' \
|
30
|
+
':self or :const, got :sclass on %p ' \
|
31
|
+
'unable to match'
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def match?(node)
|
36
|
+
n_def?(node) &&
|
37
|
+
name?(node) &&
|
38
|
+
line?(node) &&
|
39
|
+
metaclass_receiver?(node)
|
40
|
+
end
|
41
|
+
|
42
|
+
def metaclass_receiver?(node)
|
43
|
+
candidate = metaclass_containing(node)
|
44
|
+
candidate && metaclass_target?(candidate)
|
45
|
+
end
|
46
|
+
|
47
|
+
def metaclass_containing(node)
|
48
|
+
AST::FindMetaclassContaining.call(ast, node)
|
49
|
+
end
|
50
|
+
|
51
|
+
def line?(node)
|
52
|
+
node
|
53
|
+
.location
|
54
|
+
.line
|
55
|
+
.equal?(source_line)
|
56
|
+
end
|
57
|
+
|
58
|
+
def name?(node)
|
59
|
+
node.children.fetch(NAME_INDEX).equal?(method_name)
|
60
|
+
end
|
61
|
+
|
62
|
+
def metaclass_target?(node)
|
63
|
+
receiver = node.children.fetch(SCLASS_RECEIVER_INDEX)
|
64
|
+
case receiver.type
|
65
|
+
when :self
|
66
|
+
true
|
67
|
+
when :const
|
68
|
+
sclass_const_name?(receiver)
|
69
|
+
else
|
70
|
+
env.warn(RECEIVER_WARNING % receiver.type)
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def sclass_const_name?(node)
|
76
|
+
name = node.children.fetch(CONST_NAME_INDEX)
|
77
|
+
name.to_s.eql?(context.unqualified_name)
|
78
|
+
end
|
79
|
+
|
80
|
+
end # Evaluator
|
81
|
+
|
82
|
+
private_constant(*constants(false))
|
83
|
+
end # Singleton
|
84
|
+
end # Method
|
85
|
+
end # Matcher
|
86
|
+
end # Mutant
|
@@ -25,20 +25,10 @@ module Mutant
|
|
25
25
|
|
26
26
|
private
|
27
27
|
|
28
|
-
# Test for node match
|
29
|
-
#
|
30
|
-
# @param [Parser::AST::Node] node
|
31
|
-
#
|
32
|
-
# @return [Boolean]
|
33
28
|
def match?(node)
|
34
29
|
n_defs?(node) && line?(node) && name?(node) && receiver?(node)
|
35
30
|
end
|
36
31
|
|
37
|
-
# Test for line match
|
38
|
-
#
|
39
|
-
# @param [Parser::AST::Node] node
|
40
|
-
#
|
41
|
-
# @return [Boolean]
|
42
32
|
def line?(node)
|
43
33
|
node
|
44
34
|
.location
|
@@ -46,20 +36,10 @@ module Mutant
|
|
46
36
|
.equal?(source_line)
|
47
37
|
end
|
48
38
|
|
49
|
-
# Test for name match
|
50
|
-
#
|
51
|
-
# @param [Parser::AST::Node] node
|
52
|
-
#
|
53
|
-
# @return [Boolean]
|
54
39
|
def name?(node)
|
55
40
|
node.children.fetch(NAME_INDEX).equal?(method_name)
|
56
41
|
end
|
57
42
|
|
58
|
-
# Test for receiver match
|
59
|
-
#
|
60
|
-
# @param [Parser::AST::Node] node
|
61
|
-
#
|
62
|
-
# @return [Boolean]
|
63
43
|
def receiver?(node)
|
64
44
|
receiver = node.children.fetch(RECEIVER_INDEX)
|
65
45
|
case receiver.type
|
@@ -73,11 +53,6 @@ module Mutant
|
|
73
53
|
end
|
74
54
|
end
|
75
55
|
|
76
|
-
# Test if receiver name matches context
|
77
|
-
#
|
78
|
-
# @param [Parser::AST::Node] node
|
79
|
-
#
|
80
|
-
# @return [Boolean]
|
81
56
|
def receiver_name?(node)
|
82
57
|
name = node.children.fetch(NAME_INDEX)
|
83
58
|
name.to_s.eql?(context.unqualified_name)
|
@@ -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
|