mutant 0.11.20 → 0.11.22

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28479ac15f5cf3d79de8ffd27e87601db35a642c09a9d717df6d34bfb41bc0c0
4
- data.tar.gz: 1aa5fc440f828ab7a3b21fbb65534899be91281bfd238e86cf3e7e7098f3c4ba
3
+ metadata.gz: bf5fb7800ce81d8fa90585c0dbd00ef9e2f2d21fa1ffbb788cbb59bb9323f677
4
+ data.tar.gz: 206c2db89f0cfca28b088059a68b0715974dffee6062a8825dd27c703ecbb245
5
5
  SHA512:
6
- metadata.gz: 9a7bb108c85e012d4ba53444e612ff955f6ceafbac159f1d4a1561c62f8f693279d1673e2cde0899ef2356ac42bad99143405d2ab482c35215553548c734e662
7
- data.tar.gz: 143cc0c327d18f4203a6769606ceb976aaf0fb748168680d80bc0d4d2099d203a4271cf2a3644307050421c841a9019441947250c21fdefaf7883c198f0887b8
6
+ metadata.gz: 3923e0d8c6927da2c7f6ca9915fd84c98e032708bb41b9c10c91cca92503226a1d04d09b20970ffad44b06e0ca7ff20215609d385f927ea0880a8b60bafcad93
7
+ data.tar.gz: 43834f9ec8af1dd4a65b307cf43af4acaffcb839c3c76fe52069dedb2201d80c7a81e313c6e4742fd9d28f81229f36f72bbfb5f4a7c119d13a001705648993b8
@@ -33,8 +33,7 @@ module Mutant
33
33
  #
34
34
  # @return [Boolean]
35
35
  def attribute_assignment?
36
- !Types::METHOD_OPERATORS.include?(selector) &&
37
- selector.to_s.end_with?(ATTRIBUTE_ASSIGNMENT_SELECTOR_SUFFIX)
36
+ !Types::METHOD_OPERATORS.include?(selector) && selector.end_with?(ATTRIBUTE_ASSIGNMENT_SELECTOR_SUFFIX)
38
37
  end
39
38
 
40
39
  # Test for binary operator implemented as method
@@ -28,18 +28,8 @@ module Mutant
28
28
  env = Env.empty(world, @config)
29
29
 
30
30
  env
31
- .record(:config) { Config.load_config_file(env).fmap(&method(:expand)) }
32
- .bind { Bootstrap.call(env.with(config: @config)) }
33
- end
34
-
35
- def expand(file_config)
36
- if @config.matcher.subjects.any?
37
- file_config = file_config.with(
38
- matcher: file_config.matcher.with(subjects: [])
39
- )
40
- end
41
-
42
- @config = Config.env.merge(file_config).merge(@config)
31
+ .record(:config) { Config.load(cli_config: @config, world: world) }
32
+ .bind { |config| Bootstrap.call(env.with(config: config)) }
43
33
  end
44
34
 
45
35
  def parse_remaining_arguments(arguments)
@@ -87,9 +77,22 @@ module Mutant
87
77
  def add_integration_options(parser)
88
78
  parser.separator('Integration:')
89
79
 
90
- parser.on('--use INTEGRATION', 'Use INTEGRATION to kill mutations') do |name|
91
- set(integration: name)
92
- end
80
+ parser.on('--use INTEGRATION', 'deprecated alias for --integration', &method(:assign_integration_name))
81
+ parser.on('--integration NAME', 'Use test integration with NAME', &method(:assign_integration_name))
82
+
83
+ parser.on(
84
+ '--integration-argument ARGUMENT', 'Pass ARGUMENT to integration',
85
+ &method(:add_integration_argument)
86
+ )
87
+ end
88
+
89
+ def add_integration_argument(value)
90
+ config = @config.integration
91
+ set(integration: config.with(arguments: config.arguments + [value]))
92
+ end
93
+
94
+ def assign_integration_name(name)
95
+ set(integration: @config.integration.with(name: name))
93
96
  end
