mutant 0.5.12 → 0.5.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +10 -0
  3. data/circle.yml +1 -1
  4. data/config/flay.yml +1 -1
  5. data/config/flog.yml +1 -1
  6. data/config/mutant.yml +1 -2
  7. data/config/reek.yml +12 -3
  8. data/config/rubocop.yml +4 -0
  9. data/lib/mutant.rb +45 -16
  10. data/lib/mutant/constants.rb +11 -11
  11. data/lib/mutant/delegator.rb +50 -0
  12. data/lib/mutant/{differ.rb → diff.rb} +5 -5
  13. data/lib/mutant/killer.rb +29 -106
  14. data/lib/mutant/matcher/method.rb +2 -11
  15. data/lib/mutant/mutation.rb +17 -3
  16. data/lib/mutant/mutation/evil.rb +2 -10
  17. data/lib/mutant/mutation/neutral.rb +4 -30
  18. data/lib/mutant/mutator/node/literal/fixnum.rb +0 -1
  19. data/lib/mutant/mutator/node/literal/float.rb +0 -1
  20. data/lib/mutant/mutator/node/literal/string.rb +0 -1
  21. data/lib/mutant/mutator/node/literal/symbol.rb +6 -2
  22. data/lib/mutant/mutator/node/named_value/variable_assignment.rb +8 -3
  23. data/lib/mutant/mutator/util/symbol.rb +3 -1
  24. data/lib/mutant/node_helpers.rb +1 -3
  25. data/lib/mutant/reporter.rb +10 -0
  26. data/lib/mutant/reporter/cli.rb +15 -2
  27. data/lib/mutant/reporter/cli/printer.rb +12 -105
  28. data/lib/mutant/reporter/cli/progress.rb +12 -0
  29. data/lib/mutant/reporter/cli/progress/config.rb +32 -0
  30. data/lib/mutant/reporter/cli/{printer/killer.rb → progress/mutation.rb} +9 -16
  31. data/lib/mutant/reporter/cli/progress/noop.rb +22 -0
  32. data/lib/mutant/reporter/cli/progress/subject.rb +118 -0
  33. data/lib/mutant/reporter/cli/registry.rb +77 -0
  34. data/lib/mutant/reporter/cli/report.rb +12 -0
  35. data/lib/mutant/reporter/cli/report/config.rb +118 -0
  36. data/lib/mutant/reporter/cli/report/mutation.rb +112 -0
  37. data/lib/mutant/reporter/cli/report/subject.rb +33 -0
  38. data/lib/mutant/reporter/null.rb +13 -0
  39. data/lib/mutant/reporter/trace.rb +41 -0
  40. data/lib/mutant/runner.rb +22 -20
  41. data/lib/mutant/runner/config.rb +6 -5
  42. data/lib/mutant/runner/killer.rb +59 -0
  43. data/lib/mutant/runner/mutation.rb +17 -10
  44. data/lib/mutant/runner/subject.rb +14 -4
  45. data/lib/mutant/strategy.rb +30 -16
  46. data/lib/mutant/subject/method/instance.rb +1 -1
  47. data/lib/mutant/test.rb +86 -0
  48. data/lib/mutant/version.rb +1 -1
  49. data/spec/integration/mutant/null_spec.rb +18 -0
  50. data/spec/integration/mutant/rspec_spec.rb +1 -1
  51. data/spec/spec_helper.rb +0 -2
  52. data/spec/unit/mutant/diff_spec.rb +162 -0
  53. data/spec/unit/mutant/mutation_spec.rb +8 -5
  54. data/spec/unit/mutant/mutator/node/and_asgn_spec.rb +1 -9
  55. data/spec/unit/mutant/mutator/node/block_spec.rb +6 -18
  56. data/spec/unit/mutant/mutator/node/case_spec.rb +10 -16
  57. data/spec/unit/mutant/mutator/node/define_spec.rb +5 -17
  58. data/spec/unit/mutant/mutator/node/dstr_spec.rb +0 -6
  59. data/spec/unit/mutant/mutator/node/dsym_spec.rb +0 -5
  60. data/spec/unit/mutant/mutator/node/if_spec.rb +13 -17
  61. data/spec/unit/mutant/mutator/node/literal/fixnum_spec.rb +1 -7
  62. data/spec/unit/mutant/mutator/node/literal/float_spec.rb +0 -9
  63. data/spec/unit/mutant/mutator/node/literal/range_spec.rb +0 -10
  64. data/spec/unit/mutant/mutator/node/literal/string_spec.rb +1 -5
  65. data/spec/unit/mutant/mutator/node/literal/symbol_spec.rb +1 -5
  66. data/spec/unit/mutant/mutator/node/named_value/access_spec.rb +4 -7
  67. data/spec/unit/mutant/mutator/node/named_value/constant_assignment_spec.rb +1 -5
  68. data/spec/unit/mutant/mutator/node/named_value/variable_assignment_spec.rb +4 -8
  69. data/spec/unit/mutant/mutator/node/op_assgn_spec.rb +0 -7
  70. data/spec/unit/mutant/mutator/node/or_asgn_spec.rb +1 -9
  71. data/spec/unit/mutant/mutator/node/rescue_spec.rb +0 -4
  72. data/spec/unit/mutant/reporter/null_spec.rb +11 -0
  73. data/spec/unit/mutant/runner/config_spec.rb +6 -7
  74. data/spec/unit/mutant/runner/mutation_spec.rb +101 -0
  75. data/spec/unit/mutant/runner/subject_spec.rb +10 -7
  76. data/spec/unit/mutant_spec.rb +53 -0
  77. metadata +65 -62
  78. data/lib/mutant/killer/forked.rb +0 -46
  79. data/lib/mutant/killer/forking.rb +0 -46
  80. data/lib/mutant/killer/static.rb +0 -34
  81. data/lib/mutant/mutator/node/literal/dynamic.rb +0 -27
  82. data/lib/mutant/random.rb +0 -38
  83. data/lib/mutant/reporter/cli/printer/config.rb +0 -154
  84. data/lib/mutant/reporter/cli/printer/mutation.rb +0 -103
  85. data/lib/mutant/reporter/cli/printer/subject.rb +0 -150
  86. data/spec/unit/mutant/differ/diff_spec.rb +0 -123
  87. data/spec/unit/mutant/differ_spec.rb +0 -42
  88. data/spec/unit/mutant/killer/success_predicate_spec.rb +0 -30
  89. data/spec/unit/mutant/rspec/killer_spec.rb +0 -57
  90. data/spec/unit/mutant/runner/mutation/killer_spec.rb +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 297b2cebef213ce23d17e2ab0c3d27077863d433
