mutant 0.2.20 → 0.3.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (201) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +10 -11
  3. data/Changelog.md +93 -38
  4. data/Gemfile +3 -1
  5. data/Gemfile.devtools +16 -20
  6. data/Guardfile +1 -1
  7. data/README.md +36 -16
  8. data/Rakefile +21 -2
  9. data/TODO +11 -7
  10. data/bin/mutant +4 -0
  11. data/bin/zombie +4 -0
  12. data/config/devtools.yml +2 -0
  13. data/config/flay.yml +2 -2
  14. data/config/flog.yml +1 -1
  15. data/config/{site.reek → reek.yml} +94 -70
  16. data/lib/mutant/cli/classifier/method.rb +100 -0
  17. data/lib/mutant/cli/classifier/namespace.rb +47 -0
  18. data/lib/mutant/cli/classifier/scope.rb +35 -0
  19. data/lib/mutant/cli/classifier.rb +141 -0
  20. data/lib/mutant/cli.rb +115 -162
  21. data/lib/mutant/color.rb +2 -2
  22. data/lib/mutant/config.rb +27 -0
  23. data/lib/mutant/constants.rb +32 -17
  24. data/lib/mutant/context/scope.rb +33 -51
  25. data/lib/mutant/context.rb +8 -19
  26. data/lib/mutant/differ.rb +5 -5
  27. data/lib/mutant/helper.rb +2 -17
  28. data/lib/mutant/killer/forked.rb +44 -0
  29. data/lib/mutant/killer/forking.rb +3 -57
  30. data/lib/mutant/killer/rspec.rb +16 -20
  31. data/lib/mutant/killer/static.rb +6 -7
  32. data/lib/mutant/killer.rb +48 -74
  33. data/lib/mutant/loader.rb +6 -6
  34. data/lib/mutant/matcher/chain.rb +4 -25
  35. data/lib/mutant/matcher/method/instance.rb +14 -24
  36. data/lib/mutant/matcher/method/singleton.rb +35 -46
  37. data/lib/mutant/matcher/method.rb +95 -83
  38. data/lib/mutant/matcher/{scope_methods.rb → methods.rb} +53 -76
  39. data/lib/mutant/matcher/namespace.rb +71 -0
  40. data/lib/mutant/matcher/scope.rb +34 -0
  41. data/lib/mutant/matcher.rb +24 -34
  42. data/lib/mutant/mutation/evil.rb +35 -0
  43. data/lib/mutant/mutation/filter/code.rb +7 -28
  44. data/lib/mutant/mutation/filter/regexp.rb +6 -18
  45. data/lib/mutant/mutation/filter/whitelist.rb +5 -4
  46. data/lib/mutant/mutation/filter.rb +10 -9
  47. data/lib/mutant/mutation/neutral.rb +35 -0
  48. data/lib/mutant/mutation.rb +21 -61
  49. data/lib/mutant/mutator/node/argument.rb +88 -0
  50. data/lib/mutant/mutator/node/arguments.rb +52 -0
  51. data/lib/mutant/mutator/node/assignment.rb +34 -38
  52. data/lib/mutant/mutator/node/begin.rb +33 -0
  53. data/lib/mutant/mutator/node/block.rb +14 -14
  54. data/lib/mutant/mutator/node/case.rb +59 -0
  55. data/lib/mutant/mutator/node/define.rb +26 -22
  56. data/lib/mutant/mutator/node/if.rb +31 -71
  57. data/lib/mutant/mutator/node/literal/array.rb +25 -9
  58. data/lib/mutant/mutator/node/literal/boolean.rb +13 -30
  59. data/lib/mutant/mutator/node/literal/dynamic.rb +6 -5
  60. data/lib/mutant/mutator/node/literal/fixnum.rb +18 -7
  61. data/lib/mutant/mutator/node/literal/float.rb +15 -8
  62. data/lib/mutant/mutator/node/literal/hash.rb +33 -52
  63. data/lib/mutant/mutator/node/literal/nil.rb +8 -7
  64. data/lib/mutant/mutator/node/literal/range.rb +25 -50
  65. data/lib/mutant/mutator/node/literal/regex.rb +15 -23
  66. data/lib/mutant/mutator/node/literal/string.rb +7 -6
  67. data/lib/mutant/mutator/node/literal/symbol.rb +7 -6
  68. data/lib/mutant/mutator/node/literal.rb +4 -46
  69. data/lib/mutant/mutator/node/mlhs.rb +27 -0
  70. data/lib/mutant/mutator/node/noop.rb +18 -43
  71. data/lib/mutant/mutator/node/return.rb +8 -8
  72. data/lib/mutant/mutator/node/send/binary.rb +31 -0
  73. data/lib/mutant/mutator/node/send.rb +106 -72
  74. data/lib/mutant/mutator/node/super.rb +15 -20
  75. data/lib/mutant/mutator/node/when.rb +32 -7
  76. data/lib/mutant/mutator/node/while.rb +9 -7
  77. data/lib/mutant/mutator/node.rb +116 -66
  78. data/lib/mutant/mutator/registry.rb +14 -11
  79. data/lib/mutant/mutator/util/array.rb +9 -9
  80. data/lib/mutant/mutator/util/symbol.rb +6 -20
  81. data/lib/mutant/mutator/util.rb +6 -3
  82. data/lib/mutant/mutator.rb +12 -28
  83. data/lib/mutant/node_helpers.rb +28 -0
  84. data/lib/mutant/random.rb +3 -2
  85. data/lib/mutant/reporter/cli/printer/config.rb +174 -0
  86. data/lib/mutant/reporter/cli/printer/killer.rb +42 -0
  87. data/lib/mutant/reporter/cli/printer/mutation.rb +55 -0
  88. data/lib/mutant/reporter/cli/printer/subject.rb +147 -0
  89. data/lib/mutant/reporter/cli/printer.rb +165 -0
  90. data/lib/mutant/reporter/cli.rb +9 -277
  91. data/lib/mutant/reporter/null.rb +6 -30
  92. data/lib/mutant/reporter.rb +6 -73
  93. data/lib/mutant/runner/config.rb +82 -0
  94. data/lib/mutant/runner/mutation.rb +58 -0
  95. data/lib/mutant/runner/subject.rb +81 -0
  96. data/lib/mutant/runner.rb +42 -92
  97. data/lib/mutant/singleton_methods.rb +2 -2
  98. data/lib/mutant/strategy/method_expansion.rb +51 -0
  99. data/lib/mutant/strategy/rspec/dm2/lookup/method.rb +142 -0
  100. data/lib/mutant/strategy/rspec/dm2/lookup.rb +61 -0
  101. data/lib/mutant/strategy/rspec/dm2.rb +22 -0
  102. data/lib/mutant/strategy/rspec.rb +20 -22
  103. data/lib/mutant/strategy/static.rb +18 -0
  104. data/lib/mutant/strategy.rb +15 -50
  105. data/lib/mutant/subject/method.rb +100 -0
  106. data/lib/mutant/subject.rb +18 -49
  107. data/lib/mutant/support/method_object.rb +4 -2
  108. data/lib/mutant.rb +40 -35
  109. data/mutant.gemspec +9 -8
  110. data/spec/integration/mutant/rspec_killer_spec.rb +3 -3
  111. data/spec/integration/mutant/test_mutator_handles_types_spec.rb +9 -0
  112. data/spec/integration/mutant/zombie_spec.rb +1 -1
  113. data/spec/shared/method_matcher_behavior.rb +35 -0
  114. data/spec/shared/mutator_behavior.rb +63 -32
  115. data/spec/spec_helper.rb +13 -3
  116. data/spec/support/ice_nine_config.rb +8 -0
  117. data/spec/support/rspec.rb +1 -1
  118. data/spec/support/zombie.rb +1 -1
  119. data/spec/unit/mutant/cli/class_methods/new_spec.rb +42 -28
  120. data/spec/unit/mutant/cli/class_methods/run_spec.rb +15 -13
  121. data/spec/unit/mutant/cli/classifier/class_methods/build_spec.rb +44 -0
  122. data/spec/unit/mutant/context/scope/root_spec.rb +4 -4
  123. data/spec/unit/mutant/killer/rspec/class_methods/new_spec.rb +6 -5
  124. data/spec/unit/mutant/killer/success_predicate_spec.rb +28 -0
  125. data/spec/unit/mutant/loader/eval/class_methods/run_spec.rb +1 -1
  126. data/spec/unit/mutant/matcher/chain/each_spec.rb +1 -1
  127. data/spec/unit/mutant/matcher/chain/matchers_spec.rb +1 -1
  128. data/spec/unit/mutant/matcher/method/instance/each_spec.rb +112 -0
  129. data/spec/unit/mutant/matcher/method/singleton/each_spec.rb +93 -0
  130. data/spec/unit/mutant/matcher/methods/instance/each_spec.rb +59 -0
  131. data/spec/unit/mutant/matcher/methods/singleton/each_spec.rb +53 -0
  132. data/spec/unit/mutant/matcher/namespace/each_spec.rb +37 -0
  133. data/spec/unit/mutant/mutator/node/begin/mutation_spec.rb +33 -0
  134. data/spec/unit/mutant/mutator/node/block/mutation_spec.rb +42 -14
  135. data/spec/unit/mutant/mutator/node/case/mutation_spec.rb +319 -0
  136. data/spec/unit/mutant/mutator/node/define/mutation_spec.rb +31 -27
  137. data/spec/unit/mutant/mutator/node/if/mutation_spec.rb +75 -0
  138. data/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb +1 -1
  139. data/spec/unit/mutant/mutator/node/literal/hash_spec.rb +2 -2
  140. data/spec/unit/mutant/mutator/node/literal/nil_spec.rb +1 -3
  141. data/spec/unit/mutant/mutator/node/literal/regex_spec.rb +1 -9
  142. data/spec/unit/mutant/mutator/node/return/mutation_spec.rb +6 -2
  143. data/spec/unit/mutant/mutator/node/send/mutation_spec.rb +111 -108
  144. data/spec/unit/mutant/mutator/node/super/mutation_spec.rb +0 -33
  145. data/spec/unit/mutant/mutator/node/while/mutation_spec.rb +2 -2
  146. data/spec/unit/mutant/runner/config/subjects_spec.rb +38 -0
  147. data/spec/unit/mutant/runner/config/success_predicate_spec.rb +53 -0
  148. data/spec/unit/mutant/runner/failed_predicte_spec.rb +33 -0
  149. data/spec/unit/mutant/runner/mutation/killer_spec.rb +39 -0
  150. data/spec/unit/mutant/runner/subject/success_predicate_spec.rb +49 -0
  151. data/spec/unit/mutant/strategy/method_expansion/class_methods/run_spec.rb +49 -0
  152. data/spec/unit/mutant/strategy/rspec/dm2/lookup/method/instance/spec_files_spec.rb +52 -0
  153. data/spec/unit/mutant/strategy/rspec/dm2/lookup/method/singleton/spec_files_spec.rb +42 -0
  154. data/spec/unit/mutant/subject/context_spec.rb +6 -3
  155. data/spec/unit/mutant/subject/each_spec.rb +11 -8
  156. data/spec/unit/mutant/subject/node_spec.rb +6 -2
  157. data/test_app/spec/shared/method_filter_parse_behavior.rb +0 -2
  158. data/test_app/spec/shared/method_match_behavior.rb +1 -1
  159. data/test_app/spec/spec_helper.rb +4 -2
  160. metadata +101 -109
  161. data/config/roodi.yml +0 -26
  162. data/lib/mutant/matcher/method/classifier.rb +0 -141
  163. data/lib/mutant/matcher/object_space.rb +0 -114
  164. data/lib/mutant/mutator/node/actual_arguments.rb +0 -25
  165. data/lib/mutant/mutator/node/default_arguments.rb +0 -25
  166. data/lib/mutant/mutator/node/formal_arguments_19/default_mutations.rb +0 -33
  167. data/lib/mutant/mutator/node/formal_arguments_19/pattern_argument_expansion.rb +0 -35
  168. data/lib/mutant/mutator/node/formal_arguments_19/require_defaults.rb +0 -37
  169. data/lib/mutant/mutator/node/formal_arguments_19.rb +0 -41
  170. data/lib/mutant/mutator/node/iter_19.rb +0 -27
  171. data/lib/mutant/mutator/node/literal/empty_array.rb +0 -26
  172. data/lib/mutant/mutator/node/pattern_arguments.rb +0 -41
  173. data/lib/mutant/mutator/node/pattern_variable.rb +0 -23
  174. data/lib/mutant/mutator/node/receiver_case.rb +0 -122
  175. data/lib/mutant/mutator/node/send/binary_operator_method.rb +0 -61
  176. data/lib/mutant/mutator/node/send/with_arguments.rb +0 -81
  177. data/lib/mutant/reporter/stats.rb +0 -120
  178. data/lib/mutant/strategy/rspec/example_lookup.rb +0 -163
  179. data/spec/integration/mutant/method_matching_spec.rb +0 -269
  180. data/spec/shared/method_match_behavior.rb +0 -39
  181. data/spec/unit/mutant/killer/fail_ques_spec.rb +0 -39
  182. data/spec/unit/mutant/matcher/class_methods/from_string_spec.rb +0 -49
  183. data/spec/unit/mutant/matcher/class_methods/parse_spec.rb +0 -12
  184. data/spec/unit/mutant/matcher/method/class_methods/parse_spec.rb +0 -21
  185. data/spec/unit/mutant/matcher/method/classifier/class_methods/run_spec.rb +0 -52
  186. data/spec/unit/mutant/matcher/object_space/class_methods/parse_spec.rb +0 -24
  187. data/spec/unit/mutant/matcher/object_space/each_spec.rb +0 -31
  188. data/spec/unit/mutant/mutator/node/if_statement/mutation_spec.rb +0 -60
  189. data/spec/unit/mutant/mutator/node/receiver_case/mutation_spec.rb +0 -27
  190. data/spec/unit/mutant/strategy/rspec/example_lookup/spec_file_spec.rb +0 -236
  191. data/spec/unit/mutant/subject/class_methods/new_spec.rb +0 -13
  192. data/tasks/metrics/ci.rake +0 -7
  193. data/tasks/metrics/flay.rake +0 -41
  194. data/tasks/metrics/flog.rake +0 -43
  195. data/tasks/metrics/heckle.rake +0 -216
  196. data/tasks/metrics/metric_fu.rake +0 -31
  197. data/tasks/metrics/reek.rake +0 -15
  198. data/tasks/metrics/roodi.rake +0 -15
  199. data/tasks/metrics/yardstick.rake +0 -23
  200. data/tasks/spec.rake +0 -45
  201. data/tasks/yard.rake +0 -9