94
97
 
95
98
  def add_matcher_options(parser)
data/lib/mutant/config.rb CHANGED
@@ -52,6 +52,20 @@ module Mutant
52
52
  ```
53
53
  MESSAGE
54
54
 
55
+ INTEGRATION_DEPRECATION = <<~'MESSAGE'
56
+ Deprecated configuration toplevel string key `integration` found.
57
+
58
+ This key will be removed in the next major version.
59
+ Instead place your integration configuration under the `integration.name` key
60
+ like this:
61
+
62
+ ```
63
+ # mutant.yml
64
+ integration:
65
+ name: your_integration # typically rspec or minitest
66
+ ```
67
+ MESSAGE
68
+
55
69
  private_constant(*constants(false))
56
70
 
57
71
  # Merge with other config
@@ -69,7 +83,7 @@ module Mutant
69
83
  fail_fast: fail_fast || other.fail_fast,
70
84
  hooks: hooks + other.hooks,
71
85
  includes: includes + other.includes,
72
- integration: other.integration || integration,
86
+ integration: integration.merge(other.integration),
73
87
  jobs: other.jobs || jobs,
74
88
  matcher: matcher.merge(other.matcher),
75
89
  mutation: mutation.merge(other.mutation),
@@ -79,30 +93,41 @@ module Mutant
79
93
  # rubocop:enable Metrics/AbcSize
80
94
  # rubocop:enable Metrics/MethodLength
81
95
 
96
+ # Load the configuration
97
+ def self.load(cli_config:, world:)
98
+ load_config_file(reporter: cli_config.reporter, world: world).fmap do |file_config|
99
+ DEFAULT.with(
100
+ jobs: Etc.nprocessors,
101
+ mutation: Mutation::Config::DEFAULT
102
+ ).merge(file_config.merge(cli_config))
103
+ end
104
+ end
105
+
82
106
  # Load config file
83
107
  #
84
108
  # @param [Env] env
85
109
  #
86
110
  # @return [Either<String,Config>]
87
- def self.load_config_file(env)
111
+ def self.load_config_file(reporter:, world:)
88
112
  files = CANDIDATES
89
- .map(&env.world.pathname.public_method(:new))
113
+ .map(&world.pathname.public_method(:new))
90
114
  .select(&:readable?)
91
115
 
92
116
  if files.one?
93
- load_contents(env, files.first).fmap(&DEFAULT.public_method(:with))
117
+ load_contents(reporter: reporter, path: files.first).fmap(&DEFAULT.public_method(:with))
94
118
  elsif files.empty?
95
119
  Either::Right.new(DEFAULT)
96
120
  else
97
121
  Either::Left.new(MORE_THAN_ONE_CONFIG_FILE % files.join(', '))
98
122
  end
99
123
  end
124
+ private_class_method :load_config_file
100
125
 
101
- def self.load_contents(env, path)
126
+ def self.load_contents(reporter:, path:)
102
127
  Transform::Named
103
128
  .new(
104
129
  name: path.to_s,
105
- transform: sequence(env.config.reporter)
130
+ transform: sequence(reporter)
106
131
  )
107
132
  .call(path)
108
133
  .lmap(&:compact_message)
@@ -122,13 +147,6 @@ module Mutant
122
147
  end
123
148
  private_class_method :sequence
124
149
 
125
- # The configuration from the environment
126
- #
127
- # @return [Config]
128
- def self.env
129
- DEFAULT.with(jobs: Etc.nprocessors)
130
- end
131
-
132
150
  PATHNAME_ARRAY = Transform::Array.new(
133
151
  transform: Transform::Sequence.new(
134
152
  steps: [
@@ -158,14 +176,29 @@ module Mutant
158
176
  end
159
177
 
160
178
  def self.deprecations(reporter, hash)
161
- if hash.key?('mutation_timeout')
162
- reporter.warn(MUTATION_TIMEOUT_DEPRECATION)
163
-
164
- (hash['mutation'] ||= {})['timeout'] ||= hash.delete('mutation_timeout')
165
- end
179
+ mutation_timeout_deprecation(reporter, hash)
180
+ integration_deprecation(reporter, hash)
166
181
 
167
182
  hash
168
183
  end
184
+ private_class_method :deprecations
185
+
186
+ def self.mutation_timeout_deprecation(reporter, hash)
187
+ return unless hash.key?('mutation_timeout')
188
+ reporter.warn(MUTATION_TIMEOUT_DEPRECATION)
189
+
190
+ (hash['mutation'] ||= {})['timeout'] ||= hash.delete('mutation_timeout')
191
+ end
192
+ private_class_method :mutation_timeout_deprecation
193
+
194
+ def self.integration_deprecation(reporter, hash)
195
+ value = hash['integration']
196
+ return unless value.instance_of?(String)
197
+ reporter.warn(INTEGRATION_DEPRECATION)
198
+
199
+ hash['integration'] = { 'name' => value }
200
+ end
201
+ private_class_method :integration_deprecation
169
202
 
170
203
  TRANSFORMS = [
171
204
  Transform::Hash.new(
@@ -196,7 +229,7 @@ module Mutant
196
229
  value: 'includes'
197
230
  ),
198
231
  Transform::Hash::Key.new(
199
- transform: Transform::STRING,
232
+ transform: ->(value) { Integration::Config::TRANSFORM.call(value) },
200
233
  value: 'integration'
201
234
  ),
202
235
  Transform::Hash::Key.new(
data/lib/mutant/env.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Mutant
4
4
  # Mutation testing execution environment
5
+ # rubocop:disable Metrics/ClassLength
5
6
  class Env
6
7
  include Adamantium, Anima.new(
7
8
  :config,
@@ -32,6 +33,7 @@ module Mutant
32
33
  config: config,
33
34
  hooks: Hooks.empty,
34
35
  integration: Integration::Null.new(
36
+ arguments: EMPTY_ARRAY,
35
37
  expression_parser: config.expression_parser,
36
38
  world: world
37
39
  ),
@@ -175,4 +177,5 @@ module Mutant
175
177
  end
176
178
 
177
179
  end # Env
180
+ # rubocop:enable Metrics/ClassLength
178
181
  end # Mutant
@@ -4,7 +4,7 @@ module Mutant
4
4
 
5
5
  # Abstract base class mutant test framework integrations
6
6
  class Integration
7
- include AbstractType, Adamantium, Anima.new(:expression_parser, :world)
7
+ include AbstractType, Adamantium, Anima.new(:arguments, :expression_parser, :world)
8
8
 
9
9
  LOAD_MESSAGE = <<~'MESSAGE'
10
10
  Unable to load integration mutant-%<integration_name>s:
@@ -26,18 +26,47 @@ module Mutant
26
26
 
27
27
  private_constant(*constants(false))
28
28
 
29
+ class Config
30
+ include Adamantium, Anima.new(:name, :arguments)
31
+
32
+ DEFAULT = new(arguments: EMPTY_ARRAY, name: nil)
33
+
34
+ TRANSFORM = Transform::Sequence.new(
35
+ steps: [
36
+ Transform::Primitive.new(primitive: Hash),
37
+ Transform::Hash.new(
38
+ optional: [
39
+ Transform::Hash::Key.new(transform: Transform::STRING, value: 'name'),
40
+ Transform::Hash::Key.new(transform: Transform::STRING_ARRAY, value: 'arguments')
41
+ ],
42
+ required: []
43
+ ),
44
+ Transform::Hash::Symbolize.new,
45
+ Transform::Success.new(block: DEFAULT.method(:with))
46
+ ]
47
+ )
48
+
49
+ def merge(other)
50
+ self.class.new(
51
+ name: other.name || name,
52
+ arguments: arguments + other.arguments
53
+ )
54
+ end
55
+ end # Config
56
+
29
57
  # Setup integration
30
58
  #
31
59
  # @param env [Bootstrap]
32
60
  #
33
61
  # @return [Either<String, Integration>]
34
62
  def self.setup(env)
35
- unless env.config.integration
36
- return Either::Left.new(INTEGRATION_MISSING)
37
- end
63
+ integration_config = env.config.integration
64
+
65
+ return Either::Left.new(INTEGRATION_MISSING) unless integration_config.name
38
66
 
39
67
  attempt_require(env).bind { attempt_const_get(env) }.fmap do |klass|
40
68
  klass.new(
69
+ arguments: integration_config.arguments,
41
70
  expression_parser: env.config.expression_parser,
42
71
  world: env.world
43
72
  ).setup
@@ -46,7 +75,7 @@ module Mutant
46
75
 
47
76
  # rubocop:disable Style/MultilineBlockChain
48
77
  def self.attempt_require(env)
49
- integration_name = env.config.integration
78
+ integration_name = env.config.integration.name
50
79
 
51
80
  Either.wrap_error(LoadError) do
52
81
  env.world.kernel.require("mutant/integration/#{integration_name}")
@@ -61,7 +90,7 @@ module Mutant
61
90
  # rubocop:enable Style/MultilineBlockChain
62
91
 
63
92
  def self.attempt_const_get(env)
64
- integration_name = env.config.integration
93
+ integration_name = env.config.integration.name
65
94
  constant_name = integration_name.capitalize
66
95
 
67
96
  Either.wrap_error(NameError) { const_get(constant_name) }.lmap do |exception|
@@ -205,10 +205,6 @@ module Mutant
205
205
  _pid, status = world.process.wait2(@pid, Process::WNOHANG)
206
206
  status
207
207
  end
208
-
209
- def add_result(result)
210
- @result = defined?(@result) ? @result.add_error(result) : result
211
- end
212
208
  end # Parent
213
209
  # rubocop:enable Metrics/ClassLength
214
210
 
@@ -78,9 +78,11 @@ module Mutant
78
78
  #
79
79
  # @return [Config]
80
80
  def merge(other)
81
- self.class.new(
82
- to_h
83
- .to_h { |name, value| [name, value + other.public_send(name)] }
81
+ with(
82
+ ignore: ignore + other.ignore,
83
+ start_expressions: start_expressions + other.start_expressions,
84
+ subjects: other.subjects.any? ? other.subjects : subjects,
85
+ diffs: diffs + other.diffs
84
86
  )
85
87
  end
86
88
 
@@ -12,9 +12,7 @@ module Mutant
12
12
  #
13
13
  # @return [Enumerable<Subject>]
14
14
  def call(env)
15
- matcher
16
- .call(env)
17
- .select(&predicate.method(:call))
15
+ matcher.call(env).select(&predicate)
18
16
  end
19
17
 
20
18
  end # Filter
@@ -11,25 +11,26 @@ module Mutant
11
11
  #
12
12
  # @param [Thread::Backtrace::Location] location
13
13
  # @param [Set<Symbol>] types
14
+ # @param [Mutation::Operators] operators
14
15
  #
15
16
  # @return [Example]
16
- def self.call(location, types, block)
17
- instance = new(location, types)
17
+ #
18
+ def self.call(location:, types:, operators:, block:) # rubocop:disable Metrics/ParameterLists
19
+ instance = new(location, types, operators)
18
20
  instance.instance_eval(&block)
19
21
  instance.example
20
22
  end
21
-
22
23
  private_class_method :new
23
24
 
24
25
  # Initialize object
25
26
  #
26
27
  # @return [undefined]
27
- def initialize(location, types)
28
- @expected = []
29
- @location = location
30
- @lvars = []
31
- @source = nil
32
- @types = types
28
+ def initialize(location, types, operators)
29
+ @expected = []
30
+ @location = location
31
+ @lvars = []
32
+ @operators = operators
33
+ @types = types
33
34
  end
34
35
 
35
36
  # Example captured by DSL
@@ -46,6 +47,7 @@ module Mutant
46
47
  location: @location,
47
48
  lvars: @lvars,
48
49
  node: @node,
50
+ operators: @operators,
49
51
  original_source: @source,
50
52
  types: @types
51
53
  )
@@ -54,7 +54,7 @@ module Mutant
54
54
 
55
55
  def original
56
56
  [
57
- 'Original:',
57
+ "Original: (operators: #{example.operators.class.operators_name})",
58
58
  example.node,
59
59
  example.original_source
60
60
  ]
@@ -10,6 +10,7 @@ module Mutant
10
10
  :location,
11
11
  :lvars,
12
12
  :node,
13
+ :operators,
13
14
  :original_source,
14
15
  :types
15
16
  )
@@ -56,7 +57,7 @@ module Mutant
56
57
  # @return [Enumerable<Mutant::Mutation>]
57
58
  def generated
58
59
  Mutator::Node.mutate(
59
- config: Mutation::Config::DEFAULT,
60
+ config: Mutation::Config::DEFAULT.with(operators: operators),
60
61
  node: node
61
62
  ).map do |node|
62
63
  Mutation::Evil.new(subject: self, node: node)
data/lib/mutant/meta.rb CHANGED
@@ -16,8 +16,13 @@ module Mutant
16
16
  # Add example
17
17
  #
18
18
  # @return [undefined]
19
- def self.add(*types, &block)
20
- ALL << DSL.call(caller_locations(1).first, Set.new(types), block)
19
+ def self.add(*types, operators: :full, &block)
20
+ ALL << DSL.call(
21
+ block: block,
22
+ location: caller_locations(1).first,
23
+ operators: Mutation::Operators.parse(operators.to_s).from_right,
24
+ types: Set.new(types)
25
+ )
21
26
  end
22
27
 
23
28
  Pathname.glob(Pathname.new(__dir__).parent.parent.join('meta', '*.rb'))
@@ -3,11 +3,22 @@
3
3
  module Mutant
4
4
  class Mutation
5
5
  class Config
6
- include Anima.new(:ignore_patterns, :timeout)
6
+ include Anima.new(
7
+ :ignore_patterns,
8
+ :operators,
9
+ :timeout
10
+ )
11
+
12
+ EMPTY = new(
13
+ ignore_patterns: [],
14
+ operators: nil,
15
+ timeout: nil
16
+ )
7
17
 
8
18
  DEFAULT = new(
9
- timeout: nil,
10
- ignore_patterns: []
19
+ ignore_patterns: [],
20
+ operators: Mutation::Operators::Light.new,
21
+ timeout: nil
11
22
  )
12
23
 
13
24
  ignore_pattern = Transform::Block.capture('ignore pattern', &AST::Pattern.method(:parse))
@@ -20,6 +31,10 @@ module Mutant
20
31
  transform: Transform::Array.new(transform: ignore_pattern),
21
32
  value: 'ignore_patterns'
22
33
  ),
34
+ Transform::Hash::Key.new(
35
+ transform: Operators::TRANSFORM,
36
+ value: 'operators'
37
+ ),
23
38
  Transform::Hash::Key.new(
24
39
  transform: Transform::FLOAT,
25
40
  value: 'timeout'
@@ -28,13 +43,14 @@ module Mutant
28
43
  required: []
29
44
  ),
30
45
  Transform::Hash::Symbolize.new,
31
- Transform::Success.new(block: DEFAULT.method(:with))
46
+ Transform::Success.new(block: EMPTY.method(:with))
32
47
  ]
33
48
  )
34
49
 
35
50
  def merge(other)
36
51
  with(
37
52
  ignore_patterns: other.ignore_patterns,
53
+ operators: other.operators || operators,
38
54
  timeout: other.timeout || timeout
39
55
  )
40
56
  end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mutant
4
+ # Represent a mutated node with its subject
5
+ class Mutation
6
+ class Operators
7
+ include Equalizer.new
8
+
9
+ class Full < self
10
+ NAME = :full
11
+
12
+ SELECTOR_REPLACEMENTS = {
13
+ :< => %i[== eql? equal?],
14
+ :<= => %i[< == eql? equal?],
15
+ :== => %i[eql? equal?],
16
+ :=== => %i[is_a?],
17
+ :=~ => %i[match?],
18
+ :> => %i[== eql? equal?],
19
+ :>= => %i[> == eql? equal?],
20
+ __send__: %i[public_send],
21
+ all?: %i[any?],
22
+ any?: %i[all?],
23
+ at: %i[fetch key?],
24
+ fetch: %i[key?],
25
+ flat_map: %i[map],
26
+ gsub: %i[sub],
27
+ is_a?: %i[instance_of?],
28
+ kind_of?: %i[instance_of?],
29
+ map: %i[each],
30
+ match: %i[match?],
31
+ method: %i[public_method],
32
+ reverse_each: %i[each],
33
+ reverse_map: %i[map each],
34
+ reverse_merge: %i[merge],
35
+ send: %i[public_send __send__],
36
+ to_a: %i[to_ary],
37
+ to_h: %i[to_hash],
38
+ to_i: %i[to_int],
39
+ to_s: %i[to_str],
40
+ values_at: %i[fetch_values]
41
+ }.freeze.tap { |hash| hash.values(&:freeze) }
42
+ end
43
+
44
+ class Light < self
45
+ NAME = :light
46
+
47
+ SELECTOR_REPLACEMENTS = Full::SELECTOR_REPLACEMENTS
48
+ .dup
49
+ .tap do |replacements|
50
+ replacements.delete(:==)
51
+ replacements.delete(:eql?)
52
+ end
53
+ .freeze
54
+ end
55
+
56
+ def self.operators_name
57
+ self::NAME
58
+ end
59
+
60
+ def selector_replacements
61
+ self.class::SELECTOR_REPLACEMENTS
62
+ end
63
+
64
+ def self.parse(value)
65
+ klass = [Light, Full].detect { |candidate| candidate.operators_name.to_s.eql?(value) }
66
+
67
+ if klass
68
+ Either::Right.new(klass.new)
69
+ else
70
+ Either::Left.new("Unknown operators: #{value}")
71
+ end
72
+ end
73
+
74
+ TRANSFORM =
75
+ Transform::Sequence.new(
76
+ steps: [
77
+ Transform::STRING,
78
+ Transform::Block.capture('parse operator', &method(:parse))
79
+ ]
80
+ )
81
+ end # Operators
82
+ end # Mutation
83
+ end # Mutant
@@ -20,9 +20,12 @@ module Mutant
20
20
  def emit_symbol_to_proc_mutations
21
21
  return unless n_sym?(argument)
22
22
 
23
- Send::SELECTOR_REPLACEMENTS.fetch(*argument, EMPTY_ARRAY).each do |method|
24
- emit_argument(s(:sym, method))
25
- end
23
+ config
24
+ .operators
25
+ .selector_replacements
26
+ .fetch(*argument, EMPTY_ARRAY).each do |method|
27
+ emit_argument(s(:sym, method))
28
+ end
26
29
  end
27
30
  end # Block
28
31
  end # Node
@@ -13,37 +13,6 @@ module Mutant
13
13
 
14
14
  children :receiver, :selector
15
15
 
16
- SELECTOR_REPLACEMENTS = {
17
- :< => %i[== eql? equal?],
18
- :<= => %i[< == eql? equal?],
19
- :== => %i[eql? equal?],
20
- :=== => %i[is_a?],
21
- :=~ => %i[match?],
22
- :> => %i[== eql? equal?],
23
- :>= => %i[> == eql? equal?],
24
- __send__: %i[public_send],
25
- all?: %i[any?],
26
- any?: %i[all?],
27
- at: %i[fetch key?],
28
- fetch: %i[key?],
29
- flat_map: %i[map],
30
- gsub: %i[sub],
31
- is_a?: %i[instance_of?],
32
- kind_of?: %i[instance_of?],
33
- map: %i[each],
34
- match: %i[match?],
35
- method: %i[public_method],
36
- reverse_each: %i[each],
37
- reverse_map: %i[map each],
38
- reverse_merge: %i[merge],
39
- send: %i[public_send __send__],
40
- to_a: %i[to_ary],
41
- to_h: %i[to_hash],
42
- to_i: %i[to_int],
43
- to_s: %i[to_str],
44
- values_at: %i[fetch_values]
45
- }.freeze.tap { |hash| hash.values(&:freeze) }
46
-
47
16
  RECEIVER_SELECTOR_REPLACEMENTS = {
48
17
  Date: {
49
18
  parse: %i[jd civil strptime iso8601 rfc3339 xmlschema rfc2822 rfc822 httpdate jisx0301]
@@ -227,7 +196,10 @@ module Mutant
227
196
  end
228
197
 
229
198
  def emit_selector_replacement
230
- SELECTOR_REPLACEMENTS.fetch(selector, EMPTY_ARRAY).each(&method(:emit_selector))
199
+ config
200
+ .operators
201
+ .selector_replacements
202
+ .fetch(selector, EMPTY_ARRAY).each(&public_method(:emit_selector))
231
203
  end
232
204
 
233
205
  def emit_naked_receiver
@@ -16,10 +16,11 @@ module Mutant
16
16
  # rubocop:disable Metrics/AbcSize
17
17
  def run
18
18
  info 'Matcher: %s', object.matcher.inspect
19
- info 'Integration: %s', object.integration || 'null'
19
+ info 'Integration: %s', object.integration.name || 'null'
20
20
  info 'Jobs: %s', object.jobs || 'auto'
21
21
  info 'Includes: %s', object.includes
22
22
  info 'Requires: %s', object.requires
23
+ info 'Operators: %s', object.mutation.operators.class.operators_name
23
24
  info 'MutationTimeout: %0.9g', object.mutation.timeout if object.mutation.timeout
24
25
  end
25
26
  # rubocop:enable Metrics/AbcSize
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Mutant
4
4
  # Current mutant version
5
- VERSION = '0.11.20'
5
+ VERSION = '0.11.22'
6
6
  end # Mutant
data/lib/mutant.rb CHANGED
@@ -107,6 +107,7 @@ module Mutant
107
107
  require 'mutant/parallel/worker'
108
108
  require 'mutant/require_highjack'
109
109
  require 'mutant/mutation'
110
+ require 'mutant/mutation/operators'
110
111
  require 'mutant/mutation/config'
111
112
  require 'mutant/mutator'
112
113
  require 'mutant/mutator/util'
@@ -346,11 +347,11 @@ module Mutant
346
347
  fail_fast: false,
347
348
  hooks: EMPTY_ARRAY,
348
349
  includes: EMPTY_ARRAY,
349
- integration: nil,
350
+ integration: Integration::Config::DEFAULT,
350
351
  isolation: Mutant::Isolation::Fork.new(world: WORLD),
351
352
  jobs: nil,
352
353
  matcher: Matcher::Config::DEFAULT,
353
- mutation: Mutation::Config::DEFAULT,
354
+ mutation: Mutation::Config::EMPTY,
354
355
  reporter: Reporter::CLI.build(WORLD.stdout),
355
356
  requires: EMPTY_ARRAY
356
357
  )
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mutant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.20
4
+ version: 0.11.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-22 00:00:00.000000000 Z
11
+ date: 2023-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diff-lcs
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.6.7
75
+ version: 0.6.8
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.6.7
82
+ version: 0.6.8
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: parallel
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -235,6 +235,7 @@ files:
235
235
  - lib/mutant/meta/example/verification.rb
236
236
  - lib/mutant/mutation.rb
237
237
  - lib/mutant/mutation/config.rb
238
+ - lib/mutant/mutation/operators.rb
238
239
  - lib/mutant/mutation/runner.rb
239
240
  - lib/mutant/mutation/runner/sink.rb
240
241
  - lib/mutant/mutator.rb