4
- data.tar.gz: f31250e07dc3d7702c4d43b5428fc54e9b076c36
3
+ metadata.gz: 8160ffea0145b855d07b355672ae647b2d52af24
4
+ data.tar.gz: cf9f75291454ad37e97a9607b2913830bd4f27d9
5
5
  SHA512:
6
- metadata.gz: afddc1bb04782a26096e271114d2e3142c24bb68bf49fcd610614ecca0c395956925351eb8e88b0c5d35f6fc2640b8331a41364ae028785475fbcf36cdd5a011
7
- data.tar.gz: 527d4038e21573b97c1fff670cca72e79724c69e2b720352df9d9e8a236ccd742b51d0757b817d963911b7cdadbcbe680d4fc8347fed5802c49fb6f3b69b9b94
6
+ metadata.gz: eaf8c1d4bcfdcdbf85e9e6b444922325e39d461c0512b506c2b7b405c5e1d575924ef35ecfa2d312cbffbe401f7cc2ae90d6a8d09ab2a3a9807266fd64e3a874
7
+ data.tar.gz: 728a4bd10328e93ed519c4ad6b67ac9d24f3f125d277ebc52aeb76bd7b9f31e9525c64ca2c9329cf16601aa036366e68f2f31a4b3b47f69de63f510b6fc0e877
@@ -1,3 +1,13 @@
1
+ # v0.5.13 2014-05-23
2
+
3
+ Changes:
4
+
5
+ * Imporve reporting of isolation problems
6
+ * Centralize test selection
7
+ * Report selected tests
8
+ * Report rspec output on noop failures
9
+ * Silence warnings on methods without source location
10
+
1
11
  # v0.5.12 2014-05-09
2
12
 
3
13
  Changes:
data/circle.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  machine:
3
3
  ruby:
4
- version: 2.0.0
4
+ version: 2.1.2
5
5
  test:
6
6
  override:
