mutant 0.5.24 → 0.5.25

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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +8 -0
  3. data/config/flay.yml +1 -1
  4. data/config/flog.yml +1 -1
  5. data/config/reek.yml +15 -13
  6. data/lib/mutant.rb +28 -12
  7. data/lib/mutant/ast/meta.rb +0 -10
  8. data/lib/mutant/ast/named_children.rb +1 -0
  9. data/lib/mutant/ast/types.rb +5 -5
  10. data/lib/mutant/cli.rb +84 -64
  11. data/lib/mutant/config.rb +7 -39
  12. data/lib/mutant/delegator.rb +2 -0
  13. data/lib/mutant/env.rb +119 -16
  14. data/lib/mutant/expression.rb +8 -2
  15. data/lib/mutant/expression/method.rb +6 -16
  16. data/lib/mutant/expression/methods.rb +5 -5
  17. data/lib/mutant/expression/namespace.rb +7 -7
  18. data/lib/mutant/integration.rb +0 -10
  19. data/lib/mutant/isolation.rb +41 -15
  20. data/lib/mutant/matcher/chain.rb +1 -17
  21. data/lib/mutant/matcher/compiler.rb +108 -0
  22. data/lib/mutant/matcher/config.rb +28 -0
  23. data/lib/mutant/matcher/method.rb +1 -1
  24. data/lib/mutant/matcher/namespace.rb +5 -52
  25. data/lib/mutant/matcher/null.rb +1 -1
  26. data/lib/mutant/matcher/scope.rb +1 -1
  27. data/lib/mutant/mutation.rb +29 -13
  28. data/lib/mutant/mutator/node.rb +2 -12
  29. data/lib/mutant/mutator/node/named_value/variable_assignment.rb +1 -1
  30. data/lib/mutant/reporter/cli.rb +0 -2
  31. data/lib/mutant/reporter/cli/printer.rb +14 -0
  32. data/lib/mutant/reporter/cli/progress.rb +1 -3
  33. data/lib/mutant/reporter/cli/progress/config.rb +5 -9
  34. data/lib/mutant/reporter/cli/progress/env.rb +30 -0
  35. data/lib/mutant/reporter/cli/progress/noop.rb +4 -1
  36. data/lib/mutant/reporter/cli/progress/result.rb +12 -0
  37. data/lib/mutant/reporter/cli/progress/result/mutation.rb +45 -0
  38. data/lib/mutant/reporter/cli/progress/result/subject.rb +54 -0
  39. data/lib/mutant/reporter/cli/progress/subject.rb +7 -90
  40. data/lib/mutant/reporter/cli/registry.rb +2 -0
  41. data/lib/mutant/reporter/cli/report/env.rb +92 -0
  42. data/lib/mutant/reporter/cli/report/mutation.rb +58 -77
  43. data/lib/mutant/reporter/cli/report/subject.rb +4 -3
  44. data/lib/mutant/reporter/cli/report/test.rb +28 -0
  45. data/lib/mutant/reporter/null.rb +1 -1
  46. data/lib/mutant/reporter/trace.rb +16 -3
  47. data/lib/mutant/result.rb +302 -0
  48. data/lib/mutant/runner.rb +77 -123
  49. data/lib/mutant/subject.rb +32 -16
  50. data/lib/mutant/subject/method.rb +0 -15
  51. data/lib/mutant/subject/method/instance.rb +3 -3
  52. data/lib/mutant/version.rb +1 -1
  53. data/lib/mutant/warning_expectation.rb +12 -5
  54. data/spec/integration/mutant/corpus_spec.rb +1 -1
  55. data/spec/spec_helper.rb +5 -1
  56. data/spec/unit/mutant/cli_spec.rb +248 -0
  57. data/spec/unit/mutant/expression/namespace/flat_spec.rb +1 -1
  58. data/spec/unit/mutant/expression_spec.rb +55 -0
  59. data/spec/unit/mutant/integration_spec.rb +0 -5
  60. data/spec/unit/mutant/isolation_spec.rb +36 -5
  61. data/spec/unit/mutant/matcher/chain_spec.rb +1 -13
  62. data/spec/unit/mutant/matcher/compiler_spec.rb +95 -0
  63. data/spec/unit/mutant/matcher/filter_spec.rb +31 -0
  64. data/spec/unit/mutant/matcher/method/instance_spec.rb +33 -2
  65. data/spec/unit/mutant/matcher/method/singleton_spec.rb +1 -1
  66. data/spec/unit/mutant/matcher/methods/instance_spec.rb +1 -1
  67. data/spec/unit/mutant/matcher/methods/singleton_spec.rb +1 -1
  68. data/spec/unit/mutant/matcher/namespace_spec.rb +10 -6
  69. data/spec/unit/mutant/matcher/null_spec.rb +26 -0
  70. data/spec/unit/mutant/reporter/cli_spec.rb +337 -0
  71. data/spec/unit/mutant/reporter/null_spec.rb +12 -0
  72. data/spec/unit/mutant/runner_spec.rb +130 -0
  73. data/spec/unit/mutant/subject/context_spec.rb +4 -3
  74. data/spec/unit/mutant/subject/method/instance_spec.rb +5 -3
  75. data/spec/unit/mutant/subject/method/singleton_spec.rb +3 -2
  76. data/spec/unit/mutant/subject_spec.rb +36 -1
  77. data/spec/unit/mutant/test_spec.rb +25 -0
  78. data/spec/unit/mutant/warning_expectation.rb +11 -8
  79. data/spec/unit/mutant_spec.rb +11 -2
  80. metadata +27 -28
  81. data/lib/mutant/killer.rb +0 -44
  82. data/lib/mutant/matcher/builder.rb +0 -142
  83. data/lib/mutant/mutation/evil.rb +0 -23
  84. data/lib/mutant/mutation/neutral.rb +0 -18
  85. data/lib/mutant/reporter/cli/progress/mutation.rb +0 -46
  86. data/lib/mutant/reporter/cli/report/config.rb +0 -116
  87. data/lib/mutant/rspec.rb +0 -0
  88. data/lib/mutant/runner/config.rb +0 -138
  89. data/lib/mutant/runner/killer.rb +0 -75
  90. data/lib/mutant/runner/mutation.rb +0 -78
  91. data/lib/mutant/runner/subject.rb +0 -85
  92. data/lib/mutant/test/report.rb +0 -59
  93. data/spec/unit/mutant/cli_new_spec.rb +0 -147
  94. data/spec/unit/mutant/cli_run_spec.rb +0 -46
  95. data/spec/unit/mutant/runner/config_spec.rb +0 -157
  96. data/spec/unit/mutant/runner/mutation_spec.rb +0 -101
  97. data/spec/unit/mutant/runner/subject_spec.rb +0 -59
  98. data/spec/unit/mutant/subject/mutations_spec.rb +0 -23
  99. data/spec/unit/mutant/subject/node_spec.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2af74623c08acfc217b54ebc8701ac11c122f243