data/lib/mutant/runner.rb CHANGED
@@ -1,31 +1,9 @@
1
1
  module Mutant
2
- # Runner that allows to mutate an entire project
2
+ # Runner baseclass
3
3
  class Runner
4
- include Adamantium::Flat
4
+ include Adamantium::Flat, AbstractType, Equalizer.new(:config)
5
5
  extend MethodObject
6
6
 
7
- # Return killers with errors
8
- #
9
- # @return [Enumerable<Killer>]
10
- #
11
- # @api private
12
- #
13
- attr_reader :errors
14
-
15
- # Test for failure
16
- #
17
- # @return [true]
18
- # returns true when there are left mutations
19
- #
20
- # @return [false]
21
- # returns false othewise
22
- #
23
- # @api private
24
- #
25
- def fail?
26
- !errors.empty?
27
- end
28
-
29
7
  # Return config
30
8
  #
31
9
  # @return [Mutant::Config]
@@ -34,8 +12,6 @@ module Mutant
34
12
  #
35
13
  attr_reader :config
36
14
 
37
- private
38
-
39
15
  # Initialize object
40
16
  #
41
17
  # @param [Config] config
@@ -45,106 +21,80 @@ module Mutant
45
21
  # @api private
46
22
  #
47
23
  def initialize(config)
