mutant 0.10.4 → 0.10.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/mutant +0 -2
- data/lib/mutant.rb +3 -2
- data/lib/mutant/cli/command.rb +1 -1
- data/lib/mutant/cli/command/run.rb +20 -10
- data/lib/mutant/config.rb +28 -52
- data/lib/mutant/matcher/config.rb +13 -0
- data/lib/mutant/reporter/cli/printer/config.rb +2 -2
- data/lib/mutant/version.rb +1 -1
- data/lib/mutant/world.rb +52 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2e6667e21b413029cf11b268c6d36986a5960921945aad01199aaff5881a3c2
|
4
|
+
data.tar.gz: 3434159c18f80d786ecc728b3fde7eaa5e2c3939ec70c5d931e717288ba6d48f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a036402f0e95f0a41b16dbbede078a56f5ccee4d241052b034022fd6a7db505037cefb5b093061d2d12326f6a4e2ae7bd250ad7bb160586aa14dc831d019a398
|
7
|
+
data.tar.gz: 188b1bb29e0639c6a7f3c72b5ee4ca24ac25bc799181b1f7d2e6f0b056fb92aabe6b7c657345ac080e4002625dad227752c1e7c4a57d5e0f506d608f3c4be28d
|
data/bin/mutant
CHANGED
@@ -10,7 +10,6 @@ require 'mutant'
|
|
10
10
|
|
11
11
|
command = Mutant::CLI.parse(
|
12
12
|
arguments: ARGV,
|
13
|
-
config: Mutant::Config::DEFAULT,
|
14
13
|
world: Mutant::WORLD
|
15
14
|
)
|
16
15
|
|
@@ -40,7 +39,6 @@ status =
|
|
40
39
|
|
41
40
|
Zombie::Mutant::CLI.parse(
|
42
41
|
arguments: ARGV,
|
43
|
-
config: Zombie::Mutant::Config::DEFAULT,
|
44
42
|
world: Zombie::Mutant::WORLD
|
45
43
|
).call
|
46
44
|
else
|
data/lib/mutant.rb
CHANGED
@@ -163,6 +163,7 @@ require 'mutant/integration/null'
|
|
163
163
|
require 'mutant/selector'
|
164
164
|
require 'mutant/selector/expression'
|
165
165
|
require 'mutant/selector/null'
|
166
|
+
require 'mutant/world'
|
166
167
|
require 'mutant/config'
|
167
168
|
require 'mutant/cli'
|
168
169
|
require 'mutant/cli/command'
|
@@ -232,9 +233,9 @@ module Mutant
|
|
232
233
|
]),
|
233
234
|
fail_fast: false,
|
234
235
|
includes: EMPTY_ARRAY,
|
235
|
-
integration:
|
236
|
+
integration: nil,
|
236
237
|
isolation: Mutant::Isolation::Fork.new(WORLD),
|
237
|
-
jobs:
|
238
|
+
jobs: nil,
|
238
239
|
matcher: Matcher::Config::DEFAULT,
|
239
240
|
reporter: Reporter::CLI.build(WORLD.stdout),
|
240
241
|
requires: EMPTY_ARRAY,
|
data/lib/mutant/cli/command.rb
CHANGED
@@ -4,7 +4,7 @@ module Mutant
|
|
4
4
|
module CLI
|
5
5
|
# rubocop:disable Metrics/ClassLength
|
6
6
|
class Command
|
7
|
-
include AbstractType, Anima.new(:world, :
|
7
|
+
include AbstractType, Anima.new(:world, :main, :parent, :arguments)
|
8
8
|
|
9
9
|
include Equalizer.new(:parent, :arguments)
|
10
10
|
|
@@ -28,20 +28,30 @@ module Mutant
|
|
28
28
|
#
|
29
29
|
# @return [Bool]
|
30
30
|
def zombie?
|
31
|
-
config.zombie
|
31
|
+
@config.zombie
|
32
32
|
end
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
+
def initialize(attributes)
|
37
|
+
super(attributes)
|
38
|
+
@config = Config::DEFAULT
|
39
|
+
end
|
40
|
+
|
36
41
|
def execute
|
37
42
|
soft_fail(License.apply(world))
|
38
|
-
.bind { Config.load_config_file(world
|
39
|
-
.
|
43
|
+
.bind { Config.load_config_file(world) }
|
44
|
+
.fmap(&method(:expand))
|
45
|
+
.bind { Bootstrap.apply(world, @config) }
|
40
46
|
.bind(&Runner.public_method(:apply))
|
41
47
|
.from_right { |error| world.stderr.puts(error); return false }
|
42
48
|
.success?
|
43
49
|
end
|
44
50
|
|
51
|
+
def expand(file_config)
|
52
|
+
@config = Config.env.merge(file_config).merge(@config)
|
53
|
+
end
|
54
|
+
|
45
55
|
def soft_fail(result)
|
46
56
|
result.either(
|
47
57
|
lambda do |message|
|
@@ -60,7 +70,7 @@ module Mutant
|
|
60
70
|
end
|
61
71
|
|
62
72
|
def parse_remaining_arguments(arguments)
|
63
|
-
traverse(config.expression_parser.public_method(:apply), arguments)
|
73
|
+
traverse(@config.expression_parser.public_method(:apply), arguments)
|
64
74
|
.fmap do |match_expressions|
|
65
75
|
matcher(match_expressions: match_expressions)
|
66
76
|
self
|
@@ -78,19 +88,19 @@ module Mutant
|
|
78
88
|
end
|
79
89
|
|
80
90
|
def set(**attributes)
|
81
|
-
@config = config.with(attributes)
|
91
|
+
@config = @config.with(attributes)
|
82
92
|
end
|
83
93
|
|
84
94
|
def matcher(**attributes)
|
85
|
-
set(matcher: config.matcher.with(attributes))
|
95
|
+
set(matcher: @config.matcher.with(attributes))
|
86
96
|
end
|
87
97
|
|
88
98
|
def add(attribute, value)
|
89
|
-
set(attribute => config.public_send(attribute) + [value])
|
99
|
+
set(attribute => @config.public_send(attribute) + [value])
|
90
100
|
end
|
91
101
|
|
92
102
|
def add_matcher(attribute, value)
|
93
|
-
set(matcher: config.matcher.add(attribute, value))
|
103
|
+
set(matcher: @config.matcher.add(attribute, value))
|
94
104
|
end
|
95
105
|
|
96
106
|
def add_environment_options(parser)
|
@@ -119,10 +129,10 @@ module Mutant
|
|
119
129
|
parser.separator('Matcher:')
|
120
130
|
|
121
131
|
parser.on('--ignore-subject EXPRESSION', 'Ignore subjects that match EXPRESSION as prefix') do |pattern|
|
122
|
-
add_matcher(:ignore_expressions, config.expression_parser.apply(pattern).from_right)
|
132
|
+
add_matcher(:ignore_expressions, @config.expression_parser.apply(pattern).from_right)
|
123
133
|
end
|
124
134
|
parser.on('--start-subject EXPRESSION', 'Start mutation testing at a specific subject') do |pattern|
|
125
|
-
add_matcher(:start_expressions, config.expression_parser.apply(pattern).from_right)
|
135
|
+
add_matcher(:start_expressions, @config.expression_parser.apply(pattern).from_right)
|
126
136
|
end
|
127
137
|
parser.on('--since REVISION', 'Only select subjects touched since REVISION') do |revision|
|
128
138
|
add_matcher(
|
data/lib/mutant/config.rb
CHANGED
@@ -1,55 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Mutant
|
4
|
-
# The outer world IO objects mutant does interact with
|
5
|
-
class World
|
6
|
-
include Adamantium::Flat, Anima.new(
|
7
|
-
:condition_variable,
|
8
|
-
:gem,
|
9
|
-
:gem_method,
|
10
|
-
:io,
|
11
|
-
:json,
|
12
|
-
:kernel,
|
13
|
-
:load_path,
|
14
|
-
:marshal,
|
15
|
-
:mutex,
|
16
|
-
:object_space,
|
17
|
-
:open3,
|
18
|
-
:pathname,
|
19
|
-
:process,
|
20
|
-
:stderr,
|
21
|
-
:stdout,
|
22
|
-
:thread,
|
23
|
-
:warnings
|
24
|
-
)
|
25
|
-
|
26
|
-
INSPECT = '#<Mutant::World>'
|
27
|
-
|
28
|
-
private_constant(*constants(false))
|
29
|
-
|
30
|
-
# Object inspection
|
31
|
-
#
|
32
|
-
# @return [String]
|
33
|
-
def inspect
|
34
|
-
INSPECT
|
35
|
-
end
|
36
|
-
|
37
|
-
# Capture stdout of a command
|
38
|
-
#
|
39
|
-
# @param [Array<String>] command
|
40
|
-
#
|
41
|
-
# @return [Either<String,String>]
|
42
|
-
def capture_stdout(command)
|
43
|
-
stdout, status = open3.capture2(*command, binmode: true)
|
44
|
-
|
45
|
-
if status.success?
|
46
|
-
Either::Right.new(stdout)
|
47
|
-
else
|
48
|
-
Either::Left.new("Command #{command} failed!")
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end # World
|
52
|
-
|
53
4
|
# Standalone configuration of a mutant execution.
|
54
5
|
#
|
55
6
|
# Does not reference any "external" volatile state. The configuration applied
|
@@ -106,6 +57,23 @@ module Mutant
|
|
106
57
|
mutant.yml
|
107
58
|
].freeze
|
108
59
|
|
60
|
+
# Merge with other config
|
61
|
+
#
|
62
|
+
# @param [Config] other
|
63
|
+
#
|
64
|
+
# @return [Config]
|
65
|
+
def merge(other)
|
66
|
+
other.with(
|
67
|
+
fail_fast: fail_fast || other.fail_fast,
|
68
|
+
includes: includes + other.includes,
|
69
|
+
jobs: other.jobs || jobs,
|
70
|
+
integration: other.integration || integration,
|
71
|
+
matcher: matcher.merge(other.matcher),
|
72
|
+
requires: requires + other.requires,
|
73
|
+
zombie: zombie || other.zombie
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
109
77
|
private_constant(*constants(false))
|
110
78
|
|
111
79
|
# Load config file
|
@@ -114,11 +82,12 @@ module Mutant
|
|
114
82
|
# @param [Config] config
|
115
83
|
#
|
116
84
|
# @return [Either<String,Config>]
|
117
|
-
def self.load_config_file(world
|
118
|
-
|
85
|
+
def self.load_config_file(world)
|
86
|
+
config = DEFAULT
|
87
|
+
files = CANDIDATES.map(&world.pathname.public_method(:new)).select(&:readable?)
|
119
88
|
|
120
89
|
if files.one?
|
121
|
-
load_contents(files.first).fmap(&config.
|
90
|
+
load_contents(files.first).fmap(&config.public_method(:with))
|
122
91
|
elsif files.empty?
|
123
92
|
Either::Right.new(config)
|
124
93
|
else
|
@@ -133,5 +102,12 @@ module Mutant
|
|
133
102
|
.lmap(&:compact_message)
|
134
103
|
end
|
135
104
|
private_class_method :load_contents
|
105
|
+
|
106
|
+
# The configuration from the environment
|
107
|
+
#
|
108
|
+
# @return [Config]
|
109
|
+
def self.env
|
110
|
+
DEFAULT.with(jobs: Etc.nprocessors)
|
111
|
+
end
|
136
112
|
end # Config
|
137
113
|
end # Mutant
|
@@ -44,6 +44,19 @@ module Mutant
|
|
44
44
|
with(attribute => public_send(attribute) + [value])
|
45
45
|
end
|
46
46
|
|
47
|
+
# Merge with other config
|
48
|
+
#
|
49
|
+
# @param [Config] other
|
50
|
+
#
|
51
|
+
# @return [Config]
|
52
|
+
def merge(other)
|
53
|
+
self.class.new(
|
54
|
+
to_h
|
55
|
+
.map { |name, value| [name, value + other.public_send(name)] }
|
56
|
+
.to_h
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
47
60
|
private
|
48
61
|
|
49
62
|
def present_attributes
|
@@ -14,8 +14,8 @@ module Mutant
|
|
14
14
|
# @return [undefined]
|
15
15
|
def run
|
16
16
|
info 'Matcher: %s', object.matcher.inspect
|
17
|
-
info 'Integration: %s', object.integration
|
18
|
-
info 'Jobs: %
|
17
|
+
info 'Integration: %s', object.integration || 'null'
|
18
|
+
info 'Jobs: %s', object.jobs || 'auto'
|
19
19
|
info 'Includes: %s', object.includes
|
20
20
|
info 'Requires: %s', object.requires
|
21
21
|
end
|
data/lib/mutant/version.rb
CHANGED
data/lib/mutant/world.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mutant
|
4
|
+
# The outer world IO objects mutant does interact with
|
5
|
+
class World
|
6
|
+
include Adamantium::Flat, Anima.new(
|
7
|
+
:condition_variable,
|
8
|
+
:gem,
|
9
|
+
:gem_method,
|
10
|
+
:io,
|
11
|
+
:json,
|
12
|
+
:kernel,
|
13
|
+
:load_path,
|
14
|
+
:marshal,
|
15
|
+
:mutex,
|
16
|
+
:object_space,
|
17
|
+
:open3,
|
18
|
+
:pathname,
|
19
|
+
:process,
|
20
|
+
:stderr,
|
21
|
+
:stdout,
|
22
|
+
:thread,
|
23
|
+
:warnings
|
24
|
+
)
|
25
|
+
|
26
|
+
INSPECT = '#<Mutant::World>'
|
27
|
+
|
28
|
+
private_constant(*constants(false))
|
29
|
+
|
30
|
+
# Object inspection
|
31
|
+
#
|
32
|
+
# @return [String]
|
33
|
+
def inspect
|
34
|
+
INSPECT
|
35
|
+
end
|
36
|
+
|
37
|
+
# Capture stdout of a command
|
38
|
+
#
|
39
|
+
# @param [Array<String>] command
|
40
|
+
#
|
41
|
+
# @return [Either<String,String>]
|
42
|
+
def capture_stdout(command)
|
43
|
+
stdout, status = open3.capture2(*command, binmode: true)
|
44
|
+
|
45
|
+
if status.success?
|
46
|
+
Either::Right.new(stdout)
|
47
|
+
else
|
48
|
+
Either::Left.new("Command #{command} failed!")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end # World
|
52
|
+
end # Mutant
|
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.10.
|
4
|
+
version: 0.10.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Markus Schirp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-11-
|
11
|
+
date: 2020-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: abstract_type
|
@@ -450,6 +450,7 @@ files:
|
|
450
450
|
- lib/mutant/util.rb
|
451
451
|
- lib/mutant/version.rb
|
452
452
|
- lib/mutant/warnings.rb
|
453
|
+
- lib/mutant/world.rb
|
453
454
|
- lib/mutant/zombifier.rb
|
454
455
|
homepage: https://github.com/mbj/mutant
|
455
456
|
licenses:
|