4
- data.tar.gz: c9899c8efaad75e829ebf634095a4e88ca72e693
3
+ metadata.gz: 8b47d52ad659d548654d47fb3905ad423021b7a2
4
+ data.tar.gz: b3e197edb631419fbe793d8477b2cb9e0975cf0d
5
5
  SHA512:
6
- metadata.gz: 9f0f560faa4d8771649af1baef4ff2dd56c6d1a618ad7e4c640dbfcfc2f4e80b6c7963474e89f799a0f2ba1446a14a55dcab35c62653ce34462d042ca653d9dd
7
- data.tar.gz: b2d1eb8f58ce5b1a9278e11456742853940c44c4cad7bb5ecaabb01e411576beab12fcdcc419899a2b8a33bd7afa36ea4b7eedc16995728861d38a580e6f13c5
6
+ metadata.gz: 7c52c83d2d637d3f6f6baa01da3f5536d513b57247fce771af24a75e46a83eda62b94ab222075fc4908becf899ab33bb5def7c96c68453ccc6226545bb376fb2
7
+ data.tar.gz: d856b74e68b9c588a8fd518738fe237ab1ba4887da2bcf6346ad17b8329981e9d8f818d45383e5b6ea64118b8c8b6c6a722a6587d30d1cf9c68baded825d073a
@@ -1,3 +1,11 @@
1
+ # v0.5.25 2014-07-07
2
+
3
+ * Make ordering of subjects and tests deterministic
4
+ * Fix performance of subject selection
5
+ * Improve noop and neutral reporting.
6
+ * Rename noop mutations to neutral mutations
7
+ * Simplify code nuked around 1kloc.
8
+
1
9
  # v0.5.24 2014-06-30