48
- @config, @errors = config, []
49
-
50
- util_reporter = reporter
51
- util_reporter.config(config)
24
+ @config = config
25
+ @start = Time.now
52
26
  run
53
- util_reporter.errors(@errors)
54
- end
55
-
56
- # Return reporter
57
- #
58
- # @return [Reporter]
59
- #
60
- # @api private
61
- #
62
- def reporter
63
- config.reporter
27
+ @end = Time.now
64
28
  end
65
29
 
66
- # Run mutation killers on subjects
30
+ # Return runtime
67
31
  #
68
- # @return [undefined]
32
+ # @return [Float]
69
33
  #
70
34
  # @api private
71
35
  #
72
- def run
73
- config.matcher.each do |subject|
74
- reporter.subject(subject)
75
- run_subject(subject)
76
- end
36
+ def runtime
37
+ @end - @start
77
38
  end
39
+ memoize :runtime
78
40
 
79
- # Run mutation killers on subject
41
+ # Test if runner failed
80
42
  #
81
- # @param [Subject] subject
43
+ # @return [true]
44
+ # if failed
82
45
  #
83
- # @return [undefined]
46
+ # @return [false]
47
+ # otherwise
84
48
  #
85
49
  # @api private
86
50
  #
87
- def run_subject(subject)
88
- return unless noop(subject)
89
- subject.each do |mutation|
90
- next unless config.filter.match?(mutation)
91
- reporter.mutation(mutation)
92
- kill(mutation)
93
- end
51
+ def failed?
52
+ !success?
94
53
  end