7
7
  - bundle exec rake ci
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 18
3
- total_score: 832
3
+ total_score: 799
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 29.3
2
+ threshold: 29.6
@@ -1,7 +1,7 @@
1
1
  name: mutant
2
2
  namespace: Mutant
3
3
  zombify: true
4
- expect_coverage: 61.83
4
+ expect_coverage: 62.08
5
5
  ignore_subjects:
6
6
  # Mutation causes infinite runtime
7
7
  - Mutant::Runner.lookup
@@ -10,6 +10,5 @@ ignore_subjects:
10
10
  - Mutant::Reporter*
11
11
  - Mutant::CLI*
12
12
  - Mutant.singleton_subclass_instance
13
- - Mutant.symbolset
14
13
  # Executing this has undefined behavior with the zombifier
15
14
  - Mutant.zombify
@@ -40,6 +40,7 @@ LongParameterList:
40
40
  enabled: true
41
41
  exclude:
42
42
  - Mutant::Matcher::Method::Instance#self.build?
43
+ - Mutant::Runner#self.run
43
44
  max_params: 2
44
45
  LongYieldList:
45
46
  enabled: true
@@ -51,9 +52,11 @@ NestedIterators:
51
52
  - Mutant#self.singleton_subclass_instance
52
53
  - Mutant::CLI#parse
53
54
  - Mutant::Mutator::Util::Array::Element#dispatch
54
- - Mutant::Reporter::CLI::Printer::Config::Runner#generic_stats
55
+ - Mutant::Reporter::CLI::Report::Config#generic_stats
55
56
  - Mutant::RequireHighjack#infect
56
57
  - Mutant::RequireHighjack#desinfect
58
+ - Mutant::Reporter::CLI::Registry#included
59
+ - Mutant::Strategy#tests
57
60
  - Parser::Lexer#self.new
58
61
  max_allowed_nesting: 1
59
62
  ignore_iterators: []
@@ -63,6 +66,7 @@ RepeatedConditional:
63
66
  enabled: true
64
67
  exclude:
65
68
  - Mutant::Mutator
69
+ - Mutant::Rspec::Strategy
66
70
  - Mutant::Reporter::CLI
67
71
  max_ifs: 1
68
72
  TooManyInstanceVariables:
@@ -84,12 +88,16 @@ TooManyStatements:
84
88
  enabled: true
85
89
  exclude:
86
90
  - Mutant#self.singleton_subclass_instance
91
+ - Mutant#self.isolate
87
92
  - Mutant::Rspec::Killer#run
88
93
  - Mutant::Reporter::CLI#colorized_diff
89
- - Mutant::Reporter::CLI::Printer::Config::Runner#run
90
- - Mutant::Runner#dispatch
94
+ - Mutant::Reporter::CLI::Report::Config#run
95
+ - Mutant::Runner#visit_collection
91
96
  - Mutant::Zombifier::File#self.find
92
97
  - Mutant::RequireHighjack#infect
98
+ - Mutant::Reporter::CLI::Registry#included
99
+ - Mutant::Rspec::Strategy#new_reporter
100
+ - Mutant::Rspec::Strategy#run
93
101
  # How mutant does CLI parsing is shit
94
102
  - Mutant::CLI#parse
95
103
  - Mutant::CLI#initialize
@@ -139,6 +147,7 @@ UtilityFunction:
139
147
  - Mutant::Mutation::Neutral#success?
140
148
  - Mutant::NodeHelpers#s
141
149
  - Mutant::Rspec::Strategy#configuration
150
+ - Mutant::Rspec::Strategy#example_groups
142
151
  - Mutant::Rspec::Strategy#options
143
152
  - Mutant::Rspec::Strategy#world
144
153
  - Mutant::Rspec::Strategy#rspec2
@@ -99,6 +99,10 @@ IndentationWidth:
99
99
  EmptyLinesAroundBody:
100
100
  Enabled: false
101
101
 
102
+ # I test this style for a while
103
+ LambdaCall:
104
+ Enabled: false
105
+
102
106
  # I like my style more
103
107
  AccessModifierIndentation:
104
108
  Enabled: false
@@ -5,7 +5,6 @@ require 'set'
5
5
  require 'adamantium'
6
6
  require 'ice_nine'
7
7
  require 'abstract_type'