2
10
 
3
11
  * Fix invalid AST on op_assign mutations
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 18
3
- total_score: 973
3
+ total_score: 1040
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 29.6
2
+ threshold: 29.3
@@ -25,19 +25,20 @@ DuplicateMethodCall:
25
25
  FeatureEnvy:
26
26
  enabled: true
27
27
  exclude:
28
+ # Nature of OptionParser :(
29
+ - Mutant::CLI#add_environment_options
30
+ - Mutant::Env#scope_name
31
+ - Mutant::Integration::Rspec#run
28
32
  - Mutant::Integration::Rspec2#full_description
29
33
  - Mutant::Integration::Rspec3#full_description
30
34
  - Mutant::Matcher::Method::Instance#match?
31
35
  - Mutant::Matcher::Method::Singleton#receiver?
32
- - Mutant::Matcher::Namespace#scope_name
33
36
  - Mutant::Mutation::Evil#success?
34
37
  - Mutant::Mutation::Neutral#success?
35
- - Mutant::Reporter::CLI#subject_results
36
- # Nature of OptionParser :(
37
- - Mutant::CLI#add_environmental_options
38
- - Mutant::CLI#parse
39
38
  # False positive, its a utility
40
39
  - Mutant::Meta::Example::Verification#format_mutation
40
+ - Mutant::Reporter::CLI#subject_results
41
+ - Mutant::Runner#run_mutation_test
41
42
  IrresponsibleModule:
42
43
  enabled: true
43
44
  exclude: []
@@ -56,14 +57,15 @@ NestedIterators:
56
57
  exclude:
57
58
  - Mutant#self.singleton_subclass_instance
58
59
  - Mutant::CLI#parse
60
+ - Mutant::Integration::Rspec#run
59
61
  - Mutant::Mutator::Util::Array::Element#dispatch
60
62
  - Mutant::Mutator::Node::Resbody#mutate_captures
61
63
  - Mutant::Mutator::Node::Arguments#emit_argument_mutations
62
- - Mutant::Reporter::CLI::Report::Config#generic_stats
64
+ - Mutant::Reporter::CLI::Report::Env#generic_stats
63
65
  - Mutant::RequireHighjack#infect
64
66
  - Mutant::RequireHighjack#desinfect
65
67
  - Mutant::Reporter::CLI::Registry#included
66
- - Mutant::Config#tests
68
+ - Mutant::Subject#tests
67
69
  - Parser::Lexer#self.new
68
70
  max_allowed_nesting: 1
69
71
  ignore_iterators: []
@@ -82,12 +84,12 @@ TooManyInstanceVariables:
82
84
  - Mutant::CLI # 4 vars
83
85
  - Mutant::Killer # 4 vars
84
86
  - Mutant::Mutator # 4 vars
85
- - Mutant::Runner # 4 vars
86
87
  max_instance_variables: 3
87
88
  TooManyMethods:
88
89
  enabled: true
89
90
  exclude:
90
91
  - Mutant::CLI
92
+ - Mutant::Subject
91
93
  - Mutant::Mutator::Node
92
94
  - Mutant::Reporter::CLI
93
95
  - Mutant::Meta::Example::Verification
@@ -96,7 +98,8 @@ TooManyStatements:
96
98
  enabled: true
97
99
  exclude:
98
100
  - Mutant#self.singleton_subclass_instance
99
- - Mutant::Reporter::CLI::Report::Config#run
101
+ - Mutant::Integration::Rspec#run
102
+ - Mutant::Reporter::CLI::Report::Env#run
100
103
  - Mutant::Reporter::CLI::Registry#included