95
54
 
96
- # Test for noop mutation
97
- #
98
- # @param [Subject] subject
55
+ # Test if runner is successful
99
56
  #
100
57
  # @return [true]
101
- # if noop mutation is okay
58
+ # if successful
102
59
  #
103
60
  # @return [false]
104
61
  # otherwise
105
62
  #
106
63
  # @api private
107
64
  #
108
- def noop(subject)
109
- killer = killer(subject.noop)
110
- reporter.noop(killer)
111
- unless killer.fail?
112
- @errors << killer
113
- return false
114
- end
115
-
116
- true
117
- end
65
+ abstract_method :success?
118
66
 
119
- # Run killer on mutation
67
+ # Return reporter
120
68
  #
121
- # @param [Mutation] mutation
69
+ # @return [Reporter]
122
70
  #
123
- # @return [true]
124
- # if killer was unsuccessful
71
+ # @api private
125
72
  #
126
- # @return [false]
127
- # otherwise
73
+ def reporter
74
+ config.reporter
75
+ end
76
+
77
+ private
78
+
79
+ # Perform operation
80
+ #
81
+ # @return [undefined]
128
82
  #
129
83
  # @api private
130
84
  #
131
- def kill(mutation)
132
- killer = killer(mutation)
133
- reporter.killer(killer)
85
+ abstract_method :run
134
86
 
