mutant 0.2.20 → 0.3.0.beta2
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 +7 -0
- data/.travis.yml +10 -11
- data/Changelog.md +93 -38
- data/Gemfile +3 -1
- data/Gemfile.devtools +16 -20
- data/Guardfile +1 -1
- data/README.md +36 -16
- data/Rakefile +21 -2
- data/TODO +11 -7
- data/bin/mutant +4 -0
- data/bin/zombie +4 -0
- data/config/devtools.yml +2 -0
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/{site.reek → reek.yml} +94 -70
- data/lib/mutant/cli/classifier/method.rb +100 -0
- data/lib/mutant/cli/classifier/namespace.rb +47 -0
- data/lib/mutant/cli/classifier/scope.rb +35 -0
- data/lib/mutant/cli/classifier.rb +141 -0
- data/lib/mutant/cli.rb +115 -162
- data/lib/mutant/color.rb +2 -2
- data/lib/mutant/config.rb +27 -0
- data/lib/mutant/constants.rb +32 -17
- data/lib/mutant/context/scope.rb +33 -51
- data/lib/mutant/context.rb +8 -19
- data/lib/mutant/differ.rb +5 -5
- data/lib/mutant/helper.rb +2 -17
- data/lib/mutant/killer/forked.rb +44 -0
- data/lib/mutant/killer/forking.rb +3 -57
- data/lib/mutant/killer/rspec.rb +16 -20
- data/lib/mutant/killer/static.rb +6 -7
- data/lib/mutant/killer.rb +48 -74
- data/lib/mutant/loader.rb +6 -6
- data/lib/mutant/matcher/chain.rb +4 -25
- data/lib/mutant/matcher/method/instance.rb +14 -24
- data/lib/mutant/matcher/method/singleton.rb +35 -46
- data/lib/mutant/matcher/method.rb +95 -83
- data/lib/mutant/matcher/{scope_methods.rb → methods.rb} +53 -76
- data/lib/mutant/matcher/namespace.rb +71 -0
- data/lib/mutant/matcher/scope.rb +34 -0
- data/lib/mutant/matcher.rb +24 -34
- data/lib/mutant/mutation/evil.rb +35 -0
- data/lib/mutant/mutation/filter/code.rb +7 -28
- data/lib/mutant/mutation/filter/regexp.rb +6 -18
- data/lib/mutant/mutation/filter/whitelist.rb +5 -4
- data/lib/mutant/mutation/filter.rb +10 -9
- data/lib/mutant/mutation/neutral.rb +35 -0
- data/lib/mutant/mutation.rb +21 -61
- data/lib/mutant/mutator/node/argument.rb +88 -0
- data/lib/mutant/mutator/node/arguments.rb +52 -0
- data/lib/mutant/mutator/node/assignment.rb +34 -38
- data/lib/mutant/mutator/node/begin.rb +33 -0
- data/lib/mutant/mutator/node/block.rb +14 -14
- data/lib/mutant/mutator/node/case.rb +59 -0
- data/lib/mutant/mutator/node/define.rb +26 -22
- data/lib/mutant/mutator/node/if.rb +31 -71
- data/lib/mutant/mutator/node/literal/array.rb +25 -9
- data/lib/mutant/mutator/node/literal/boolean.rb +13 -30
- data/lib/mutant/mutator/node/literal/dynamic.rb +6 -5
- data/lib/mutant/mutator/node/literal/fixnum.rb +18 -7
- data/lib/mutant/mutator/node/literal/float.rb +15 -8
- data/lib/mutant/mutator/node/literal/hash.rb +33 -52
- data/lib/mutant/mutator/node/literal/nil.rb +8 -7
- data/lib/mutant/mutator/node/literal/range.rb +25 -50
- data/lib/mutant/mutator/node/literal/regex.rb +15 -23
- data/lib/mutant/mutator/node/literal/string.rb +7 -6
- data/lib/mutant/mutator/node/literal/symbol.rb +7 -6
- data/lib/mutant/mutator/node/literal.rb +4 -46
- data/lib/mutant/mutator/node/mlhs.rb +27 -0
- data/lib/mutant/mutator/node/noop.rb +18 -43
- data/lib/mutant/mutator/node/return.rb +8 -8
- data/lib/mutant/mutator/node/send/binary.rb +31 -0
- data/lib/mutant/mutator/node/send.rb +106 -72
- data/lib/mutant/mutator/node/super.rb +15 -20
- data/lib/mutant/mutator/node/when.rb +32 -7
- data/lib/mutant/mutator/node/while.rb +9 -7
- data/lib/mutant/mutator/node.rb +116 -66
- data/lib/mutant/mutator/registry.rb +14 -11
- data/lib/mutant/mutator/util/array.rb +9 -9
- data/lib/mutant/mutator/util/symbol.rb +6 -20
- data/lib/mutant/mutator/util.rb +6 -3
- data/lib/mutant/mutator.rb +12 -28
- data/lib/mutant/node_helpers.rb +28 -0
- data/lib/mutant/random.rb +3 -2
- data/lib/mutant/reporter/cli/printer/config.rb +174 -0
- data/lib/mutant/reporter/cli/printer/killer.rb +42 -0
- data/lib/mutant/reporter/cli/printer/mutation.rb +55 -0
- data/lib/mutant/reporter/cli/printer/subject.rb +147 -0
- data/lib/mutant/reporter/cli/printer.rb +165 -0
- data/lib/mutant/reporter/cli.rb +9 -277
- data/lib/mutant/reporter/null.rb +6 -30
- data/lib/mutant/reporter.rb +6 -73
- data/lib/mutant/runner/config.rb +82 -0
- data/lib/mutant/runner/mutation.rb +58 -0
- data/lib/mutant/runner/subject.rb +81 -0
- data/lib/mutant/runner.rb +42 -92
- data/lib/mutant/singleton_methods.rb +2 -2
- data/lib/mutant/strategy/method_expansion.rb +51 -0
- data/lib/mutant/strategy/rspec/dm2/lookup/method.rb +142 -0
- data/lib/mutant/strategy/rspec/dm2/lookup.rb +61 -0
- data/lib/mutant/strategy/rspec/dm2.rb +22 -0
- data/lib/mutant/strategy/rspec.rb +20 -22
- data/lib/mutant/strategy/static.rb +18 -0
- data/lib/mutant/strategy.rb +15 -50
- data/lib/mutant/subject/method.rb +100 -0
- data/lib/mutant/subject.rb +18 -49
- data/lib/mutant/support/method_object.rb +4 -2
- data/lib/mutant.rb +40 -35
- data/mutant.gemspec +9 -8
- data/spec/integration/mutant/rspec_killer_spec.rb +3 -3
- data/spec/integration/mutant/test_mutator_handles_types_spec.rb +9 -0
- data/spec/integration/mutant/zombie_spec.rb +1 -1
- data/spec/shared/method_matcher_behavior.rb +35 -0
- data/spec/shared/mutator_behavior.rb +63 -32
- data/spec/spec_helper.rb +13 -3
- data/spec/support/ice_nine_config.rb +8 -0
- data/spec/support/rspec.rb +1 -1
- data/spec/support/zombie.rb +1 -1
- data/spec/unit/mutant/cli/class_methods/new_spec.rb +42 -28
- data/spec/unit/mutant/cli/class_methods/run_spec.rb +15 -13
- data/spec/unit/mutant/cli/classifier/class_methods/build_spec.rb +44 -0
- data/spec/unit/mutant/context/scope/root_spec.rb +4 -4
- data/spec/unit/mutant/killer/rspec/class_methods/new_spec.rb +6 -5
- data/spec/unit/mutant/killer/success_predicate_spec.rb +28 -0
- data/spec/unit/mutant/loader/eval/class_methods/run_spec.rb +1 -1
- data/spec/unit/mutant/matcher/chain/each_spec.rb +1 -1
- data/spec/unit/mutant/matcher/chain/matchers_spec.rb +1 -1
- data/spec/unit/mutant/matcher/method/instance/each_spec.rb +112 -0
- data/spec/unit/mutant/matcher/method/singleton/each_spec.rb +93 -0
- data/spec/unit/mutant/matcher/methods/instance/each_spec.rb +59 -0
- data/spec/unit/mutant/matcher/methods/singleton/each_spec.rb +53 -0
- data/spec/unit/mutant/matcher/namespace/each_spec.rb +37 -0
- data/spec/unit/mutant/mutator/node/begin/mutation_spec.rb +33 -0
- data/spec/unit/mutant/mutator/node/block/mutation_spec.rb +42 -14
- data/spec/unit/mutant/mutator/node/case/mutation_spec.rb +319 -0
- data/spec/unit/mutant/mutator/node/define/mutation_spec.rb +31 -27
- data/spec/unit/mutant/mutator/node/if/mutation_spec.rb +75 -0
- data/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb +1 -1
- data/spec/unit/mutant/mutator/node/literal/hash_spec.rb +2 -2
- data/spec/unit/mutant/mutator/node/literal/nil_spec.rb +1 -3
- data/spec/unit/mutant/mutator/node/literal/regex_spec.rb +1 -9
- data/spec/unit/mutant/mutator/node/return/mutation_spec.rb +6 -2
- data/spec/unit/mutant/mutator/node/send/mutation_spec.rb +111 -108
- data/spec/unit/mutant/mutator/node/super/mutation_spec.rb +0 -33
- data/spec/unit/mutant/mutator/node/while/mutation_spec.rb +2 -2
- data/spec/unit/mutant/runner/config/subjects_spec.rb +38 -0
- data/spec/unit/mutant/runner/config/success_predicate_spec.rb +53 -0
- data/spec/unit/mutant/runner/failed_predicte_spec.rb +33 -0
- data/spec/unit/mutant/runner/mutation/killer_spec.rb +39 -0
- data/spec/unit/mutant/runner/subject/success_predicate_spec.rb +49 -0
- data/spec/unit/mutant/strategy/method_expansion/class_methods/run_spec.rb +49 -0
- data/spec/unit/mutant/strategy/rspec/dm2/lookup/method/instance/spec_files_spec.rb +52 -0
- data/spec/unit/mutant/strategy/rspec/dm2/lookup/method/singleton/spec_files_spec.rb +42 -0
- data/spec/unit/mutant/subject/context_spec.rb +6 -3
- data/spec/unit/mutant/subject/each_spec.rb +11 -8
- data/spec/unit/mutant/subject/node_spec.rb +6 -2
- data/test_app/spec/shared/method_filter_parse_behavior.rb +0 -2
- data/test_app/spec/shared/method_match_behavior.rb +1 -1
- data/test_app/spec/spec_helper.rb +4 -2
- metadata +101 -109
- data/config/roodi.yml +0 -26
- data/lib/mutant/matcher/method/classifier.rb +0 -141
- data/lib/mutant/matcher/object_space.rb +0 -114
- data/lib/mutant/mutator/node/actual_arguments.rb +0 -25
- data/lib/mutant/mutator/node/default_arguments.rb +0 -25
- data/lib/mutant/mutator/node/formal_arguments_19/default_mutations.rb +0 -33
- data/lib/mutant/mutator/node/formal_arguments_19/pattern_argument_expansion.rb +0 -35
- data/lib/mutant/mutator/node/formal_arguments_19/require_defaults.rb +0 -37
- data/lib/mutant/mutator/node/formal_arguments_19.rb +0 -41
- data/lib/mutant/mutator/node/iter_19.rb +0 -27
- data/lib/mutant/mutator/node/literal/empty_array.rb +0 -26
- data/lib/mutant/mutator/node/pattern_arguments.rb +0 -41
- data/lib/mutant/mutator/node/pattern_variable.rb +0 -23
- data/lib/mutant/mutator/node/receiver_case.rb +0 -122
- data/lib/mutant/mutator/node/send/binary_operator_method.rb +0 -61
- data/lib/mutant/mutator/node/send/with_arguments.rb +0 -81
- data/lib/mutant/reporter/stats.rb +0 -120
- data/lib/mutant/strategy/rspec/example_lookup.rb +0 -163
- data/spec/integration/mutant/method_matching_spec.rb +0 -269
- data/spec/shared/method_match_behavior.rb +0 -39
- data/spec/unit/mutant/killer/fail_ques_spec.rb +0 -39
- data/spec/unit/mutant/matcher/class_methods/from_string_spec.rb +0 -49
- data/spec/unit/mutant/matcher/class_methods/parse_spec.rb +0 -12
- data/spec/unit/mutant/matcher/method/class_methods/parse_spec.rb +0 -21
- data/spec/unit/mutant/matcher/method/classifier/class_methods/run_spec.rb +0 -52
- data/spec/unit/mutant/matcher/object_space/class_methods/parse_spec.rb +0 -24
- data/spec/unit/mutant/matcher/object_space/each_spec.rb +0 -31
- data/spec/unit/mutant/mutator/node/if_statement/mutation_spec.rb +0 -60
- data/spec/unit/mutant/mutator/node/receiver_case/mutation_spec.rb +0 -27
- data/spec/unit/mutant/strategy/rspec/example_lookup/spec_file_spec.rb +0 -236
- data/spec/unit/mutant/subject/class_methods/new_spec.rb +0 -13
- data/tasks/metrics/ci.rake +0 -7
- data/tasks/metrics/flay.rake +0 -41
- data/tasks/metrics/flog.rake +0 -43
- data/tasks/metrics/heckle.rake +0 -216
- data/tasks/metrics/metric_fu.rake +0 -31
- data/tasks/metrics/reek.rake +0 -15
- data/tasks/metrics/roodi.rake +0 -15
- data/tasks/metrics/yardstick.rake +0 -23
- data/tasks/spec.rake +0 -45
- data/tasks/yard.rake +0 -9
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
module Mutant
|
|
2
|
-
class Reporter
|
|
3
|
-
|
|
4
|
-
# Stats gathered while reporter is running
|
|
5
|
-
class Stats
|
|
6
|
-
|
|
7
|
-
# Return subject count
|
|
8
|
-
#
|
|
9
|
-
# @return [Fixnum]
|
|
10
|
-
#
|
|
11
|
-
# @api private
|
|
12
|
-
#
|
|
13
|
-
attr_reader :subjects
|
|
14
|
-
|
|
15
|
-
# Return mutation count
|
|
16
|
-
#
|
|
17
|
-
# @return [Fixnum]
|
|
18
|
-
#
|
|
19
|
-
# @api private
|
|
20
|
-
#
|
|
21
|
-
attr_reader :mutations
|
|
22
|
-
|
|
23
|
-
# Return skip count
|
|
24
|
-
#
|
|
25
|
-
# @return [Fixnum]
|
|
26
|
-
#
|
|
27
|
-
# @api private
|
|
28
|
-
#
|
|
29
|
-
attr_reader :noop_fails
|
|
30
|
-
|
|
31
|
-
# Return kill count
|
|
32
|
-
#
|
|
33
|
-
# @return [Fixnum]
|
|
34
|
-
#
|
|
35
|
-
# @api private
|
|
36
|
-
#
|
|
37
|
-
attr_reader :kills
|
|
38
|
-
|
|
39
|
-
# Return mutation runtime
|
|
40
|
-
#
|
|
41
|
-
# @return [Float]
|
|
42
|
-
#
|
|
43
|
-
# @api private
|
|
44
|
-
#
|
|
45
|
-
attr_reader :time
|
|
46
|
-
|
|
47
|
-
# Initialize object
|
|
48
|
-
#
|
|
49
|
-
# @return [undefined]
|
|
50
|
-
#
|
|
51
|
-
# @api private
|
|
52
|
-
#
|
|
53
|
-
def initialize
|
|
54
|
-
@start = Time.now
|
|
55
|
-
@noop_fails = @subjects = @mutations = @kills = @time = 0
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Return runtime in seconds
|
|
59
|
-
#
|
|
60
|
-
# @return [Float]
|
|
61
|
-
#
|
|
62
|
-
# @api private
|
|
63
|
-
#
|
|
64
|
-
def runtime
|
|
65
|
-
Time.now - @start
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Count subject
|
|
69
|
-
#
|
|
70
|
-
# @return [self]
|
|
71
|
-
#
|
|
72
|
-
# @api private
|
|
73
|
-
#
|
|
74
|
-
def subject
|
|
75
|
-
@subjects +=1
|
|
76
|
-
self
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Return number of mutants alive
|
|
80
|
-
#
|
|
81
|
-
# @return [Fixnum]
|
|
82
|
-
#
|
|
83
|
-
# @api private
|
|
84
|
-
#
|
|
85
|
-
def alive
|
|
86
|
-
@mutations - @kills
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
# Count noop mutation fail
|
|
90
|
-
#
|
|
91
|
-
# @param [Killer] killer
|
|
92
|
-
#
|
|
93
|
-
# @return [self]
|
|
94
|
-
#
|
|
95
|
-
# @api private
|
|
96
|
-
#
|
|
97
|
-
def noop_fail(killer)
|
|
98
|
-
@noop_fails += 1
|
|
99
|
-
@time += killer.runtime
|
|
100
|
-
self
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# Count killer
|
|
104
|
-
#
|
|
105
|
-
# @param [Killer] killer
|
|
106
|
-
#
|
|
107
|
-
# @return [self]
|
|
108
|
-
#
|
|
109
|
-
# @api private
|
|
110
|
-
#
|
|
111
|
-
def killer(killer)
|
|
112
|
-
@mutations +=1
|
|
113
|
-
@kills +=1 unless killer.fail?
|
|
114
|
-
@time += killer.runtime
|
|
115
|
-
self
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
module Mutant
|
|
2
|
-
class Strategy
|
|
3
|
-
class Rspec
|
|
4
|
-
|
|
5
|
-
# Example lookup for rspec
|
|
6
|
-
class ExampleLookup
|
|
7
|
-
include Adamantium::Flat, Equalizer.new(:mutation)
|
|
8
|
-
|
|
9
|
-
# Perform example lookup
|
|
10
|
-
#
|
|
11
|
-
# @param [Mutation] mutation
|
|
12
|
-
#
|
|
13
|
-
# @return [Enumerable<String>]
|
|
14
|
-
#
|
|
15
|
-
# @api private
|
|
16
|
-
#
|
|
17
|
-
def self.run(mutation)
|
|
18
|
-
new(mutation).spec_files
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# Return mutation
|
|
22
|
-
#
|
|
23
|
-
# @return [Mutation]
|
|
24
|
-
#
|
|
25
|
-
# @api private
|
|
26
|
-
#
|
|
27
|
-
attr_reader :mutation
|
|
28
|
-
|
|
29
|
-
# Return spec files
|
|
30
|
-
#
|
|
31
|
-
# @return [Enumerable<String>]
|
|
32
|
-
#
|
|
33
|
-
# @api private
|
|
34
|
-
#
|
|
35
|
-
def spec_files
|
|
36
|
-
expression = glob_expression
|
|
37
|
-
files = Dir[expression]
|
|
38
|
-
|
|
39
|
-
if files.empty?
|
|
40
|
-
$stderr.puts("Spec file(s): #{expression.inspect} not found for #{mutation.identification}")
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
files
|
|
44
|
-
end
|
|
45
|
-
memoize :spec_files
|
|
46
|
-
|
|
47
|
-
private
|
|
48
|
-
|
|
49
|
-
# Return method matcher
|
|
50
|
-
#
|
|
51
|
-
# @return [Matcher]
|
|
52
|
-
#
|
|
53
|
-
# @api private
|
|
54
|
-
#
|
|
55
|
-
def matcher
|
|
56
|
-
mutation.subject.matcher
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
EXPANSIONS = {
|
|
60
|
-
/\?\z/ => '_predicate',
|
|
61
|
-
/=\z/ => '_writer',
|
|
62
|
-
/!\z/ => '_bang'
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
# Return spec file
|
|
66
|
-
#
|
|
67
|
-
# @return [String]
|
|
68
|
-
#
|
|
69
|
-
# @api private
|
|
70
|
-
#
|
|
71
|
-
def spec_file
|
|
72
|
-
"#{mapped_name || expanded_name}_spec.rb"
|
|
73
|
-
end
|
|
74
|
-
memoize :spec_file
|
|
75
|
-
|
|
76
|
-
# Return mapped name
|
|
77
|
-
#
|
|
78
|
-
# @return [Symbol]
|
|
79
|
-
# if name was mapped
|
|
80
|
-
#
|
|
81
|
-
# @return [nil]
|
|
82
|
-
# otherwise
|
|
83
|
-
#
|
|
84
|
-
# @api private
|
|
85
|
-
#
|
|
86
|
-
def mapped_name
|
|
87
|
-
OPERATOR_EXPANSIONS[method_name]
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# Return expanded name
|
|
91
|
-
#
|
|
92
|
-
# @return [Symbol]
|
|
93
|
-
#
|
|
94
|
-
# @api private
|
|
95
|
-
#
|
|
96
|
-
def expanded_name
|
|
97
|
-
EXPANSIONS.inject(method_name) do |name, (regexp, expansion)|
|
|
98
|
-
name.to_s.gsub(regexp, expansion)
|
|
99
|
-
end.to_sym
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# Return method name
|
|
103
|
-
#
|
|
104
|
-
# @return [Symbol]
|
|
105
|
-
#
|
|
106
|
-
# @api private
|
|
107
|
-
#
|
|
108
|
-
def method_name
|
|
109
|
-
matcher.method_name
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
# Return glob expression
|
|
113
|
-
#
|
|
114
|
-
# @return [String]
|
|
115
|
-
#
|
|
116
|
-
# @api private
|
|
117
|
-
#
|
|
118
|
-
def glob_expression
|
|
119
|
-
base = base_path
|
|
120
|
-
|
|
121
|
-
if mutation.subject.matcher.public?
|
|
122
|
-
"#{base}/#{spec_file}"
|
|
123
|
-
else
|
|
124
|
-
"#{base}/*_spec.rb"
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# Return instance of singleton path appendo
|
|
129
|
-
#
|
|
130
|
-
# @return [String]
|
|
131
|
-
#
|
|
132
|
-
# @api private
|
|
133
|
-
#
|
|
134
|
-
def scope_append
|
|
135
|
-
matcher.kind_of?(Matcher::Method::Singleton) ? '/class_methods' : ''
|
|
136
|
-
end
|
|
137
|
-
memoize :scope_append
|
|
138
|
-
|
|
139
|
-
# Return base path
|
|
140
|
-
#
|
|
141
|
-
# @return [String]
|
|
142
|
-
#
|
|
143
|
-
# @api private
|
|
144
|
-
#
|
|
145
|
-
def base_path
|
|
146
|
-
"spec/unit/#{Inflecto.underscore(mutation.subject.context.scope.name)}#{scope_append}"
|
|
147
|
-
end
|
|
148
|
-
memoize :base_path
|
|
149
|
-
|
|
150
|
-
# Initalize object
|
|
151
|
-
#
|
|
152
|
-
# @param [Mutation] mutation
|
|
153
|
-
#
|
|
154
|
-
# @api private
|
|
155
|
-
#
|
|
156
|
-
def initialize(mutation)
|
|
157
|
-
@mutation = mutation
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
end
|
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Mutant, 'method matching' do
|
|
4
|
-
after do
|
|
5
|
-
if defined?(::Foo)
|
|
6
|
-
Object.send(:remove_const, 'Foo')
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
before do
|
|
11
|
-
#eval(body, TOPLEVEL_BINDING, __FILE__, 0)
|
|
12
|
-
eval(body)
|
|
13
|
-
File.stub(:read => body)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
let(:defaults) { {} }
|
|
17
|
-
|
|
18
|
-
context 'on instance methods' do
|
|
19
|
-
def name(node)
|
|
20
|
-
node.name
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def arguments(node)
|
|
24
|
-
node.arguments
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
let(:pattern) { 'Foo#bar' }
|
|
28
|
-
let(:defaults) do
|
|
29
|
-
{
|
|
30
|
-
:scope => Foo,
|
|
31
|
-
:node_class => Rubinius::AST::Define,
|
|
32
|
-
:method_name => :bar,
|
|
33
|
-
:method_arity => 0
|
|
34
|
-
}
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
context 'when method is defined once' do
|
|
38
|
-
let(:body) do
|
|
39
|
-
<<-RUBY
|
|
40
|
-
class Foo
|
|
41
|
-
def bar; end
|
|
42
|
-
end
|
|
43
|
-
RUBY
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
let(:expectation) do
|
|
47
|
-
{ :method_line => 2 }
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it_should_behave_like 'a method match'
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
context 'when method is defined multiple times' do
|
|
54
|
-
context 'on differend lines' do
|
|
55
|
-
let(:body) do
|
|
56
|
-
<<-RUBY
|
|
57
|
-
class Foo
|
|
58
|
-
def bar; end
|
|
59
|
-
def bar(arg); end
|
|
60
|
-
end
|
|
61
|
-
RUBY
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
let(:expectation) do
|
|
65
|
-
{
|
|
66
|
-
:method_line => 3,
|
|
67
|
-
:method_arity => 1
|
|
68
|
-
}
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
it_should_behave_like 'a method match'
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
context 'on the same line' do
|
|
75
|
-
let(:body) do
|
|
76
|
-
<<-RUBY
|
|
77
|
-
class Foo
|
|
78
|
-
def bar; end; def bar(arg); end
|
|
79
|
-
end
|
|
80
|
-
RUBY
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
let(:expectation) do
|
|
84
|
-
{
|
|
85
|
-
:method_line => 2,
|
|
86
|
-
:method_arity => 1
|
|
87
|
-
}
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
it_should_behave_like 'a method match'
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
context 'on the same line with differend scope' do
|
|
94
|
-
let(:body) do
|
|
95
|
-
<<-RUBY
|
|
96
|
-
class Foo
|
|
97
|
-
def self.bar; end; def bar(arg); end
|
|
98
|
-
end
|
|
99
|
-
RUBY
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
let(:expectation) do
|
|
103
|
-
{
|
|
104
|
-
:method_line => 2,
|
|
105
|
-
:method_arity => 1
|
|
106
|
-
}
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
it_should_behave_like 'a method match'
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
context 'when nested' do
|
|
113
|
-
let(:pattern) { 'Foo::Bar#baz' }
|
|
114
|
-
|
|
115
|
-
context 'in class' do
|
|
116
|
-
let(:body) do
|
|
117
|
-
<<-RUBY
|
|
118
|
-
class Foo
|
|
119
|
-
class Bar
|
|
120
|
-
def baz; end
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
RUBY
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
let(:expectation) do
|
|
127
|
-
{
|
|
128
|
-
:method_line => 3,
|
|
129
|
-
:method_name => :baz,
|
|
130
|
-
:scope => Foo::Bar
|
|
131
|
-
}
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
it_should_behave_like 'a method match'
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
context 'in module' do
|
|
138
|
-
let(:body) do
|
|
139
|
-
<<-RUBY
|
|
140
|
-
module Foo
|
|
141
|
-
class Bar
|
|
142
|
-
def baz; end
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
RUBY
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
let(:expectation) do
|
|
149
|
-
{
|
|
150
|
-
:method_line => 3,
|
|
151
|
-
:method_name => :baz,
|
|
152
|
-
:scope => Foo::Bar
|
|
153
|
-
}
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
it_should_behave_like 'a method match'
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
context 'on singleton methods' do
|
|
163
|
-
let(:pattern) { 'Foo.bar' }
|
|
164
|
-
let(:defaults) do
|
|
165
|
-
{
|
|
166
|
-
:scope => Foo,
|
|
167
|
-
:node_class => Rubinius::AST::DefineSingleton,
|
|
168
|
-
:method_arity => 0
|
|
169
|
-
}
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
def name(node)
|
|
173
|
-
node.body.name
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def arguments(node)
|
|
177
|
-
node.body.arguments
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
context 'when defined on self' do
|
|
181
|
-
let(:body) do
|
|
182
|
-
<<-RUBY
|
|
183
|
-
class Foo
|
|
184
|
-
def self.bar; end
|
|
185
|
-
end
|
|
186
|
-
RUBY
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
let(:expectation) do
|
|
191
|
-
{
|
|
192
|
-
:method_name => :bar,
|
|
193
|
-
:method_line => 2,
|
|
194
|
-
}
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
it_should_behave_like 'a method match'
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
context 'when defined on constant' do
|
|
201
|
-
|
|
202
|
-
context 'inside namespace' do
|
|
203
|
-
let(:body) do
|
|
204
|
-
<<-RUBY
|
|
205
|
-
class Foo
|
|
206
|
-
def Foo.bar; end
|
|
207
|
-
end
|
|
208
|
-
RUBY
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
let(:expectation) do
|
|
213
|
-
{
|
|
214
|
-
:method_name => :bar,
|
|
215
|
-
:method_line => 2,
|
|
216
|
-
}
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
it_should_behave_like 'a method match'
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
context 'outside namespace' do
|
|
223
|
-
let(:body) do
|
|
224
|
-
<<-RUBY
|
|
225
|
-
class Foo; end;
|
|
226
|
-
def Foo.bar; end
|
|
227
|
-
RUBY
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
let(:expectation) do
|
|
232
|
-
{
|
|
233
|
-
:method_name => :bar,
|
|
234
|
-
:method_line => 2,
|
|
235
|
-
}
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
it_should_behave_like 'a method match'
|
|
239
|
-
end
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
context 'when defined multiple times in the same line' do
|
|
243
|
-
context 'with method on differend scope' do
|
|
244
|
-
let(:body) do
|
|
245
|
-
<<-RUBY
|
|
246
|
-
module Foo; end
|
|
247
|
-
|
|
248
|
-
module Bar
|
|
249
|
-
def self.baz; end; def Foo.baz(arg); end
|
|
250
|
-
end
|
|
251
|
-
RUBY
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
let(:pattern) { 'Bar.baz' }
|
|
255
|
-
|
|
256
|
-
let(:expectation) do
|
|
257
|
-
{
|
|
258
|
-
:scope => Bar,
|
|
259
|
-
:method_name => :baz,
|
|
260
|
-
:method_line => 4,
|
|
261
|
-
:method_arity => 0
|
|
262
|
-
}
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
it_should_behave_like 'a method match'
|
|
266
|
-
end
|
|
267
|
-
end
|
|
268
|
-
end
|
|
269
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
shared_examples_for 'a method match' do
|
|
2
|
-
subject { Mutant::Matcher::Method.parse(pattern).to_a }
|
|
3
|
-
|
|
4
|
-
let(:values) { defaults.merge(expectation) }
|
|
5
|
-
|
|
6
|
-
let(:method_name) { values.fetch(:method_name) }
|
|
7
|
-
let(:method_line) { values.fetch(:method_line) }
|
|
8
|
-
let(:method_arity) { values.fetch(:method_arity) }
|
|
9
|
-
let(:scope) { values.fetch(:scope) }
|
|
10
|
-
let(:node_class) { values.fetch(:node_class) }
|
|
11
|
-
|
|
12
|
-
let(:node) { mutation_subject.node }
|
|
13
|
-
let(:context) { mutation_subject.context }
|
|
14
|
-
let(:mutation_subject) { subject.first }
|
|
15
|
-
|
|
16
|
-
it 'should return one subject' do
|
|
17
|
-
subject.size.should be(1)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it 'should have correct method name' do
|
|
21
|
-
name(node).should eql(method_name)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it 'should have correct line number' do
|
|
25
|
-
node.line.should eql(method_line)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it 'should have correct arity' do
|
|
29
|
-
arguments(node).required.length.should eql(method_arity)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it 'should have correct scope in context' do
|
|
33
|
-
context.send(:scope).should eql(scope)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it 'should have the correct node class' do
|
|
37
|
-
node.should be_a(node_class)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Mutant::Killer,'#fail?' do
|
|
4
|
-
subject { object.fail? }
|
|
5
|
-
|
|
6
|
-
let(:object) { class_under_test.new(strategy, mutation) }
|
|
7
|
-
let(:strategy) { mock('Strategy') }
|
|
8
|
-
let(:mutation) { mock('Mutation') }
|
|
9
|
-
|
|
10
|
-
before do
|
|
11
|
-
mutation.stub(:insert)
|
|
12
|
-
mutation.stub(:reset)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
let(:class_under_test) do
|
|
16
|
-
kill_state = self.kill_state
|
|
17
|
-
Class.new(described_class) do
|
|
18
|
-
define_method :run do
|
|
19
|
-
kill_state
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
context 'when mutant was killed' do
|
|
25
|
-
let(:kill_state) { true }
|
|
26
|
-
|
|
27
|
-
it_should_behave_like 'an idempotent method'
|
|
28
|
-
|
|
29
|
-
it { should be(false) }
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
context 'when mutant was NOT killed' do
|
|
33
|
-
let(:kill_state) { false }
|
|
34
|
-
|
|
35
|
-
it_should_behave_like 'an idempotent method'
|
|
36
|
-
|
|
37
|
-
it { should be(true) }
|
|
38
|
-
end
|
|
39
|
-
end
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Mutant::Matcher, '.from_string' do
|
|
4
|
-
subject { object.from_string(input) }
|
|
5
|
-
|
|
6
|
-
let(:input) { mock('Input') }
|
|
7
|
-
let(:matcher) { mock('Matcher') }
|
|
8
|
-
|
|
9
|
-
let(:descendant_a) { mock('Descendant A', :parse => nil) }
|
|
10
|
-
let(:descendant_b) { mock('Descendant B', :parse => nil) }
|
|
11
|
-
|
|
12
|
-
let(:object) { described_class }
|
|
13
|
-
|
|
14
|
-
before do
|
|
15
|
-
described_class.stub(:descendants => [descendant_a, descendant_b])
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
context 'when no descendant takes the input' do
|
|
19
|
-
it { should be(nil) }
|
|
20
|
-
|
|
21
|
-
it_should_behave_like 'an idempotent method'
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
context 'when one descendant handles input' do
|
|
25
|
-
before do
|
|
26
|
-
descendant_a.stub(:parse => matcher)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it { should be(matcher) }
|
|
30
|
-
|
|
31
|
-
it_should_behave_like 'an idempotent method'
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
context 'when more than one descendant handles input' do
|
|
35
|
-
let(:matcher_b) { mock('Matcher B') }
|
|
36
|
-
|
|
37
|
-
before do
|
|
38
|
-
descendant_a.stub(:parse => matcher)
|
|
39
|
-
descendant_b.stub(:parse => matcher_b)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it 'should return the first matcher' do
|
|
43
|
-
should be(matcher)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it_should_behave_like 'an idempotent method'
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Mutant::Matcher::Method, '.parse' do
|
|
4
|
-
subject { described_class.parse(input) }
|
|
5
|
-
|
|
6
|
-
let(:response) { mock('Response') }
|
|
7
|
-
let(:input) { mock('Input') }
|
|
8
|
-
|
|
9
|
-
let(:classifier) { described_class::Classifier }
|
|
10
|
-
|
|
11
|
-
before do
|
|
12
|
-
classifier.stub(:run => response)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it { should be(response) }
|
|
16
|
-
|
|
17
|
-
it 'should call classifier' do
|
|
18
|
-
classifier.should_receive(:run).with(input).and_return(response)
|
|
19
|
-
subject
|
|
20
|
-
end
|
|
21
|
-
end
|