101
104
  - Mutant::Reporter::CLI#colorized_diff
102
105
  - Mutant::RequireHighjack#infect
@@ -105,10 +108,8 @@ TooManyStatements:
105
108
  - Mutant::Runner#initialize
106
109
  - Mutant::Runner::Mutation#run
107
110
  - Mutant::Zombifier::File#self.find
108
- # How mutant does CLI parsing is shit
109
- - Mutant::CLI#parse
110
- - Mutant::CLI#initialize
111
111
  - Mutant::CLI#add_debug_options
112
+ - Mutant::CLI#add_environment_options
112
113
  max_statements: 7
113
114
  UncommunicativeMethodName:
114
115
  enabled: true
@@ -151,6 +152,7 @@ UnusedParameters:
151
152
  UtilityFunction:
152
153
  enabled: true
153
154
  exclude:
155
+ - Mutant::AST::Sexp#s
154
156
  - Mutant::CLI#reporter
155
157
  - Mutant::Integration::Rspec#configuration
156
158
  - Mutant::Integration::Rspec#options
@@ -160,5 +162,5 @@ UtilityFunction:
160
162
  - Mutant::Meta::Example::Verification#format_mutation
161
163
  - Mutant::Mutation::Evil#success?
162
164
  - Mutant::Mutation::Neutral#success?
163
- - Mutant::AST::Sexp#s
165
+ - Mutant::Runner#run_mutation_test
164
166
  max_helper_calls: 0
@@ -96,8 +96,6 @@ require 'mutant/require_highjack'
96
96
  require 'mutant/isolation'
97
97
  require 'mutant/mutator'
98
98
  require 'mutant/mutation'
99
- require 'mutant/mutation/evil'
100
- require 'mutant/mutation/neutral'
101
99
  require 'mutant/mutator/registry'
102
100
  require 'mutant/mutator/util'
103
101
  require 'mutant/mutator/util/array'
@@ -165,7 +163,8 @@ require 'mutant/subject/method'
165
163
  require 'mutant/subject/method/instance'
166
164
  require 'mutant/subject/method/singleton'
167
165
  require 'mutant/matcher'
168
- require 'mutant/matcher/builder'
166
+ require 'mutant/matcher/config'
167
+ require 'mutant/matcher/compiler'
169
168
  require 'mutant/matcher/chain'
170
169
  require 'mutant/matcher/method'
171
170
  require 'mutant/matcher/method/finder'
@@ -180,18 +179,12 @@ require 'mutant/expression'
180
179
  require 'mutant/expression/method'
181
180
  require 'mutant/expression/methods'
182
181
  require 'mutant/expression/namespace'
183
- require 'mutant/killer'
184
182
  require 'mutant/test'
185
- require 'mutant/test/report'
186
183
  require 'mutant/integration'
187
- require 'mutant/runner'
188
- require 'mutant/runner/config'
189
- require 'mutant/runner/subject'
190
- require 'mutant/runner/mutation'
191
- require 'mutant/runner/killer'
192
184
  require 'mutant/cli'
193
185
  require 'mutant/color'
194
186
  require 'mutant/diff'
187
+ require 'mutant/result'
195
188
  require 'mutant/reporter'
196
189
  require 'mutant/reporter/null'
197
190
  require 'mutant/reporter/trace'
@@ -199,13 +192,36 @@ require 'mutant/reporter/cli'
199
192
  require 'mutant/reporter/cli/registry'
200
193
  require 'mutant/reporter/cli/printer'
201
194
  require 'mutant/reporter/cli/report'
202
- require 'mutant/reporter/cli/report/config'
195
+ require 'mutant/reporter/cli/report/env'
203
196
  require 'mutant/reporter/cli/report/subject'
204
197
  require 'mutant/reporter/cli/report/mutation'
198
+ require 'mutant/reporter/cli/report/test'
205
199
  require 'mutant/reporter/cli/progress'
200
+ require 'mutant/reporter/cli/progress/env'
206
201
  require 'mutant/reporter/cli/progress/config'
207
202
  require 'mutant/reporter/cli/progress/subject'