8
- require 'securerandom'
9
8
  require 'equalizer'
10
9
  require 'digest/sha1'
11
10
  require 'inflecto'
@@ -38,18 +37,42 @@ module Mutant
38
37
  self
39
38
  end
40
39
 
41
- # Return a frozen set of symbols from string enumerable
40
+ IsolationError = Class.new(RuntimeError)
41
+
42
+ # Call block in isolation
42
43
  #
43
- # @param [Enumerable<String>]
44
+ # This isolation implements the fork strategy.
45
+ # Future strategies will probably use a process pool that can
46
+ # handle multiple mutation kills, in-isolation at once.
44
47
  #
45
- # @return [Set<Symbol>]
48
+ # @return [Object]
46
49
  #
47
50
  # @api private
48
51
  #
49
- def self.symbolset(strings)
50
- strings.map(&:to_sym).to_set.freeze
52
+ def self.isolate(&block)
53
+ reader, writer = IO.pipe
54
+
55
+ pid = fork do
56
+ reader.close
57
+ writer.write(Marshal.dump(block.call))
58
+ end
59
+
60
+ writer.close
61
+
62
+ begin
63
+ data = Marshal.load(reader.read)
64
+ rescue ArgumentError
65
+ raise IsolationError, 'Childprocess wrote un-unmarshallable data'
66
+ end
67
+
68
+ status = Process.waitpid2(pid).last
69
+
70
+ unless status.exitstatus.zero?
71
+ raise IsolationError, "Childprocess exited with nonzero exit status: #{status.exitstatus}"
72
+ end
73
+
74
+ data
51
75
  end
52
- private_class_method :symbolset
53
76
 
54
77
  # Define instance of subclassed superclass as constant
55
78
  #
@@ -79,11 +102,11 @@ end # Mutant
79
102
 
80
103
  require 'mutant/version'
81
104
  require 'mutant/cache'
105
+ require 'mutant/delegator'
82
106
  require 'mutant/node_helpers'
83
107
  require 'mutant/warning_filter'
84
108
  require 'mutant/warning_expectation'
85
109
  require 'mutant/constants'
86
- require 'mutant/random'
87
110
  require 'mutant/walker'
88
111
  require 'mutant/require_highjack'
89
112
  require 'mutant/mutator'
@@ -164,27 +187,33 @@ require 'mutant/matcher/scope'
164
187
  require 'mutant/matcher/filter'
165
188
  require 'mutant/matcher/null'
166
189
  require 'mutant/killer'
167
- require 'mutant/killer/static'
168
- require 'mutant/killer/forking'
169
- require 'mutant/killer/forked'
190
+ require 'mutant/test'
170
191
  require 'mutant/strategy'
171
192
  require 'mutant/runner'
172
193
  require 'mutant/runner/config'
173
194
  require 'mutant/runner/subject'
174
195
  require 'mutant/runner/mutation'
196
+ require 'mutant/runner/killer'
175
197
  require 'mutant/cli'
176
198
  require 'mutant/cli/classifier'
177
199
  require 'mutant/cli/classifier/namespace'
178
200
  require 'mutant/cli/classifier/method'
179
201
  require 'mutant/color'
180
- require 'mutant/differ'
202
+ require 'mutant/diff'
181
203
  require 'mutant/reporter'
182
204
  require 'mutant/reporter/null'
205
+ require 'mutant/reporter/trace'
183
206
  require 'mutant/reporter/cli'
207
+ require 'mutant/reporter/cli/registry'
184
208
  require 'mutant/reporter/cli/printer'
185
- require 'mutant/reporter/cli/printer/config'
186
- require 'mutant/reporter/cli/printer/subject'
187
- require 'mutant/reporter/cli/printer/killer'
188
- require 'mutant/reporter/cli/printer/mutation'
209
+ require 'mutant/reporter/cli/report'
210
+ require 'mutant/reporter/cli/report/config'
211
+ require 'mutant/reporter/cli/report/subject'
212
+ require 'mutant/reporter/cli/report/mutation'
213
+ require 'mutant/reporter/cli/progress'
214
+ require 'mutant/reporter/cli/progress/config'
215
+ require 'mutant/reporter/cli/progress/subject'
216
+ require 'mutant/reporter/cli/progress/mutation'
217
+ require 'mutant/reporter/cli/progress/noop'
189
218
  require 'mutant/zombifier'