135
- if killer.fail?
136
- @errors << killer
137
- end
138
- end
139
-
140
- # Return killer for mutation
87
+ # Return reporter
141
88
  #
142
- # @return [Killer]
89
+ # @param [Object] object
90
+ #
91
+ # @return [undefined]
143
92
  #
144
93
  # @api private
145
94
  #
146
- def killer(mutation)
147
- config.strategy.kill(mutation)
95
+ def report(object)
96
+ reporter.report(object)
148
97
  end
149
- end
150
- end
98
+
99
+ end # Runner
100
+ end # Mutant
@@ -10,7 +10,7 @@ module Mutant
10
10
  #
11
11
  # @api private
12
12
  #
13
- def self.define_singleton_subclass(name, superclass, &block)
13
+ def self.singleton_subclass_instance(name, superclass, &block)
14
14
  klass = Class.new(superclass) do
15
15
 
16
16
  def inspect; self.class.name; end
@@ -25,4 +25,4 @@ module Mutant
25
25
  self
26
26
  end
27
27
 
28
- end
28
+ end # Mutant
@@ -0,0 +1,51 @@
1
+ module Mutant
2
+ class Strategy
3
+ module MethodExpansion
4
+
5
+ # Run method name expansion
6
+ #
7
+ # @param [Symbol] name
8
+ #
9
+ # @return [Symbol]
10
+ #
11
+ # @api private
12
+ #
13
+ def self.run(name)
14
+ name = map(name) || expand(name)
15
+ end
16
+
17
+ # Return mapped name
18
+ #
19
+ # @param [Symbol] name
20
+ #
21
+ # @return [Symbol]
22
+ # if name was mapped
23
+ #
24
+ # @return [nil]
25
+ # otherwise
26
+ #
27
+ # @api private
28
+ #
29
+ def self.map(name)
30
+ OPERATOR_EXPANSIONS[name]
31
+ end
32
+ private_class_method :map
33
+
34
+ REGEXP = /#{Regexp.union(*METHOD_POSTFIX_EXPANSIONS.keys)}\z/.freeze
35
+
36
+ # Return expanded name
37
+ #
38
+ # @param [Symbol] name
39
+ #
40
+ # @return [Symbol]
41
+ #
42
+ # @api private
43
+ #
44
+ def self.expand(name)
45
+ name.to_s.gsub(REGEXP, METHOD_POSTFIX_EXPANSIONS).to_sym
46
+ end
47
+ private_class_method :expand
48
+
49
+ end # MethodExpansion
50
+ end # Strategy
51
+ end # Mutant
@@ -0,0 +1,142 @@
1
+ module Mutant
2
+ class Strategy
3
+ class Rspec
4
+ class DM2
5
+ class Lookup
6
+
7
+ # Base class for dm2 style method lookup
8
+ class Method < self
9
+
10
+ # Return spec files
11
+ #
12
+ # @return [Enumerable<String>]
13
+ #
14
+ # @api private
15
+ #
16
+ def spec_files
17
+ Dir.glob(glob_expression)
18
+ end
19
+ memoize :spec_files
20
+
21
+ private
22
+
23
+ # Return base path
24
+ #
25
+ # @return [String]
26
+ #
27
+ # @api private
28
+ #
29
+ def base_path
30
+ "spec/unit/#{Inflecto.underscore(subject.context.name)}"
31
+ end
32
+
33
+ # Return method name
34
+ #
35
+ # @return [Symbol]
36
+ #
37
+ # @api private
38
+ #
39
+ def method_name
40
+ subject.name
41
+ end
42
+
43
+ # Test if method is public
44
+ #
45
+ # @return [true]
46
+ # if method is public
47
+ #
48
+ # @return [false]
49
+ #
50
+ # @api private
51
+ #
52
+ def public?
53
+ subject.public?
54
+ end
55
+
56
+ # Return expanded name
57
+ #
58
+ # @return [String]
59
+ #
60
+ # @api private
61
+ #
62
+ def expanded_name
63
+ MethodExpansion.run(method_name)
64
+ end
65
+
66
+ # Return glob expression
67
+ #
68
+ # @return [String]
69
+ #
70
+ # @api private
71
+ #
72
+ def glob_expression
73
+ public? ? public_glob_expression : private_glob_expression
74
+ end
75
+
76
+ # Return public glob expression
77
+ #
78
+ # @return [String]
79
+ #
80
+ # @api private
81
+ #
82
+ def public_glob_expression
83
+ "#{base_path}/#{expanded_name}_spec.rb"
84
+ end
85
+
86
+ # Return private glob expression
87
+ #
88
+ # @return [String]
89
+ #
90
+ # @api private
91
+ #
92
+ def private_glob_expression
93
+ "#{base_path}/*_spec.rb"
94
+ end
95
+
96
+ # Instance method dm2 style method lookup
97
+ class Instance < self
98
+ handle(Subject::Method::Instance)
99
+
100
+ private
101
+
102
+ # Return glob expression
103
+ #
104
+ # @return [String]
105
+ #
106
+ # @api private
107
+ #
108
+ def glob_expression
109
+ glob_expression = super
110
+ if method_name == :initialize and !public?
111
+ "{#{glob_expression},#{base_path}/class_methods/new_spec.rb}"
112
+ else
113
+ glob_expression
114
+ end
115
+ end
116
+
117
+ end # Instance
118
+
119
+ # Singleton method dm2 style method lookup
120
+ class Singleton < self
121
+ handle(Subject::Method::Singleton)
122
+
123
+ private
124
+
125
+ # Return base path
126
+ #
127
+ # @return [String]
128
+ #
129
+ # @api private
130
+ #
131
+ def base_path
132
+ "#{super}/class_methods"
133
+ end
134
+
135
+ end # Singleton
136
+
137
+ end # Method
138
+ end # Lookup
139
+ end # DM2
140
+ end # Rspec
141
+ end # Strategy
142
+ end # Mutant
@@ -0,0 +1,61 @@
1
+ module Mutant
2
+ class Strategy
3
+ class Rspec
4
+ class DM2
5
+
6
+ # Example lookup for the rspec dm2
7
+ class Lookup
8
+ include AbstractType, Adamantium::Flat, Concord::Public.new(:subject)
9
+
10
+ # Return glob expression
11
+ #
12
+ # @return [String]
13
+ #
14
+ # @api private
15
+ #
16
+ abstract_method :spec_files
17
+
18
+ # Perform example lookup
19
+ #
20
+ # @param [Subject] subject
21
+ #
22
+ # @return [Enumerable<String>]
23
+ #
24
+ # @api private
25
+ #
26
+ def self.run(subject)
27
+ build(subject).spec_files
28
+ end
29
+
30
+ REGISTRY = {}
31
+
32
+ # Register subject hander
33
+ #
34
+ # @param [Class:Subject]
35
+ #
36
+ # @return [undefined]
37
+ #
38
+ # @api private
39
+ #
40
+ def self.handle(subject_class)
41
+ REGISTRY[subject_class]=self
42
+ end
43
+ private_class_method :handle
44
+
45
+ # Build lookup object
46
+ #
47
+ # @param [Subjecŧ] subject
48
+ #
49
+ # @return [Lookup]
50
+ #
51
+ # @api private
52
+ #
53
+ def self.build(subject)
54
+ REGISTRY.fetch(subject.class).new(subject)
55
+ end
56
+
57
+ end # Lookup
58
+ end # DM2
59
+ end # Rspec
60
+ end # Strategy
61
+ end # Mutant
@@ -0,0 +1,22 @@
1
+ module Mutant
2
+ class Strategy
3
+ class Rspec
4
+ # DM2-style strategy
5
+ class DM2 < self
6
+
7
+ # Return filename pattern
8
+ #
9
+ # @param [Subject] subject
10
+ #
11
+ # @return [Enumerable<String>]
12
+ #
13
+ # @api private
14
+ #
15
+ def self.spec_files(subject)
16
+ Lookup.run(subject)
17
+ end
18
+
19
+ end # DM2
20
+ end # Rspec
21
+ end # Strategy
22
+ end # Mutant
@@ -6,18 +6,15 @@ module Mutant
6
6
 
