mutant 0.17.0 → 0.17.1
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/mutant/ast/structure.rb +71 -0
- data/lib/mutant/cli/command/session.rb +19 -11
- data/lib/mutant/matcher/method/instance.rb +26 -0
- data/lib/mutant/mutation/runner.rb +1 -0
- data/lib/mutant/mutator/node/itblock.rb +36 -0
- data/lib/mutant/result/json_writer.rb +33 -7
- data/lib/mutant/result/session_files.rb +51 -0
- data/lib/mutant/subject/method/instance.rb +22 -0
- data/lib/mutant.rb +3 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fd77b62cd208529f1fd030e87ffbce9c4df69cf18c097f7895ddd76204f8577d
|
|
4
|
+
data.tar.gz: f4ce398e717e5a8d34aa2ed57eafea5358cdb7af02fb8dc1dbcca2b862f754cc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c6dbb4139015cfe33c91b7c802004aca5d9015299d517552c56bcaa4cc81fa40b5a5f8e39bd17319ff0876da90b2cc7164566c0c65221f6dd0de1758fe767829
|
|
7
|
+
data.tar.gz: caa47a0c66816fe06b76bf0da184d9b91404abceb93eec83d374c42f1d2c3c51ae578e57b98f00b9fb431ffcc770cb864aabfe203bdd9400b30a77fdf8acade3
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.17.
|
|
1
|
+
0.17.1
|
data/lib/mutant/ast/structure.rb
CHANGED
|
@@ -177,6 +177,11 @@ module Mutant
|
|
|
177
177
|
fixed: EMPTY_ARRAY,
|
|
178
178
|
variable: Node::Variable::Descendants.new(name: :members, range: 0..)
|
|
179
179
|
),
|
|
180
|
+
Node.new(
|
|
181
|
+
type: :array_pattern_with_tail,
|
|
182
|
+
fixed: EMPTY_ARRAY,
|
|
183
|
+
variable: Node::Variable::Descendants.new(name: :members, range: 0..)
|
|
184
|
+
),
|
|
180
185
|
Node.new(
|
|
181
186
|
type: :back_ref,
|
|
182
187
|
fixed: Node.fixed([[Node::Fixed::Attribute, :name]]),
|
|
@@ -381,6 +386,11 @@ module Mutant
|
|
|
381
386
|
fixed: EMPTY_ARRAY,
|
|
382
387
|
variable: nil
|
|
383
388
|
),
|
|
389
|
+
Node.new(
|
|
390
|
+
type: :find_pattern,
|
|
391
|
+
fixed: EMPTY_ARRAY,
|
|
392
|
+
variable: Node::Variable::Descendants.new(name: :members, range: 0..)
|
|
393
|
+
),
|
|
384
394
|
Node.new(
|
|
385
395
|
type: :float,
|
|
386
396
|
fixed: Node.fixed([[Node::Fixed::Attribute, :value]]),
|
|
@@ -442,6 +452,11 @@ module Mutant
|
|
|
442
452
|
fixed: EMPTY_ARRAY,
|
|
443
453
|
variable: Node::Variable::Descendants.new(name: :members, range: 0..)
|
|
444
454
|
),
|
|
455
|
+
Node.new(
|
|
456
|
+
type: :hash_pattern,
|
|
457
|
+
fixed: EMPTY_ARRAY,
|
|
458
|
+
variable: Node::Variable::Descendants.new(name: :members, range: 0..)
|
|
459
|
+
),
|
|
445
460
|
Node.new(
|
|
446
461
|
type: :index,
|
|
447
462
|
fixed: Node.fixed([[Node::Fixed::Descendant, :receiver]]),
|
|
@@ -505,6 +520,17 @@ module Mutant
|
|
|
505
520
|
),
|
|
506
521
|
variable: nil
|
|
507
522
|
),
|
|
523
|
+
Node.new(
|
|
524
|
+
type: :itblock,
|
|
525
|
+
fixed: Node.fixed(
|
|
526
|
+
[
|
|
527
|
+
[Node::Fixed::Descendant, :receiver],
|
|
528
|
+
[Node::Fixed::Attribute, :parameter],
|
|
529
|
+
[Node::Fixed::Descendant, :body]
|
|
530
|
+
]
|
|
531
|
+
),
|
|
532
|
+
variable: nil
|
|
533
|
+
),
|
|
508
534
|
Node.new(
|
|
509
535
|
type: :ivar,
|
|
510
536
|
fixed: Node.fixed([[Node::Fixed::Attribute, :name]]),
|
|
@@ -535,6 +561,11 @@ module Mutant
|
|
|
535
561
|
fixed: EMPTY_ARRAY,
|
|
536
562
|
variable: Node::Variable::Descendants.new(name: :members, range: 0..)
|
|
537
563
|
),
|
|
564
|
+
Node.new(
|
|
565
|
+
type: :kwnilarg,
|
|
566
|
+
fixed: EMPTY_ARRAY,
|
|
567
|
+
variable: nil
|
|
568
|
+
),
|
|
538
569
|
Node.new(
|
|
539
570
|
type: :kwoptarg,
|
|
540
571
|
fixed: Node.fixed(
|
|
@@ -575,11 +606,36 @@ module Mutant
|
|
|
575
606
|
),
|
|
576
607
|
variable: nil
|
|
577
608
|
),
|
|
609
|
+
Node.new(
|
|
610
|
+
type: :match_alt,
|
|
611
|
+
fixed: Node.fixed(
|
|
612
|
+
[
|
|
613
|
+
[Node::Fixed::Descendant, :left],
|
|
614
|
+
[Node::Fixed::Descendant, :right]
|
|
615
|
+
]
|
|
616
|
+
),
|
|
617
|
+
variable: nil
|
|
618
|
+
),
|
|
619
|
+
Node.new(
|
|
620
|
+
type: :match_as,
|
|
621
|
+
fixed: Node.fixed(
|
|
622
|
+
[
|
|
623
|
+
[Node::Fixed::Descendant, :pattern],
|
|
624
|
+
[Node::Fixed::Descendant, :target]
|
|
625
|
+
]
|
|
626
|
+
),
|
|
627
|
+
variable: nil
|
|
628
|
+
),
|
|
578
629
|
Node.new(
|
|
579
630
|
type: :match_current_line,
|
|
580
631
|
fixed: Node.fixed([[Node::Fixed::Descendant, :pattern]]),
|
|
581
632
|
variable: nil
|
|
582
633
|
),
|
|
634
|
+
Node.new(
|
|
635
|
+
type: :match_nil_pattern,
|
|
636
|
+
fixed: EMPTY_ARRAY,
|
|
637
|
+
variable: nil
|
|
638
|
+
),
|
|
583
639
|
Node.new(
|
|
584
640
|
type: :match_pattern,
|
|
585
641
|
fixed: Node.fixed(
|
|
@@ -590,6 +646,16 @@ module Mutant
|
|
|
590
646
|
),
|
|
591
647
|
variable: nil
|
|
592
648
|
),
|
|
649
|
+
Node.new(
|
|
650
|
+
type: :match_pattern_p,
|
|
651
|
+
fixed: Node.fixed(
|
|
652
|
+
[
|
|
653
|
+
[Node::Fixed::Descendant, :target],
|
|
654
|
+
[Node::Fixed::Descendant, :pattern]
|
|
655
|
+
]
|
|
656
|
+
),
|
|
657
|
+
variable: nil
|
|
658
|
+
),
|
|
593
659
|
Node.new(
|
|
594
660
|
type: :match_rest,
|
|
595
661
|
fixed: Node.fixed([[Node::Fixed::Descendant, :value]]),
|
|
@@ -794,6 +860,11 @@ module Mutant
|
|
|
794
860
|
),
|
|
795
861
|
variable: nil
|
|
796
862
|
),
|
|
863
|
+
Node.new(
|
|
864
|
+
type: :pin,
|
|
865
|
+
fixed: Node.fixed([[Node::Fixed::Descendant, :value]]),
|
|
866
|
+
variable: nil
|
|
867
|
+
),
|
|
797
868
|
Node.new(
|
|
798
869
|
type: :postexe,
|
|
799
870
|
fixed: Node.fixed([[Node::Fixed::Descendant, :body]]),
|
|
@@ -7,23 +7,29 @@ module Mutant
|
|
|
7
7
|
NAME = 'session'
|
|
8
8
|
SHORT_DESCRIPTION = 'Session history subcommands'
|
|
9
9
|
|
|
10
|
-
RESULTS_DIR =
|
|
10
|
+
RESULTS_DIR = Result::SessionFiles::DIRECTORY
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
GZIP_MAGIC = [0x1F, 0x8B].pack('C2')
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
dir = world.pathname.new(RESULTS_DIR)
|
|
14
|
+
private_constant(:GZIP_MAGIC)
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
private
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
def session_files
|
|
19
|
+
Result::SessionFiles.new(world:).paths
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def load_session_file(path)
|
|
23
|
-
world.parse_json(path
|
|
23
|
+
world.parse_json(read_session_file(path))
|
|
24
24
|
.bind(&Result::Session::CODEC.load_transform.public_method(:call))
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
def read_session_file(path)
|
|
28
|
+
content = path.binread
|
|
29
|
+
|
|
30
|
+
content.start_with?(GZIP_MAGIC) ? Zlib.gunzip(content) : content
|
|
31
|
+
end
|
|
32
|
+
|
|
27
33
|
# Shared base for commands that operate on a session
|
|
28
34
|
class SessionCommand < self
|
|
29
35
|
OPTIONS = %i[add_session_id_option].freeze
|
|
@@ -68,7 +74,9 @@ module Mutant
|
|
|
68
74
|
|
|
69
75
|
def resolve_session_path
|
|
70
76
|
if @session_id
|
|
71
|
-
world.pathname.new("#{RESULTS_DIR}/#{@session_id}.json")
|
|
77
|
+
compressed = world.pathname.new("#{RESULTS_DIR}/#{@session_id}.json.gz")
|
|
78
|
+
|
|
79
|
+
compressed.file? ? compressed : world.pathname.new("#{RESULTS_DIR}/#{@session_id}.json")
|
|
72
80
|
else
|
|
73
81
|
session_files.last
|
|
74
82
|
end
|
|
@@ -131,9 +139,9 @@ module Mutant
|
|
|
131
139
|
end
|
|
132
140
|
|
|
133
141
|
def colorize_unsupported(path)
|
|
134
|
-
session_id = path.basename('.json')
|
|
142
|
+
session_id = path.basename.to_s.delete_suffix('.gz').delete_suffix('.json')
|
|
135
143
|
|
|
136
|
-
Unparser::Color::RED.format(INCOMPATIBLE.ljust(54)) + session_id
|
|
144
|
+
Unparser::Color::RED.format(INCOMPATIBLE.ljust(54)) + session_id
|
|
137
145
|
end
|
|
138
146
|
end # List
|
|
139
147
|
|
|
@@ -230,7 +238,7 @@ module Mutant
|
|
|
230
238
|
SUBCOMMANDS = [].freeze
|
|
231
239
|
OPTIONS = %i[add_gc_options].freeze
|
|
232
240
|
|
|
233
|
-
DEFAULT_KEEP =
|
|
241
|
+
DEFAULT_KEEP = Result::SessionFiles::KEEP
|
|
234
242
|
|
|
235
243
|
def initialize(*)
|
|
236
244
|
super
|
|
@@ -18,6 +18,8 @@ module Mutant
|
|
|
18
18
|
evaluator =
|
|
19
19
|
if memoized_method?(scope, target_method.name)
|
|
20
20
|
Evaluator::Memoized
|
|
21
|
+
elsif module_function?(scope, target_method)
|
|
22
|
+
Evaluator::ModuleFunction
|
|
21
23
|
else
|
|
22
24
|
Evaluator
|
|
23
25
|
end
|
|
@@ -39,6 +41,25 @@ module Mutant
|
|
|
39
41
|
end
|
|
40
42
|
private_class_method :memoized_method?
|
|
41
43
|
|
|
44
|
+
# Test if method was exposed via module_function
|
|
45
|
+
#
|
|
46
|
+
# module_function makes the instance method private and copies it
|
|
47
|
+
# onto the singleton class, where it keeps the source location.
|
|
48
|
+
#
|
|
49
|
+
# @param [Scope] scope
|
|
50
|
+
# @param [UnboundMethod] target_method
|
|
51
|
+
#
|
|
52
|
+
# @return [Boolean]
|
|
53
|
+
def self.module_function?(scope, target_method)
|
|
54
|
+
raw = scope.raw
|
|
55
|
+
method_name = target_method.name
|
|
56
|
+
|
|
57
|
+
raw.private_method_defined?(method_name) &&
|
|
58
|
+
raw.singleton_class.public_method_defined?(method_name) &&
|
|
59
|
+
raw.singleton_class.instance_method(method_name).source_location.eql?(target_method.source_location)
|
|
60
|
+
end
|
|
61
|
+
private_class_method :module_function?
|
|
62
|
+
|
|
42
63
|
# Instance method specific evaluator
|
|
43
64
|
class Evaluator < Evaluator
|
|
44
65
|
MATCH_NODE_TYPE = :def
|
|
@@ -75,6 +96,11 @@ module Mutant
|
|
|
75
96
|
end
|
|
76
97
|
|
|
77
98
|
end # Memoized
|
|
99
|
+
|
|
100
|
+
# Evaluator specialized for module_function instance methods
|
|
101
|
+
class ModuleFunction < self
|
|
102
|
+
SUBJECT_CLASS = Subject::Method::Instance::ModuleFunction
|
|
103
|
+
end # ModuleFunction
|
|
78
104
|
end # Evaluator
|
|
79
105
|
|
|
80
106
|
private_constant(*constants(false))
|
|
@@ -19,6 +19,7 @@ module Mutant
|
|
|
19
19
|
.record(:analysis) { run_driver(reporter, async_driver(env)) }
|
|
20
20
|
.tap { |result| env.record(:report) { reporter.report(result) } }
|
|
21
21
|
.tap { |result| Result::JSONWriter.new(env:, result:).call }
|
|
22
|
+
.tap { Result::SessionFiles.new(world: env.world).prune(Result::SessionFiles::KEEP) }
|
|
22
23
|
end
|
|
23
24
|
private_class_method :run_mutation_analysis
|
|
24
25
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mutant
|
|
4
|
+
class Mutator
|
|
5
|
+
class Node
|
|
6
|
+
class Itblock < self
|
|
7
|
+
|
|
8
|
+
handle(:itblock)
|
|
9
|
+
|
|
10
|
+
children :receiver, :parameter, :body
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def dispatch
|
|
15
|
+
emit_nil
|
|
16
|
+
emit_receiver_mutations(&method(:n_send?))
|
|
17
|
+
emit_body_mutations(&method(:references_it?))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def references_it?(node)
|
|
21
|
+
return true if node.eql?(s(:lvar, :it))
|
|
22
|
+
|
|
23
|
+
children = owns_it?(node) ? [node.children.first] : node.children
|
|
24
|
+
|
|
25
|
+
children.any? do |child|
|
|
26
|
+
child.instance_of?(::Parser::AST::Node) && references_it?(child)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def owns_it?(node)
|
|
31
|
+
n_block?(node) || n_itblock?(node) || n_def?(node) || n_defs?(node)
|
|
32
|
+
end
|
|
33
|
+
end # Itblock
|
|
34
|
+
end # Node
|
|
35
|
+
end # Mutator
|
|
36
|
+
end # Mutant
|
|
@@ -2,26 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
module Mutant
|
|
4
4
|
module Result
|
|
5
|
-
# Write result JSON to .mutant/results
|
|
5
|
+
# Write result JSON to .mutant/results/, gzip compressed
|
|
6
6
|
class JSONWriter
|
|
7
7
|
include Anima.new(:env, :result)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
# Log stored in place of the log of a covered mutation
|
|
10
|
+
EMPTY_LOG = LogCapture::String.new(content: '')
|
|
10
11
|
|
|
11
12
|
# Write result JSON file
|
|
12
13
|
#
|
|
14
|
+
# The JSON repeats the source, diff, and tests of each mutation,
|
|
15
|
+
# and compresses about twentyfold.
|
|
16
|
+
#
|
|
13
17
|
# Written to a temporary file first and renamed into place, so a
|
|
14
18
|
# concurrent reader of the session file never observes a partial
|
|
15
19
|
# document. This matters once the file is rewritten during a run.
|
|
16
20
|
#
|
|
17
21
|
# @return [Pathname]
|
|
18
22
|
def call
|
|
19
|
-
dir = env.world.pathname.new(
|
|
23
|
+
dir = env.world.pathname.new(SessionFiles::DIRECTORY)
|
|
20
24
|
dir.mkpath
|
|
21
25
|
|
|
22
|
-
path = dir.join("#{SESSION_ID}.json")
|
|
23
|
-
tmp_path = dir.join("#{SESSION_ID}.json.tmp")
|
|
24
|
-
tmp_path.
|
|
26
|
+
path = dir.join("#{SESSION_ID}.json.gz")
|
|
27
|
+
tmp_path = dir.join("#{SESSION_ID}.json.gz.tmp")
|
|
28
|
+
tmp_path.binwrite(Zlib.gzip(json))
|
|
25
29
|
tmp_path.rename(path)
|
|
26
30
|
|
|
27
31
|
path
|
|
@@ -41,7 +45,29 @@ module Mutant
|
|
|
41
45
|
ruby_version: RUBY_VERSION,
|
|
42
46
|
runtime: result.runtime,
|
|
43
47
|
session_id: SESSION_ID,
|
|
44
|
-
subject_results: result.subject_results
|
|
48
|
+
subject_results: result.subject_results.map(&method(:without_covered_logs))
|
|
49
|
+
)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def without_covered_logs(subject_result)
|
|
53
|
+
subject_result.with(
|
|
54
|
+
coverage_results: subject_result.coverage_results.map(&method(:without_log))
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# The log of a covered mutation is the output of the tests that
|
|
59
|
+
# killed it. The session subcommands only report alive mutations,
|
|
60
|
+
# so nothing reads it back, and on a suite whose failures print
|
|
61
|
+
# large values it is most of the session file.
|
|
62
|
+
def without_log(coverage_result)
|
|
63
|
+
return coverage_result unless coverage_result.success?
|
|
64
|
+
|
|
65
|
+
mutation_result = coverage_result.mutation_result
|
|
66
|
+
|
|
67
|
+
coverage_result.with(
|
|
68
|
+
mutation_result: mutation_result.with(
|
|
69
|
+
isolation_result: mutation_result.isolation_result.with(log: EMPTY_LOG)
|
|
70
|
+
)
|
|
45
71
|
)
|
|
46
72
|
end
|
|
47
73
|
end # JSONWriter
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mutant
|
|
4
|
+
module Result
|
|
5
|
+
# The session files of past runs in .mutant/results/
|
|
6
|
+
class SessionFiles
|
|
7
|
+
include Anima.new(:world)
|
|
8
|
+
|
|
9
|
+
DIRECTORY = '.mutant/results'
|
|
10
|
+
|
|
11
|
+
# Sessions this version writes gzip compressed, and those earlier
|
|
12
|
+
# versions wrote as plain JSON. The plain ones are listed first,
|
|
13
|
+
# each kind oldest first, as the earlier versions wrote them before
|
|
14
|
+
# this one wrote any.
|
|
15
|
+
PATTERN = '*.json{,.gz}'
|
|
16
|
+
|
|
17
|
+
# Sessions a run keeps, and `mutant session gc` keeps by default
|
|
18
|
+
KEEP = 100
|
|
19
|
+
|
|
20
|
+
# The session files, oldest first
|
|
21
|
+
#
|
|
22
|
+
# @return [Array<Pathname>]
|
|
23
|
+
def paths
|
|
24
|
+
dir = world.pathname.new(DIRECTORY)
|
|
25
|
+
|
|
26
|
+
return EMPTY_ARRAY unless dir.directory?
|
|
27
|
+
|
|
28
|
+
dir.glob(PATTERN)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Delete all but the most recent sessions
|
|
32
|
+
#
|
|
33
|
+
# A session written alongside this one by a concurrent run may
|
|
34
|
+
# have been deleted by that run already.
|
|
35
|
+
#
|
|
36
|
+
# @param [Integer] keep
|
|
37
|
+
#
|
|
38
|
+
# @return [Array<Pathname>]
|
|
39
|
+
# the deleted session files
|
|
40
|
+
def prune(keep)
|
|
41
|
+
excess = paths.reverse.drop(keep)
|
|
42
|
+
|
|
43
|
+
excess.each do |path|
|
|
44
|
+
path.delete
|
|
45
|
+
rescue Errno::ENOENT
|
|
46
|
+
nil
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end # SessionFiles
|
|
50
|
+
end # Result
|
|
51
|
+
end # Mutant
|
|
@@ -38,6 +38,28 @@ module Mutant
|
|
|
38
38
|
s(:begin, mutant, s(:send, nil, :memoize, s(:sym, name)))
|
|
39
39
|
end
|
|
40
40
|
end # Memoized
|
|
41
|
+
|
|
42
|
+
# Subject for instance methods exposed via module_function
|
|
43
|
+
#
|
|
44
|
+
# module_function copies the method onto the module's singleton
|
|
45
|
+
# class. Redefining only the instance method would leave that copy,
|
|
46
|
+
# which callers use, unmutated.
|
|
47
|
+
class ModuleFunction < self
|
|
48
|
+
|
|
49
|
+
# Prepare subject for mutation insertion
|
|
50
|
+
#
|
|
51
|
+
# @return [self]
|
|
52
|
+
def prepare
|
|
53
|
+
scope.raw.singleton_class.undef_method(name)
|
|
54
|
+
|
|
55
|
+
super
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Copy the inserted method onto the singleton class again
|
|
59
|
+
#
|
|
60
|
+
# @return [self]
|
|
61
|
+
def post_insert = tap { scope.raw.__send__(:module_function, name) }
|
|
62
|
+
end # ModuleFunction
|
|
41
63
|
end # Instance
|
|
42
64
|
end # Method
|
|
43
65
|
end # Subject
|
data/lib/mutant.rb
CHANGED
|
@@ -42,6 +42,7 @@ module Mutant
|
|
|
42
42
|
stringio
|
|
43
43
|
unparser
|
|
44
44
|
yaml
|
|
45
|
+
zlib
|
|
45
46
|
].each { |name| require(name) }
|
|
46
47
|
end
|
|
47
48
|
|
|
@@ -187,6 +188,7 @@ module Mutant
|
|
|
187
188
|
require 'mutant/mutator/node/procarg_zero'
|
|
188
189
|
require 'mutant/mutator/node/kwargs'
|
|
189
190
|
require 'mutant/mutator/node/numblock'
|
|
191
|
+
require 'mutant/mutator/node/itblock' if RUBY_VERSION > '3.4.0'
|
|
190
192
|
require 'mutant/mutator/node/const_pattern'
|
|
191
193
|
require 'mutant/mutator/regexp'
|
|
192
194
|
require 'mutant/loader'
|
|
@@ -249,6 +251,7 @@ module Mutant
|
|
|
249
251
|
require 'mutant/mutation/runner/sink'
|
|
250
252
|
require 'mutant/result'
|
|
251
253
|
require 'mutant/result/session'
|
|
254
|
+
require 'mutant/result/session_files'
|
|
252
255
|
require 'mutant/result/json_writer'
|
|
253
256
|
require 'mutant/reporter'
|
|
254
257
|
require 'mutant/reporter/null'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mutant
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.17.
|
|
4
|
+
version: 0.17.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Markus Schirp
|
|
@@ -304,6 +304,7 @@ files:
|
|
|
304
304
|
- lib/mutant/mutator/node/if.rb
|
|
305
305
|
- lib/mutant/mutator/node/in_pattern.rb
|
|
306
306
|
- lib/mutant/mutator/node/index.rb
|
|
307
|
+
- lib/mutant/mutator/node/itblock.rb
|
|
307
308
|
- lib/mutant/mutator/node/kwargs.rb
|
|
308
309
|
- lib/mutant/mutator/node/kwbegin.rb
|
|
309
310
|
- lib/mutant/mutator/node/literal.rb
|
|
@@ -389,6 +390,7 @@ files:
|
|
|
389
390
|
- lib/mutant/result/json_writer.rb
|
|
390
391
|
- lib/mutant/result/process_status.rb
|
|
391
392
|
- lib/mutant/result/session.rb
|
|
393
|
+
- lib/mutant/result/session_files.rb
|
|
392
394
|
- lib/mutant/result/test.rb
|
|
393
395
|
- lib/mutant/scope.rb
|
|
394
396
|
- lib/mutant/segment.rb
|
|
@@ -435,7 +437,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
435
437
|
- !ruby/object:Gem::Version
|
|
436
438
|
version: '0'
|
|
437
439
|
requirements: []
|
|
438
|
-
rubygems_version: 4.0.
|
|
440
|
+
rubygems_version: 4.0.20
|
|
439
441
|
specification_version: 4
|
|
440
442
|
summary: ''
|
|
441
443
|
test_files: []
|