190
219
  require 'mutant/zombifier/file'
@@ -2,23 +2,23 @@
2
2
 
3
3
  module Mutant
4
4
 
5
+ symbolset = ->(strings) { strings.map(&:to_sym).to_set.freeze }
6
+
5
7
  # Set of nodes that cannot be on the LHS of an assignment
6
- NOT_ASSIGNABLE = symbolset %w(
7
- int float str dstr class module self
8
- )
8
+ NOT_ASSIGNABLE = symbolset.(%w(int float str dstr class module self))
9
9
 
10
10
  # Set of op-assign types
11
- OP_ASSIGN = symbolset %w(or_asgn and_asgn op_asgn)
11
+ OP_ASSIGN = symbolset.call(%w(or_asgn and_asgn op_asgn))
12
12
  # Set of node types that are not valid when emitted standalone
13
- NOT_STANDALONE = symbolset %w( splat restarg block_pass)
14
- INDEX_OPERATORS = symbolset %w([] []=)
15
- UNARY_METHOD_OPERATORS = symbolset %w(~@ +@ -@ !)
13
+ NOT_STANDALONE = symbolset.(%w( splat restarg block_pass))
14
+ INDEX_OPERATORS = symbolset.(%w([] []=))
15
+ UNARY_METHOD_OPERATORS = symbolset.(%w(~@ +@ -@ !))
16
16
 
17
17
  # Operators ruby implementeds as methods
18
- METHOD_OPERATORS = symbolset %w(
18
+ METHOD_OPERATORS = symbolset.(%w(
19
19
  <=> === []= [] <= >= == !~ != =~ <<
20
20
  >> ** * % / | ^ & < > + - ~@ +@ -@ !
21
- )
21
+ ))
22
22
 