7
7
  KILLER = Killer::Forking.new(Killer::Rspec)
8
8
 
9
- # DM2-style strategy
10
- class DM2 < self
11
-
12
- # Return filename pattern
13
- #
14
- # @return [Enumerable<String>]
15
- #
16
- # @api private
17
- #
18
- def spec_files(mutation)
19
- ExampleLookup.run(mutation)
20
- end
9
+ # Setup rspec strategy
10
+ #
11
+ # @return [self]
12
+ #
13
+ # @api private
14
+ #
15
+ def self.setup
16
+ require('./spec/spec_helper.rb')
17
+ self
21
18
  end
22
19
 
23
20
  # Run all unit specs per mutation
@@ -29,10 +26,10 @@ module Mutant
29
26
  #
30
27
  # @api private
31
28
  #
32
- def spec_files(mutation)
33
- ['spec/unit']
29
+ def self.spec_files(_mutation)
30
+ Dir['spec/unit/**/*_spec.rb']
34
31
  end
35
- end
32
+ end # Unit
36
33
 
37
34
  # Run all integration specs per mutation
38
35
  class Integration < self
@@ -43,10 +40,10 @@ module Mutant
43
40
  #
44
41
  # @api private
45
42
  #
46
- def spec_files(mutation)
43
+ def self.spec_files(_mutation)
47
44
  Dir['spec/integration/**/*_spec.rb']
