mutant 0.3.0.rc1 → 0.3.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/.travis.yml +5 -4
- data/Gemfile.devtools +4 -4
- data/Guardfile +7 -5
- data/README.md +8 -8
- data/config/flay.yml +2 -2
- data/config/reek.yml +1 -0
- data/config/rubocop.yml +0 -4
- data/lib/mutant/cli/builder.rb +177 -0
- data/lib/mutant/cli/classifier/method.rb +10 -14
- data/lib/mutant/cli/classifier/namespace.rb +7 -9
- data/lib/mutant/cli/classifier.rb +29 -31
- data/lib/mutant/cli.rb +34 -96
- data/lib/mutant/color.rb +1 -1
- data/lib/mutant/config.rb +9 -3
- data/lib/mutant/constants.rb +1 -1
- data/lib/mutant/context/scope.rb +2 -2
- data/lib/mutant/differ.rb +0 -1
- data/lib/mutant/killer/rspec.rb +3 -8
- data/lib/mutant/killer.rb +1 -22
- data/lib/mutant/matcher/chain.rb +2 -2
- data/lib/mutant/matcher/filter.rb +32 -0
- data/lib/mutant/matcher/method/instance.rb +2 -2
- data/lib/mutant/matcher/method.rb +3 -3
- data/lib/mutant/matcher/methods.rb +1 -1
- data/lib/mutant/matcher.rb +1 -0
- data/lib/mutant/mutation/evil.rb +0 -10
- data/lib/mutant/mutation/neutral.rb +0 -23
- data/lib/mutant/mutation.rb +13 -23
- data/lib/mutant/mutator/node/begin.rb +12 -10
- data/lib/mutant/mutator/node/block.rb +1 -0
- data/lib/mutant/mutator/node/blockarg.rb +15 -0
- data/lib/mutant/mutator/node/case.rb +1 -0
- data/lib/mutant/mutator/node/connective/binary.rb +2 -2
- data/lib/mutant/mutator/node/const.rb +2 -1
- data/lib/mutant/mutator/node/dstr.rb +28 -0
- data/lib/mutant/mutator/node/dsym.rb +28 -0
- data/lib/mutant/mutator/node/generic.rb +3 -4
- data/lib/mutant/mutator/node/if.rb +1 -0
- data/lib/mutant/mutator/node/literal/boolean.rb +2 -2
- data/lib/mutant/mutator/node/literal/range.rb +8 -6
- data/lib/mutant/mutator/node/literal.rb +0 -17
- data/lib/mutant/mutator/node/masgn.rb +1 -1
- data/lib/mutant/mutator/node/named_value/variable_assignment.rb +5 -4
- data/lib/mutant/mutator/node/op_asgn.rb +30 -0
- data/lib/mutant/mutator/node/restarg.rb +15 -0
- data/lib/mutant/mutator/node/return.rb +1 -2
- data/lib/mutant/mutator/node/send.rb +6 -5
- data/lib/mutant/mutator/node/super.rb +1 -0
- data/lib/mutant/mutator/node/while.rb +1 -0
- data/lib/mutant/mutator/node.rb +11 -1
- data/lib/mutant/node_helpers.rb +3 -3
- data/lib/mutant/predicate/attribute.rb +85 -0
- data/lib/mutant/predicate/blacklist.rb +27 -0
- data/lib/mutant/predicate/matcher.rb +36 -0
- data/lib/mutant/predicate/whitelist.rb +28 -0
- data/lib/mutant/predicate.rb +91 -0
- data/lib/mutant/reporter/cli/printer/config.rb +3 -3
- data/lib/mutant/reporter/cli/printer/killer.rb +1 -1
- data/lib/mutant/reporter/cli/printer/mutation.rb +12 -14
- data/lib/mutant/reporter/cli/printer/subject.rb +1 -3
- data/lib/mutant/reporter/cli/printer.rb +31 -7
- data/lib/mutant/runner/mutation.rb +9 -1
- data/lib/mutant/runner/subject.rb +9 -1
- data/lib/mutant/runner.rb +5 -6
- data/lib/mutant/strategy/rspec.rb +4 -4
- data/lib/mutant/strategy.rb +2 -0
- data/lib/mutant/support/method_object.rb +0 -1
- data/lib/mutant/version.rb +1 -2
- data/lib/mutant/zombifier.rb +6 -3
- data/lib/mutant.rb +12 -4
- data/mutant.gemspec +7 -7
- data/spec/integration/mutant/rspec_spec.rb +12 -5
- data/spec/shared/mutator_behavior.rb +2 -1
- data/spec/spec_helper.rb +11 -9
- data/spec/unit/mutant/cli/builder/rspec_spec.rb +38 -0
- data/spec/unit/mutant/cli/classifier/{method/each_spec.rb → method_spec.rb} +2 -14
- data/spec/unit/mutant/cli/classifier/namespace/{flat/each_spec.rb → flat_spec.rb} +1 -1
- data/spec/unit/mutant/cli/classifier/namespace/{recursive/each_spec.rb → recursive_spec.rb} +1 -1
- data/spec/unit/mutant/cli/classifier_spec.rb +59 -0
- data/spec/unit/mutant/{cli/class_methods/new_spec.rb → cli_new_spec.rb} +22 -23
- data/spec/unit/mutant/{cli/class_methods/run_spec.rb → cli_run_spec.rb} +8 -8
- data/spec/unit/mutant/killer/rspec/class_methods/new_spec.rb +6 -6
- data/spec/unit/mutant/killer/success_predicate_spec.rb +5 -5
- data/spec/unit/mutant/loader/eval/class_methods/run_spec.rb +1 -1
- data/spec/unit/mutant/matcher/filter_spec.rb +19 -0
- data/spec/unit/mutant/matcher/namespace/each_spec.rb +5 -5
- data/spec/unit/mutant/mutation_spec.rb +42 -0
- data/spec/unit/mutant/mutator/each_spec.rb +1 -1
- data/spec/unit/mutant/mutator/node/and_asgn/mutation_spec.rb +3 -2
- data/spec/unit/mutant/mutator/node/block/mutation_spec.rb +7 -2
- data/spec/unit/mutant/mutator/node/block_pass/mutation_spec.rb +1 -0
- data/spec/unit/mutant/mutator/node/blockarg/mutation_spec.rb +17 -0
- data/spec/unit/mutant/mutator/node/case/mutation_spec.rb +5 -1
- data/spec/unit/mutant/mutator/node/cbase/mutation_spec.rb +1 -0
- data/spec/unit/mutant/mutator/node/const/mutation_spec.rb +3 -2
- data/spec/unit/mutant/mutator/node/define/mutation_spec.rb +3 -3
- data/spec/unit/mutant/mutator/node/defined_predicate/mutation_spec.rb +6 -2
- data/spec/unit/mutant/mutator/node/dstr/mutation_spec.rb +4 -2
- data/spec/unit/mutant/mutator/node/dsym/mutation_spec.rb +4 -2
- data/spec/unit/mutant/mutator/node/if/mutation_spec.rb +6 -1
- data/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb +1 -1
- data/spec/unit/mutant/mutator/node/literal/float_spec.rb +1 -1
- data/spec/unit/mutant/mutator/node/literal/range_spec.rb +31 -0
- data/spec/unit/mutant/mutator/node/literal/regex_spec.rb +4 -2
- data/spec/unit/mutant/mutator/node/literal/string_spec.rb +1 -1
- data/spec/unit/mutant/mutator/node/literal/symbol_spec.rb +1 -1
- data/spec/unit/mutant/mutator/node/masgn/mutation_spec.rb +6 -2
- data/spec/unit/mutant/mutator/node/match_current_line/mutation_spec.rb +1 -0
- data/spec/unit/mutant/mutator/node/named_value/access/mutation_spec.rb +5 -1
- data/spec/unit/mutant/mutator/node/named_value/constant_assignment/mutation_spec.rb +1 -2
- data/spec/unit/mutant/mutator/node/named_value/variable_assignment/mutation_spec.rb +5 -5
- data/spec/unit/mutant/mutator/node/op_assgn/mutation_spec.rb +3 -2
- data/spec/unit/mutant/mutator/node/or_asgn/mutation_spec.rb +3 -2
- data/spec/unit/mutant/mutator/node/rescue/mutation_spec.rb +1 -1
- data/spec/unit/mutant/mutator/node/restarg/mutation_spec.rb +3 -1
- data/spec/unit/mutant/mutator/node/return/mutation_spec.rb +7 -3
- data/spec/unit/mutant/mutator/node/send/mutation_spec.rb +37 -2
- data/spec/unit/mutant/mutator/node/super/mutation_spec.rb +4 -0
- data/spec/unit/mutant/mutator/node/while/mutation_spec.rb +3 -0
- data/spec/unit/mutant/predicate_spec.rb +135 -0
- data/spec/unit/mutant/runner/config/subjects_spec.rb +11 -11
- data/spec/unit/mutant/runner/config/success_predicate_spec.rb +6 -6
- data/spec/unit/mutant/runner/mutation/killer_spec.rb +11 -11
- data/spec/unit/mutant/runner/subject/success_predicate_spec.rb +9 -9
- data/spec/unit/mutant/strategy_spec.rb +21 -0
- data/spec/unit/mutant/subject_spec.rb +39 -0
- data/test_app/spec/shared/method_filter_parse_behavior.rb +1 -1
- metadata +54 -36
- data/lib/mutant/cli/classifier/scope.rb +0 -37
- data/lib/mutant/mutation/filter/code.rb +0 -49
- data/lib/mutant/mutation/filter/regexp.rb +0 -29
- data/lib/mutant/mutation/filter/whitelist.rb +0 -52
- data/lib/mutant/mutation/filter.rb +0 -78
- data/lib/mutant/strategy/static.rb +0 -20
- data/spec/unit/mutant/cli/classifier/class_methods/build_spec.rb +0 -48
- data/spec/unit/mutant/cli/classifier/scope/each_spec.rb +0 -33
@@ -20,14 +20,7 @@ module Mutant
|
|
20
20
|
#
|
21
21
|
def self.build(runner, output)
|
22
22
|
mutation = runner.mutation
|
23
|
-
|
24
|
-
when Mutant::Mutation::Neutral::Noop
|
25
|
-
Noop
|
26
|
-
when Mutant::Mutation::Evil, Mutant::Mutation::Neutral
|
27
|
-
Diff
|
28
|
-
else
|
29
|
-
raise "Unknown mutation: #{mutation}"
|
30
|
-
end.new(runner, output)
|
23
|
+
lookup(mutation.class).new(runner, output)
|
31
24
|
end
|
32
25
|
|
33
26
|
# Run mutation printer
|
@@ -56,12 +49,14 @@ module Mutant
|
|
56
49
|
# Reporter for noop mutations
|
57
50
|
class Noop < self
|
58
51
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
52
|
+
handle(Mutant::Mutation::Neutral::Noop)
|
53
|
+
|
54
|
+
MESSAGE = [
|
55
|
+
'Parsed subject AST:',
|
56
|
+
'%s',
|
57
|
+
'Unparsed source:',
|
58
|
+
'%s',
|
59
|
+
].join("\n")
|
65
60
|
|
66
61
|
private
|
67
62
|
|
@@ -84,6 +79,9 @@ module Mutant
|
|
84
79
|
# Reporter for neutral and evil mutations
|
85
80
|
class Diff < self
|
86
81
|
|
82
|
+
handle(Mutant::Mutation::Neutral)
|
83
|
+
handle(Mutant::Mutation::Evil)
|
84
|
+
|
87
85
|
# Return diff
|
88
86
|
#
|
89
87
|
# @return [String]
|
@@ -8,9 +8,7 @@ module Mutant
|
|
8
8
|
# Subject results printer
|
9
9
|
class Subject < self
|
10
10
|
|
11
|
-
handle(Mutant::Subject
|
12
|
-
handle(Mutant::Subject::Method::Instance::Memoized)
|
13
|
-
handle(Mutant::Subject::Method::Singleton)
|
11
|
+
handle(Mutant::Subject)
|
14
12
|
|
15
13
|
# Run subject results printer
|
16
14
|
#
|
@@ -63,10 +63,34 @@ module Mutant
|
|
63
63
|
# @api private
|
64
64
|
#
|
65
65
|
def self.visit(object, output)
|
66
|
-
printer =
|
66
|
+
printer = lookup(object.class)
|
67
67
|
printer.run(object, output)
|
68
68
|
end
|
69
69
|
|
70
|
+
# Lookup printer class
|
71
|
+
#
|
72
|
+
# @param [Class] klass
|
73
|
+
#
|
74
|
+
# @return [Class:Printer]
|
75
|
+
# if found
|
76
|
+
#
|
77
|
+
# @raise [RuntimeError]
|
78
|
+
# otherwise
|
79
|
+
#
|
80
|
+
# @api private
|
81
|
+
#
|
82
|
+
def self.lookup(klass)
|
83
|
+
current = klass
|
84
|
+
until current == Object
|
85
|
+
if REGISTRY.key?(current)
|
86
|
+
return REGISTRY.fetch(current)
|
87
|
+
end
|
88
|
+
current = current.superclass
|
89
|
+
end
|
90
|
+
raise "No printer for: #{klass}"
|
91
|
+
end
|
92
|
+
private_class_method :lookup
|
93
|
+
|
70
94
|
abstract_method :run
|
71
95
|
|
72
96
|
private
|
@@ -140,10 +164,10 @@ module Mutant
|
|
140
164
|
# Test for colored output
|
141
165
|
#
|
142
166
|
# @return [true]
|
143
|
-
#
|
167
|
+
# if output is colored
|
144
168
|
#
|
145
169
|
# @return [false]
|
146
|
-
#
|
170
|
+
# otherwise
|
147
171
|
#
|
148
172
|
# @api private
|
149
173
|
#
|
@@ -159,8 +183,8 @@ module Mutant
|
|
159
183
|
# @api private
|
160
184
|
#
|
161
185
|
# @return [String]
|
162
|
-
#
|
163
|
-
#
|
186
|
+
# if color is enabled
|
187
|
+
# unmodified message otherwise
|
164
188
|
#
|
165
189
|
def colorize(color, message)
|
166
190
|
color = Color::NONE unless tty?
|
@@ -170,10 +194,10 @@ module Mutant
|
|
170
194
|
# Test for output to tty
|
171
195
|
#
|
172
196
|
# @return [true]
|
173
|
-
#
|
197
|
+
# if output is a tty
|
174
198
|
#
|
175
199
|
# @return [false]
|
176
|
-
#
|
200
|
+
# otherwise
|
177
201
|
#
|
178
202
|
# @api private
|
179
203
|
#
|
@@ -4,10 +4,18 @@ module Mutant
|
|
4
4
|
class Runner
|
5
5
|
# Mutation runner
|
6
6
|
class Mutation < self
|
7
|
-
include
|
7
|
+
include Equalizer.new(:config, :mutation)
|
8
8
|
|
9
9
|
register Mutant::Mutation
|
10
10
|
|
11
|
+
# Return mutation
|
12
|
+
#
|
13
|
+
# @return [Mutation]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
#
|
17
|
+
attr_reader :mutation
|
18
|
+
|
11
19
|
# Return killer instance
|
12
20
|
#
|
13
21
|
# @return [Killer]
|
@@ -4,7 +4,15 @@ module Mutant
|
|
4
4
|
class Runner
|
5
5
|
# Subject specific runner
|
6
6
|
class Subject < self
|
7
|
-
include
|
7
|
+
include Equalizer.new(:config, :subject)
|
8
|
+
|
9
|
+
# Return subject
|
10
|
+
#
|
11
|
+
# @return [Subject]
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
#
|
15
|
+
attr_reader :subject
|
8
16
|
|
9
17
|
register Mutant::Subject
|
10
18
|
|
data/lib/mutant/runner.rb
CHANGED
@@ -71,7 +71,8 @@ module Mutant
|
|
71
71
|
#
|
72
72
|
def initialize(config)
|
73
73
|
@config = config
|
74
|
-
@
|
74
|
+
@stop = false
|
75
|
+
@start = Time.now
|
75
76
|
run
|
76
77
|
@end = Time.now
|
77
78
|
end
|
@@ -87,7 +88,7 @@ module Mutant
|
|
87
88
|
# @api private
|
88
89
|
#
|
89
90
|
def stop?
|
90
|
-
|
91
|
+
@stop
|
91
92
|
end
|
92
93
|
|
93
94
|
# Return runtime
|
@@ -155,10 +156,8 @@ module Mutant
|
|
155
156
|
input.each do |object|
|
156
157
|
runner = visit(object)
|
157
158
|
collection << runner
|
158
|
-
|
159
|
-
|
160
|
-
break
|
161
|
-
end
|
159
|
+
@stop = runner.stop?
|
160
|
+
break if @stop
|
162
161
|
end
|
163
162
|
collection
|
164
163
|
end
|
@@ -4,7 +4,7 @@ module Mutant
|
|
4
4
|
class Strategy
|
5
5
|
# Rspec killer strategy
|
6
6
|
class Rspec < self
|
7
|
-
include
|
7
|
+
include Concord.new(:level)
|
8
8
|
|
9
9
|
KILLER = Killer::Forking.new(Killer::Rspec)
|
10
10
|
|
@@ -33,7 +33,7 @@ module Mutant
|
|
33
33
|
def configuration
|
34
34
|
RSpec::Core::Configuration.new
|
35
35
|
end
|
36
|
-
memoize :configuration, :
|
36
|
+
memoize :configuration, freezer: :noop
|
37
37
|
|
38
38
|
# Return example groups
|
39
39
|
#
|
@@ -56,7 +56,7 @@ module Mutant
|
|
56
56
|
def world
|
57
57
|
RSpec.world
|
58
58
|
end
|
59
|
-
memoize :world, :
|
59
|
+
memoize :world, freezer: :noop
|
60
60
|
|
61
61
|
# Return options
|
62
62
|
#
|
@@ -69,7 +69,7 @@ module Mutant
|
|
69
69
|
options.parse_options
|
70
70
|
options
|
71
71
|
end
|
72
|
-
memoize :options, :
|
72
|
+
memoize :options, freezer: :noop
|
73
73
|
|
74
74
|
end # Rspec
|
75
75
|
end # Strategy
|
data/lib/mutant/strategy.rb
CHANGED
data/lib/mutant/version.rb
CHANGED
data/lib/mutant/zombifier.rb
CHANGED
@@ -11,7 +11,7 @@ module Mutant
|
|
11
11
|
# * Toplevel reference/cbase nodes in code (rspec)
|
12
12
|
# * Creates useless toplevel modules that get vendored under ::Zombie (set)
|
13
13
|
#
|
14
|
-
|
14
|
+
IGNORE = %w(
|
15
15
|
set
|
16
16
|
rspec
|
17
17
|
diff/lcs
|
@@ -31,6 +31,7 @@ module Mutant
|
|
31
31
|
#
|
32
32
|
def self.zombify
|
33
33
|
run('mutant')
|
34
|
+
self
|
34
35
|
end
|
35
36
|
|
36
37
|
# Zombify gem
|
@@ -43,6 +44,7 @@ module Mutant
|
|
43
44
|
#
|
44
45
|
def self.run(name)
|
45
46
|
Gem.new(name).zombify
|
47
|
+
self
|
46
48
|
end
|
47
49
|
|
48
50
|
# Zombifier subject, compatible with mutants loader
|
@@ -68,7 +70,7 @@ module Mutant
|
|
68
70
|
# @api private
|
69
71
|
#
|
70
72
|
def zombify
|
71
|
-
$stderr.puts
|
73
|
+
$stderr.puts("Zombifying #{context.source_path}")
|
72
74
|
Loader::Eval.run(zombified_root, self)
|
73
75
|
self
|
74
76
|
end
|
@@ -109,6 +111,7 @@ module Mutant
|
|
109
111
|
end
|
110
112
|
self
|
111
113
|
end
|
114
|
+
memoize :zombify
|
112
115
|
|
113
116
|
# Find file
|
114
117
|
#
|
@@ -123,7 +126,7 @@ module Mutant
|
|
123
126
|
# @api private
|
124
127
|
#
|
125
128
|
def self.find(logical_name)
|
126
|
-
return if
|
129
|
+
return if IGNORE.include?(logical_name)
|
127
130
|
CACHE.fetch(logical_name) do
|
128
131
|
CACHE[logical_name] = find_uncached(logical_name)
|
129
132
|
end
|
data/lib/mutant.rb
CHANGED
@@ -34,13 +34,15 @@ require 'mutant/singleton_methods'
|
|
34
34
|
require 'mutant/constants'
|
35
35
|
require 'mutant/support/method_object'
|
36
36
|
require 'mutant/random'
|
37
|
+
require 'mutant/predicate'
|
38
|
+
require 'mutant/predicate/attribute'
|
39
|
+
require 'mutant/predicate/whitelist'
|
40
|
+
require 'mutant/predicate/blacklist'
|
41
|
+
require 'mutant/predicate/matcher'
|
37
42
|
require 'mutant/mutator'
|
38
43
|
require 'mutant/mutation'
|
39
44
|
require 'mutant/mutation/evil'
|
40
45
|
require 'mutant/mutation/neutral'
|
41
|
-
require 'mutant/mutation/filter'
|
42
|
-
require 'mutant/mutation/filter/code'
|
43
|
-
require 'mutant/mutation/filter/whitelist'
|
44
46
|
require 'mutant/mutator/registry'
|
45
47
|
require 'mutant/mutator/util'
|
46
48
|
require 'mutant/mutator/util/array'
|
@@ -60,16 +62,21 @@ require 'mutant/mutator/node/literal/regex'
|
|
60
62
|
require 'mutant/mutator/node/literal/nil'
|
61
63
|
require 'mutant/mutator/node/argument'
|
62
64
|
require 'mutant/mutator/node/arguments'
|
65
|
+
require 'mutant/mutator/node/blockarg'
|
63
66
|
require 'mutant/mutator/node/begin'
|
64
67
|
require 'mutant/mutator/node/connective/binary'
|
65
68
|
require 'mutant/mutator/node/const'
|
69
|
+
require 'mutant/mutator/node/dstr'
|
70
|
+
require 'mutant/mutator/node/dsym'
|
66
71
|
require 'mutant/mutator/node/named_value/access'
|
67
72
|
require 'mutant/mutator/node/named_value/constant_assignment'
|
68
73
|
require 'mutant/mutator/node/named_value/variable_assignment'
|
69
74
|
require 'mutant/mutator/node/noop'
|
75
|
+
require 'mutant/mutator/node/op_asgn'
|
70
76
|
require 'mutant/mutator/node/while'
|
71
77
|
require 'mutant/mutator/node/super'
|
72
78
|
require 'mutant/mutator/node/zsuper'
|
79
|
+
require 'mutant/mutator/node/restarg'
|
73
80
|
require 'mutant/mutator/node/send'
|
74
81
|
require 'mutant/mutator/node/send/binary'
|
75
82
|
require 'mutant/mutator/node/when'
|
@@ -99,13 +106,13 @@ require 'mutant/matcher/method/instance'
|
|
99
106
|
require 'mutant/matcher/methods'
|
100
107
|
require 'mutant/matcher/namespace'
|
101
108
|
require 'mutant/matcher/scope'
|
109
|
+
require 'mutant/matcher/filter'
|
102
110
|
require 'mutant/killer'
|
103
111
|
require 'mutant/killer/static'
|
104
112
|
require 'mutant/killer/rspec'
|
105
113
|
require 'mutant/killer/forking'
|
106
114
|
require 'mutant/killer/forked'
|
107
115
|
require 'mutant/strategy'
|
108
|
-
require 'mutant/strategy/static'
|
109
116
|
require 'mutant/strategy/rspec'
|
110
117
|
require 'mutant/runner'
|
111
118
|
require 'mutant/runner/config'
|
@@ -115,6 +122,7 @@ require 'mutant/cli'
|
|
115
122
|
require 'mutant/cli/classifier'
|
116
123
|
require 'mutant/cli/classifier/namespace'
|
117
124
|
require 'mutant/cli/classifier/method'
|
125
|
+
require 'mutant/cli/builder'
|
118
126
|
require 'mutant/color'
|
119
127
|
require 'mutant/differ'
|
120
128
|
require 'mutant/reporter'
|
data/mutant.gemspec
CHANGED
@@ -18,15 +18,15 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.extra_rdoc_files = %w[TODO LICENSE]
|
19
19
|
gem.executables = %w[mutant]
|
20
20
|
|
21
|
-
gem.add_runtime_dependency('parser', '~> 2.0.0.
|
22
|
-
gem.add_runtime_dependency('unparser', '~> 0.
|
23
|
-
gem.add_runtime_dependency('ice_nine', '~> 0.8
|
21
|
+
gem.add_runtime_dependency('parser', '~> 2.0.0.pre7')
|
22
|
+
gem.add_runtime_dependency('unparser', '~> 0.1.1')
|
23
|
+
gem.add_runtime_dependency('ice_nine', '~> 0.8')
|
24
24
|
gem.add_runtime_dependency('descendants_tracker', '~> 0.0.1')
|
25
|
-
gem.add_runtime_dependency('adamantium', '~> 0.0
|
26
|
-
gem.add_runtime_dependency('equalizer', '~> 0.0.
|
25
|
+
gem.add_runtime_dependency('adamantium', '~> 0.1.0')
|
26
|
+
gem.add_runtime_dependency('equalizer', '~> 0.0.7')
|
27
27
|
gem.add_runtime_dependency('inflecto', '~> 0.0.2')
|
28
|
-
gem.add_runtime_dependency('anima', '~> 0.
|
29
|
-
gem.add_runtime_dependency('concord', '~> 0.1.
|
28
|
+
gem.add_runtime_dependency('anima', '~> 0.1.1')
|
29
|
+
gem.add_runtime_dependency('concord', '~> 0.1.4')
|
30
30
|
gem.add_runtime_dependency('rspec', '~> 2.14.1')
|
31
31
|
|
32
32
|
gem.add_development_dependency('bundler', '~> 1.3', '>= 1.3.5')
|
@@ -10,17 +10,24 @@ describe Mutant, 'rspec integration' do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
let(:base_cmd) { 'bundle exec mutant -I lib --require test_app --rspec' }
|
14
|
+
|
13
15
|
specify 'it allows to kill mutations' do
|
14
|
-
Kernel.system(
|
16
|
+
Kernel.system("#{base_cmd} ::TestApp::Literal#string').should be(true)")
|
17
|
+
end
|
18
|
+
|
19
|
+
specify 'it allows to exclude mutations' do
|
20
|
+
cli = "#{base_cmd} ::TestApp::Literal#string --ignore-subject ::TestApp::Literal#uncovered_string"
|
21
|
+
Kernel.system(cli).should be(true)
|
15
22
|
end
|
16
23
|
|
17
|
-
|
18
|
-
cli =
|
24
|
+
specify 'fails to kill mutations when they are not covered' do
|
25
|
+
cli = "#{base_cmd} ::TestApp::Literal#uncovered_string"
|
19
26
|
Kernel.system(cli).should be(false)
|
20
27
|
end
|
21
28
|
|
22
|
-
|
23
|
-
cli =
|
29
|
+
specify 'fails when some mutations are not covered' do
|
30
|
+
cli = "#{base_cmd} ::TestApp::Literal"
|
24
31
|
Kernel.system(cli).should be(false)
|
25
32
|
end
|
26
33
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require 'equalizer'
|
4
|
-
require 'devtools/spec_helper'
|
5
|
-
|
6
3
|
if ENV['COVERAGE'] == 'true'
|
7
4
|
require 'simplecov'
|
8
5
|
require 'coveralls'
|
@@ -13,14 +10,19 @@ if ENV['COVERAGE'] == 'true'
|
|
13
10
|
]
|
14
11
|
|
15
12
|
SimpleCov.start do
|
16
|
-
command_name
|
17
|
-
|
18
|
-
add_filter
|
19
|
-
add_filter
|
20
|
-
|
13
|
+
command_name 'spec:unit'
|
14
|
+
|
15
|
+
add_filter 'config'
|
16
|
+
add_filter 'spec'
|
17
|
+
add_filter 'vendor'
|
18
|
+
add_filter 'test_app'
|
19
|
+
|
20
|
+
minimum_coverage 90.1 # TODO: raise this to 100, then mutation test
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
require 'equalizer'
|
25
|
+
require 'devtools/spec_helper'
|
24
26
|
require 'mutant'
|
25
27
|
|
26
28
|
$LOAD_PATH << File.join(TestApp.root, 'lib')
|
@@ -45,7 +47,7 @@ RSpec.configure do |config|
|
|
45
47
|
config.include(CompressHelper)
|
46
48
|
config.include(ParserHelper)
|
47
49
|
config.include(Mutant::NodeHelpers)
|
48
|
-
config.
|
50
|
+
config.expect_with :rspec do |rspec|
|
49
51
|
rspec.syntax = [:expect, :should]
|
50
52
|
end
|
51
53
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Mutant::CLI::Builder::Rspec do
|
6
|
+
|
7
|
+
let(:option_parser) { OptionParser.new }
|
8
|
+
|
9
|
+
let(:cache) { Mutant::Cache.new }
|
10
|
+
let(:object) { described_class.new(cache, option_parser) }
|
11
|
+
let(:level) { double('Level') }
|
12
|
+
|
13
|
+
let(:default_strategy) do
|
14
|
+
Mutant::Strategy::Rspec.new(0)
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:altered_strategy) do
|
18
|
+
Mutant::Strategy::Rspec.new(1)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'default' do
|
22
|
+
specify do
|
23
|
+
object
|
24
|
+
option_parser.parse!(%w[--rspec])
|
25
|
+
expect(object.output).to eql(default_strategy)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'parsing a level' do
|
30
|
+
|
31
|
+
specify do
|
32
|
+
object
|
33
|
+
option_parser.parse!(%w[--rspec --rspec-level 1])
|
34
|
+
expect(object.output).to eql(altered_strategy)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -3,7 +3,8 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Mutant::CLI::Classifier::Method, '#each' do
|
6
|
-
|
6
|
+
|
7
|
+
let(:object) { described_class.run(cache, input) }
|
7
8
|
let(:cache) { Mutant::Cache.new }
|
8
9
|
let(:instance_method) { '::TestApp::Literal#string' }
|
9
10
|
let(:singleton_method) { '::TestApp::Literal.string' }
|
@@ -72,18 +73,5 @@ describe Mutant::CLI::Classifier::Method, '#each' do
|
|
72
73
|
.to yield_with_args(Mutant::Subject::Method::Singleton)
|
73
74
|
end
|
74
75
|
end
|
75
|
-
|
76
|
-
context 'with an unknown method' do
|
77
|
-
let(:input) { unknown_method }
|
78
|
-
|
79
|
-
it 'returns an enumerator' do
|
80
|
-
should be_instance_of(to_enum.class)
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'raises an exception when #each is called' do
|
84
|
-
expect { subject.each {} }
|
85
|
-
.to raise_error(NameError, "Cannot find method #{input}")
|
86
|
-
end
|
87
|
-
end
|
88
76
|
end
|
89
77
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Mutant::CLI::Classifier::Namespace::Flat, '#each' do
|
6
|
-
let(:object) { described_class.
|
6
|
+
let(:object) { described_class.run(cache, input) }
|
7
7
|
let(:cache) { Mutant::Cache.new }
|
8
8
|
let(:known_namespace) { '::TestApp::Literal' }
|
9
9
|
let(:unknown_namespace) { '::TestApp::Object' }
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Mutant::CLI::Classifier::Namespace::Recursive, '#each' do
|
6
|
-
let(:object) { described_class.
|
6
|
+
let(:object) { described_class.run(cache, "#{input}*") }
|
7
7
|
let(:cache) { Mutant::Cache.new }
|
8
8
|
let(:known_namespace) { '::TestApp::Literal' }
|
9
9
|
let(:unknown_namespace) { '::TestApp::Object' }
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Mutant::CLI::Classifier, '.run' do
|
6
|
+
subject { described_class.run(cache, input) }
|
7
|
+
|
8
|
+
let(:cache) { double('Cache') }
|
9
|
+
|
10
|
+
this_spec = 'Mutant::CLI::Classifier.build'
|
11
|
+
|
12
|
+
shared_examples_for this_spec do
|
13
|
+
it 'shoud return expected instance' do
|
14
|
+
should eql(expected_matcher)
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:expected_class) { Mutant::CLI::Classifier::Method }
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with explicit toplevel scope' do
|
21
|
+
|
22
|
+
let(:input) { '::TestApp::Literal#string' }
|
23
|
+
|
24
|
+
let(:expected_matcher) do
|
25
|
+
Mutant::Matcher::Method::Instance.new(cache, TestApp::Literal, TestApp::Literal.instance_method(:string))
|
26
|
+
end
|
27
|
+
|
28
|
+
include_examples this_spec
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with instance method notation' do
|
32
|
+
|
33
|
+
let(:input) { 'TestApp::Literal#string' }
|
34
|
+
|
35
|
+
let(:expected_matcher) do
|
36
|
+
Mutant::Matcher::Method::Instance.new(cache, TestApp::Literal, TestApp::Literal.instance_method(:string))
|
37
|
+
end
|
38
|
+
|
39
|
+
include_examples this_spec
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'with singleton method notation' do
|
43
|
+
let(:input) { 'TestApp::Literal.string' }
|
44
|
+
|
45
|
+
let(:expected_matcher) do
|
46
|
+
Mutant::Matcher::Method::Singleton.new(cache, TestApp::Literal, TestApp::Literal.method(:string))
|
47
|
+
end
|
48
|
+
|
49
|
+
include_examples this_spec
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'with invalid notation' do
|
53
|
+
let(:input) { '::' }
|
54
|
+
|
55
|
+
it 'should return nil' do
|
56
|
+
expect { subject }.to raise_error(Mutant::CLI::Error, "No matcher handles: #{input.inspect}")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|