208
- require 'mutant/reporter/cli/progress/mutation'
209
203
  require 'mutant/reporter/cli/progress/noop'
204
+ require 'mutant/reporter/cli/progress/result'
205
+ require 'mutant/reporter/cli/progress/result/mutation'
206
+ require 'mutant/reporter/cli/progress/result/subject'
207
+ require 'mutant/runner'
210
208
  require 'mutant/zombifier'
211
209
  require 'mutant/zombifier/file'
210
+
211
+ module Mutant
212
+ # Repoen class to initialize constant to avoid dep circle
213
+ class Config
214
+ DEFAULT = new(
215
+ debug: false,
216
+ fail_fast: false,
217
+ integration: Integration::Null.new,
218
+ matcher_config: Matcher::Config::DEFAULT,
219
+ includes: [],
220
+ requires: [],
221
+ isolation: Mutant::Isolation::Fork,
222
+ reporter: Reporter::CLI.new($stdout),
223
+ zombie: false,
224
+ expected_coverage: 100.0
225
+ )
226
+ end # Config
227
+ end # Mutant
@@ -76,16 +76,6 @@ module Mutant
76
76
  arguments.one? && Types::BINARY_METHOD_OPERATORS.include?(selector)
77
77
  end
78
78
 
79
- # Test if node is part of an mlhs
80
- #
81
- # @return [Boolean]
82
- #
83
- # @api private
84
- #
85
- def mlhs?
86
- (index_assignment_selector? && arguments.one?) || (arguments.empty? && attribute_assignment_selector?)
87
- end
88
-
89
79
  private
90
80
 
91
81
  # Test for index assignment operator
@@ -14,6 +14,7 @@ module Mutant
14
14
  #
15
15
  def self.included(host)
16
16
  super
17
+
17
18
  host.class_eval do
18
19
  include InstanceMethods
19
20
  extend ClassMethods
@@ -24,13 +24,13 @@ module Mutant
24
24
  >> ** * % / | ^ & < > + - ~@ +@ -@ !
25
25
  ])
26
26
 
27
- BINARY_METHOD_OPERATORS = (
27
+ BINARY_METHOD_OPERATORS = symbolset.(
28
28
  METHOD_OPERATORS - (INDEX_OPERATORS + UNARY_METHOD_OPERATORS)
29
- ).to_set.freeze
29
+ )
30
30
 
31
- OPERATOR_METHODS = (
31
+ OPERATOR_METHODS = symbolset.(
32
32
  METHOD_OPERATORS + INDEX_OPERATORS + UNARY_METHOD_OPERATORS
33
- ).to_set.freeze
33
+ )
34
34
 
35
35
  # Nodes that are NOT handled by mutant.
36
36
  #
@@ -42,7 +42,7 @@ module Mutant
42
42
  EXTRA = symbolset.(%w[empty])
43
43
 
44
44
  # All node types mutant handles
45
- ALL = ((Parser::Meta::NODE_TYPES + EXTRA) - BLACKLIST).to_set.freeze
45
+ ALL = symbolset.((Parser::Meta::NODE_TYPES + EXTRA) - BLACKLIST)
46
46
  end # Types
47
47
  end # AST
48
48
  end # Mutant
@@ -4,9 +4,9 @@ module Mutant
4
4
 
5
5
  # Comandline parser
6
6
  class CLI
7
- include Adamantium::Flat, Equalizer.new(:config)
7
+ include Adamantium::Flat, Equalizer.new(:config), Procto.call(:config)
8
8
 
9
- # Error raised when CLI argv is invalid
9
+ # Error faild when CLI argv is invalid
10
10
  Error = Class.new(RuntimeError)
11
11
 
12
12
  EXIT_FAILURE = 1
@@ -22,9 +22,7 @@ module Mutant
22
22
  # @api private
23
23
  #
24
24
  def self.run(arguments)
25
- config = new(arguments).config
26
- runner = Runner::Config.run(config)
27
- runner.success? ? EXIT_SUCCESS : EXIT_FAILURE
25
+ Env.call(call(arguments)).success? ? EXIT_SUCCESS : EXIT_FAILURE
28
26
  rescue Error => exception
