mutant 0.5.24 → 0.5.25

Sign up to get free protection for your applications and to get access to all the features.
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