48
45
  end
49
- end
46
+ end # Integration
50
47
 
51
48
  # Run all specs per mutation
52
49
  class Full < self
@@ -57,10 +54,11 @@ module Mutant
57
54
  #
58
55
  # @api private
59
56
  #
60
- def spec_files(mutation)
57
+ def self.spec_files(_mutation)
61
58
  Dir['spec/**/*_spec.rb']
62
59
  end
63
- end
64
- end
65
- end
66
- end
60
+ end # Full
61
+
62
+ end # Rspec
63
+ end # Strategy
64
+ end # Mutant
@@ -0,0 +1,18 @@
1
+ module Mutant
2
+ class Strategy
3
+ # Static strategies
4
+ class Static < self
5
+
6
+ # Always fail to kill strategy
7
+ class Fail < self
8
+ KILLER = Killer::Static::Fail
9
+ end # Fail
10
+
11
+ # Always succeed to kill strategy
12
+ class Success < self
13
+ KILLER = Killer::Static::Success
14
+ end # Success
15
+
16
+ end # Static
17
+ end # Strategy
18
+ end # Mutant
@@ -1,47 +1,27 @@
1
1
  module Mutant
2
2
 
3
3
  # Abstract base class for killing strategies
4
- class Strategy
5
- include AbstractType, Adamantium::Flat, Equalizer.new
4
+ class Strategy
5
+ include AbstractType, Adamantium::Flat
6
6
 