23
23
  BINARY_METHOD_OPERATORS = (
24
24
  METHOD_OPERATORS - (INDEX_OPERATORS + UNARY_METHOD_OPERATORS)
@@ -32,10 +32,10 @@ module Mutant
32
32
  #
33
33
  # not - 1.8 only, mutant does not support 1.8
34
34
  #
35
- NODE_BLACKLIST = symbolset %w(not)
35
+ NODE_BLACKLIST = symbolset.(%w(not))
36
36
 
37
37
  # Nodes that are NOT generated by parser but used by mutant / unparser.
38
- NODE_EXTRA = symbolset %w(empty)
38
+ NODE_EXTRA = symbolset.(%w(empty))
39
39
 
40
40
  NODE_TYPES = ((Parser::Meta::NODE_TYPES + NODE_EXTRA) - NODE_BLACKLIST).to_set.freeze
41
41
 
@@ -0,0 +1,50 @@
1
+ module Mutant
2
+ module Delegator
3
+ module ClassMethods
4
+
5
+ private
6
+
7
+ # Create delegators to object
8
+ #
9
+ # @return [undefined]
10
+ #
11
+ # @api private
12
+ #
13
+ def delegate(*names)
14
+ names.each do |name|
15
+ define_delegator(name)
16
+ end
17
+ end
18
+
19
+ # Create delegator to object
20
+ #
21
+ # @param [Symbol] name
22
+ #
23
+ # @return [undefined]
24
+ #
25
+ # @api private
26
+ #
27
+ def define_delegator(name)
28
+ define_method(name) do
29
+ object.public_send(name)
30
+ end
31
+ private name
32
+ end
33
+
34
+ end # ClassMethods
35
+
36
+ # Hook called when module is included
37
+ #
38
+ # @param [Class,Module] host
39
+ #
40
+ # @api private
41
+ #
42
+ def self.included(host)
43
+ super
44
+ host.class_eval do
45
+ extend ClassMethods
46
+ end
47
+ end
48
+
49
+ end # Delegator
50
+ end # Mutant
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Mutant
4
4
  # Class to create diffs from source code
5
- class Differ
5
+ class Diff
6
6
  include Adamantium::Flat, Concord.new(:old, :new)
7
7
 
8
8
  # Return source diff
@@ -20,7 +20,7 @@ module Mutant
20
20
  when 0
21
21
  nil
22
22
  when 1
23
- Diff::LCS::Hunk.new(old, new, diffs.first, max_length, 0)
23
+ ::Diff::LCS::Hunk.new(old, new, diffs.first, max_length, 0)
24
24
  .diff(:unified) << "\n"
25
25
  else
26
26
  $stderr.puts(
@@ -55,7 +55,7 @@ module Mutant
55
55
  # @param [String] old
56
56
  # @param [String] new
57
57
  #
58
- # @return [Differ]
58
+ # @return [Diff]
59
59
  #
60
60
  # @api private
61
61
  #
@@ -85,7 +85,7 @@ module Mutant
85
85
  # @api private
86
86
  #
87
87
  def diffs
88
- Diff::LCS.diff(old, new)
88
+ ::Diff::LCS.diff(old, new)
89
89
  end
90
90
  memoize :diffs
91
91
 
@@ -118,5 +118,5 @@ module Mutant
118
118
  end.format(line)
119
119
  end
120
120
 
121
- end # Differ
121
+ end # Diff
122
122
  end # Mutant
@@ -1,123 +1,46 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Mutant
4
- # Abstract base class for mutant killers
4
+ # Mutation killer
5
5
  class Killer
6
- include Adamantium::Flat, AbstractType
7
- include Equalizer.new(:strategy, :mutation, :killed?)
6
+ include Adamantium::Flat, Anima.new(:test, :mutation)
8
7
 
9
- # Return strategy
10
- #
11
- # @return [Strategy]
12
- #
13
- # @api private
14
- #
15
- attr_reader :strategy
16
-
17
- # Return mutation to kill
18
- #
19
- # @return [Mutation]
20
- #
21
- # @api private
22
- #
23
- attr_reader :mutation
24
-
25
- # Initialize killer object
26
- #
27
- # @param [Strategy] strategy
28
- # @param [Mutation] mutation
29
- #
30
- # @return [undefined]
31
- #
32
- # @api private
33
- #
34
- def initialize(strategy, mutation)
35
- @strategy, @mutation = strategy, mutation
36
- @killed = run
37
- end
38
-
39
- # Test for kill failure
40
- #
41
- # @return [true]
42
- # when killer succeeded
43
- #
44
- # @return [false]
45
- # otherwise
46
- #
47
- # @api private
48
- #
49
- def success?
50
- mutation.success?(self)
51
- end
52
- memoize :success?
53
-
54
- # Test if mutant was killed
55
- #
56
- # @return [true]
57
- # if mutant was killed
58
- #
59
- # @return [false]
60
- # otherwise
61
- #
62
- # @api private
63
- #
64
- def killed?
65
- @killed
66
- end
67
-
68
- # Return mutated source
69
- #
70
- # @return [String]
71
- #
72
- # @api private
73
- #
74
- def mutation_source
75
- mutation.source
76
- end
8
+ # Report object for kill results
9
+ class Report
10
+ include Anima.new(
11
+ :killer,
12
+ :test_report
13
+ )
77
14
 
78
- private
15
+ # Test if kill was successful
16
+ #
17
+ # @return [Boolean]
18
+ #
19
+ # @api private
20
+ #
21
+ def success?
22
+ killer.mutation.should_fail?.equal?(test_report.failed?)
23
+ end
79
24
 
80
- # Return subject
81
- #
82
- # @return [Subject]
83
- #
84
- # @api private
85
- #
86
- def subject
87
- mutation.subject
88
- end
25
+ end # Report
89
26
 
90
- # Run killer
27
+ # Return killer report
91
28
  #
92
- # @return [true]
93
- # when mutant was killed
94
- #
95
- # @return [false]
96
- # otherwise
29
+ # @return [Killer::Report]
97
30
  #
98
31
  # @api private
99
32
  #
100
- abstract_method :run
101
-
102
- # Null killer that never kills a mutation
103
- class Null < self
104
-
105
- private
106
-
107
- # Run killer
108
- #
109
- # @return [true]
110
- # when mutant was killed
111
- #
112
- # @return [false]
113
- # otherwise
114
- #
115
- # @api private
116
- #
117
- def run
118
- false
33
+ def run
34
+ test_report = Mutant.isolate do
35
+ mutation.insert
36
+ test.run
119
37
  end
120
38
 
39
+ Report.new(
40
+ killer: self,
41
+ test_report: test_report.update(test: test)
42
+ )
121
43
  end
44
+
122
45
  end # Killer
123
46
  end # Mutant