29
27
  $stderr.puts(exception.message)
30
28
  EXIT_FAILURE
@@ -38,21 +36,10 @@ module Mutant
38
36
  #
39
37
  # @api private
40
38
  #
41
- def initialize(arguments = [])
42
- @builder = Matcher::Builder.new(Env::Boot.new(Reporter::CLI.new($stderr), Cache.new))
43
- @debug = @fail_fast = @zombie = false
44
- @expected_coverage = 100.0
45
- @integration = Integration::Null.new
39
+ def initialize(arguments)
40
+ @config = Config::DEFAULT
41
+
46
42
  parse(arguments)
47
- @config = Config.new(
48
- zombie: @zombie,
49
- debug: @debug,
50
- matcher: @builder.matcher,
51
- integration: @integration,
52
- fail_fast: @fail_fast,
53
- reporter: Reporter::CLI.new($stdout),
54
- expected_coverage: @expected_coverage
55
- )
56
43
  end
57
44
 
58
45
  # Return config
@@ -70,7 +57,7 @@ module Mutant
70
57
  # @param [Array<String>] arguments
71
58
  # Command-line options and arguments to be parsed.
72
59
  #
73
- # @raise [Error]
60
+ # @fail [Error]
74
61
  # An error occurred while parsing the options.
75
62
  #
76
63
  # @return [undefined]
@@ -79,22 +66,15 @@ module Mutant
79
66
  #
80
67
  def parse(arguments)
81
68
  opts = OptionParser.new do |builder|
82
- builder.banner = 'usage: mutant STRATEGY [options] PATTERN ...'
83
- builder.separator('')
84
- add_environmental_options(builder)
85
- add_mutation_options(builder)
86
- add_filter_options(builder)
87
- add_debug_options(builder)
88
- end
89
-
90
- patterns =
91
- begin
92
- opts.parse!(arguments)
93
- rescue OptionParser::ParseError => error
94
- raise(Error, error.message, error.backtrace)
69
+ builder.banner = 'usage: mutant [options] MATCH_EXPRESSION ...'
70
+ %w[add_environment_options add_mutation_options add_filter_options add_debug_options].each do |name|
71
+ send(name, builder)
95
72
  end
73
+ end
96
74
 
97
- parse_matchers(patterns)
75
+ parse_match_expressions(opts.parse!(arguments))
76
+ rescue OptionParser::ParseError => error
77
+ fail(Error, error.message, error.backtrace)
98
78
  end
99
79
 
100
80
  # Parse matchers
@@ -105,10 +85,11 @@ module Mutant
105
85
  #
106
86
  # @api private
107
87
  #
108
- def parse_matchers(patterns)
109
- raise Error, 'No patterns given' if patterns.empty?
110
- patterns.each do |pattern|
111
- @builder.add_match_expression(Expression.parse(pattern))
88
+ def parse_match_expressions(expressions)
89
+ fail Error, 'No expressions given' if expressions.empty?
90
+
91
+ expressions.map(&Expression.method(:parse)).each do |expression|
92
+ add_matcher(:match_expressions, expression)
112
93
  end
113
94
  end
114
95
 
@@ -120,21 +101,20 @@ module Mutant
120
101
  #
121
102
  # @api private
122
103
  #
123
- def add_environmental_options(opts)
124
- opts.separator('')
104
+ def add_environment_options(opts)
125
105
  opts.separator('Environment:')
126
106
  opts.on('--zombie', 'Run mutant zombified') do
127
- @zombie = true
128
- end.on('-I', '--include DIRECTORY', 'Add DIRECTORY to $LOAD_PATH') do |directory|
129
- $LOAD_PATH << directory
130
- end.on('-r', '--require NAME', 'Require file with NAME') do |name|
131
- require(name)
107
+ update(zombie: true)
108
+ end
109
+ opts.on('-I', '--include DIRECTORY', 'Add DIRECTORY to $LOAD_PATH') do |directory|
110
+ add(:includes, directory)
111
+ end
112
+ opts.on('-r', '--require NAME', 'Require file with NAME') do |name|
113
+ add(:requires, name)
132
114
  end
133
115
  end