7
- # Return config
7
+ # Perform setup
8
8
  #
9
- # @return [Config]
9
+ # @return [self]
10
10
  #
11
11
  # @api private
12
12
  #
13
- attr_reader :config
14
-
15
- # Initialize object
16
- #
17
- # @param [Config] config
18
- #
19
- # @return [undefined
20
- #
21
- # @api private
22
- #
23
- def initialize(config)
24
- @config = config
25
- end
26
-
27
- # Return output stream
28
- #
29
- # @return [IO]
30
- #
31
- # @api private
32
- #
33
- def output_stream
34
- config.reporter.output_stream
13
+ def self.setup
14
+ self
35
15
  end
36
16
 
37
- # Return error stream
17
+ # Perform teardown
38
18
  #
39
- # @return [IO]
19
+ # @return [self]
40
20
  #
41
21
  # @api private
42
22
  #
43
- def error_stream
44
- config.reporter.error_stream
23
+ def self.teardown
24
+ self
45
25
  end
46
26
 
47
27
  # Kill mutation
@@ -52,7 +32,7 @@ module Mutant
52
32
  #
53
33
  # @api private
54
34
  #
55
- def kill(mutation)
35
+ def self.kill(mutation)
56
36
  killer.new(self, mutation)
57
37
  end
58
38
 
@@ -62,24 +42,9 @@ module Mutant
62
42
  #
63
43
  # @api private
64
44
  #
65
- def killer
66
- self.class::KILLER
45
+ def self.killer
46
+ self::KILLER
67
47
  end
68
48
 
69
- # Static strategies
70
- class Static < self
71
- include Equalizer.new
72
-
73
- # Always fail to kill strategy
74
- class Fail < self
75
- KILLER = Killer::Static::Fail
76
- end
77
-
78
- # Always succeed to kill strategy
79
- class Success < self
80
- KILLER = Killer::Static::Success
81
- end
82
-
83
- end
84
- end
85
- end
49
+ end # Strategy
50
+ end # Mutant