134
116
 
135
- # Use plugin
136
- #
137
- # FIXME: For now all plugins are strategies. Later they could be anything that allows "late integration".
117
+ # Use integration
138
118
  #
139
119
  # @param [String] name
140
120
  #
@@ -142,12 +122,9 @@ module Mutant
142
122
  #
143
123
  # @api private
144
124
  #
145
- def use(name)
125
+ def setup_integration(name)
146
126
  require "mutant/integration/#{name}"
147
- @integration = Integration.lookup(name).new
148
- rescue LoadError
149
- $stderr.puts("Cannot load plugin: #{name.inspect}")
150
- raise
127
+ update(integration: Integration.lookup(name).new)
151
128
  end
152
129
 
153
130
  # Add options
@@ -163,10 +140,8 @@ module Mutant
163
140
  opts.separator('Options:')
164
141
 
165
142
  opts.on('--score COVERAGE', 'Fail unless COVERAGE is not reached exactly') do |coverage|
166
- @expected_coverage = Float(coverage)
167
- end.on('--use STRATEGY', 'Use STRATEGY for killing mutations') do |runner|
168
- use(runner)
169
- end
143
+ update(expected_coverage: Float(coverage))
144
+ end.on('--use STRATEGY', 'Use STRATEGY for killing mutations', &method(:setup_integration))
170
145
  end
171
146
 
172
147
  # Add filter options
@@ -179,10 +154,10 @@ module Mutant
179
154
  #
180
155
  def add_filter_options(opts)
181
156
  opts.on('--ignore-subject PATTERN', 'Ignore subjects that match PATTERN') do |pattern|
182
- @builder.add_subject_ignore(Expression.parse(pattern))
157
+ add_matcher(:subject_ignores, Expression.parse(pattern))
183
158
  end
184
159
  opts.on('--code CODE', 'Scope execution to subjects with CODE') do |code|
185
- @builder.add_subject_selector(:code, code)
160
+ add_matcher(:subject_selects, [:code, code])
186
161
  end
187
162
  end
188
163
 
@@ -196,16 +171,61 @@ module Mutant
196
171
  #
197
172
  def add_debug_options(opts)
198
173
  opts.on('--fail-fast', 'Fail fast') do
199
- @fail_fast = true
174
+ update(fail_fast: true)
200
175
  end.on('--version', 'Print mutants version') do
201
176
  puts("mutant-#{Mutant::VERSION}")
202
- Kernel.exit(0)
177
+ Kernel.exit(EXIT_SUCCESS)
203
178
  end.on('-d', '--debug', 'Enable debugging output') do
204
- @debug = true
179
+ update(debug: true)
205
180
  end.on_tail('-h', '--help', 'Show this message') do
206
- puts(opts)
207
- exit
181
+ puts(opts.to_s)
182
+ Kernel.exit(EXIT_SUCCESS)
208
183
  end
209
184
  end
185
+
186
+ # Update configuration
187
+ #
188
+ # @param [Hash<Symbol, Object>] attributes
189
+ #
190
+ # @return [undefined]
191
+ #
192
+ # @api private
193
+ #
194
+ def update(attributes)
195
+ @config = @config.update(attributes)
196
+ end
197
+
198
+ # Add configuration
199
+ #
200
+ # @param [Symbol] attribute
201
+ # the attribute to add to
202
+ #
203
+ # @param [Object] value
204
+ # the value to add
205
+ #
206
+ # @return [undefined]
207
+ #
208
+ # @api private
209
+ #
210
+ def add(attribute, value)
211
+ update(attribute => config.public_send(attribute).dup << value)
212
+ end
213
+
214
+ # Add matcher configuration
215
+ #
216
+ # @param [Symbol] attribute
217
+ # the attribute to add to
218
+ #
219
+ # @param [Object] value
220
+ # the value to add
221
+ #
222
+ # @return [undefined]
223
+ #
224
+ # @api private
225
+ #
226
+ def add_matcher(attribute, value)
227
+ update(matcher_config: config.matcher_config.add(attribute, value))
228
+ end
229
+
210
230
  end # CLI
211
231
  end # Mutant