evilution 0.12.0 → 0.14.0
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/.beads/.migration-hint-ts +1 -1
- data/.beads/issues.jsonl +127 -0
- data/CHANGELOG.md +29 -0
- data/lib/evilution/ast/parser.rb +69 -68
- data/lib/evilution/ast/source_surgeon.rb +7 -9
- data/lib/evilution/ast.rb +4 -0
- data/lib/evilution/baseline.rb +73 -75
- data/lib/evilution/cache.rb +75 -77
- data/lib/evilution/cli.rb +408 -173
- data/lib/evilution/config.rb +141 -136
- data/lib/evilution/equivalent/detector.rb +25 -27
- data/lib/evilution/equivalent/heuristic/alias_swap.rb +29 -33
- data/lib/evilution/equivalent/heuristic/dead_code.rb +41 -45
- data/lib/evilution/equivalent/heuristic/method_body_nil.rb +11 -15
- data/lib/evilution/equivalent/heuristic/noop_source.rb +5 -9
- data/lib/evilution/equivalent/heuristic.rb +6 -0
- data/lib/evilution/equivalent.rb +4 -0
- data/lib/evilution/git/changed_files.rb +35 -37
- data/lib/evilution/git.rb +4 -0
- data/lib/evilution/integration/base.rb +5 -7
- data/lib/evilution/integration/rspec.rb +114 -116
- data/lib/evilution/integration.rb +4 -0
- data/lib/evilution/isolation/fork.rb +98 -100
- data/lib/evilution/isolation/in_process.rb +59 -61
- data/lib/evilution/isolation.rb +4 -0
- data/lib/evilution/mcp/mutate_tool.rb +172 -143
- data/lib/evilution/mcp/server.rb +12 -11
- data/lib/evilution/mcp/session_diff_tool.rb +89 -0
- data/lib/evilution/mcp/session_list_tool.rb +46 -0
- data/lib/evilution/mcp/session_show_tool.rb +53 -0
- data/lib/evilution/mcp.rb +4 -0
- data/lib/evilution/memory/leak_check.rb +80 -84
- data/lib/evilution/memory.rb +34 -36
- data/lib/evilution/mutation.rb +40 -42
- data/lib/evilution/mutator/base.rb +46 -48
- data/lib/evilution/mutator/operator/argument_nil_substitution.rb +32 -36
- data/lib/evilution/mutator/operator/argument_removal.rb +32 -36
- data/lib/evilution/mutator/operator/arithmetic_replacement.rb +26 -30
- data/lib/evilution/mutator/operator/array_literal.rb +18 -22
- data/lib/evilution/mutator/operator/block_removal.rb +16 -20
- data/lib/evilution/mutator/operator/boolean_literal_replacement.rb +38 -42
- data/lib/evilution/mutator/operator/boolean_operator_replacement.rb +41 -45
- data/lib/evilution/mutator/operator/collection_replacement.rb +32 -36
- data/lib/evilution/mutator/operator/comparison_replacement.rb +24 -28
- data/lib/evilution/mutator/operator/compound_assignment.rb +119 -0
- data/lib/evilution/mutator/operator/conditional_branch.rb +25 -29
- data/lib/evilution/mutator/operator/conditional_flip.rb +26 -30
- data/lib/evilution/mutator/operator/conditional_negation.rb +25 -29
- data/lib/evilution/mutator/operator/float_literal.rb +22 -26
- data/lib/evilution/mutator/operator/hash_literal.rb +18 -22
- data/lib/evilution/mutator/operator/integer_literal.rb +18 -44
- data/lib/evilution/mutator/operator/method_body_replacement.rb +12 -16
- data/lib/evilution/mutator/operator/method_call_removal.rb +12 -16
- data/lib/evilution/mutator/operator/negation_insertion.rb +12 -16
- data/lib/evilution/mutator/operator/nil_replacement.rb +13 -17
- data/lib/evilution/mutator/operator/range_replacement.rb +12 -16
- data/lib/evilution/mutator/operator/receiver_replacement.rb +16 -20
- data/lib/evilution/mutator/operator/regexp_mutation.rb +15 -19
- data/lib/evilution/mutator/operator/return_value_removal.rb +12 -16
- data/lib/evilution/mutator/operator/send_mutation.rb +36 -40
- data/lib/evilution/mutator/operator/statement_deletion.rb +13 -17
- data/lib/evilution/mutator/operator/string_literal.rb +18 -22
- data/lib/evilution/mutator/operator/symbol_literal.rb +17 -21
- data/lib/evilution/mutator/operator.rb +6 -0
- data/lib/evilution/mutator/registry.rb +54 -55
- data/lib/evilution/mutator.rb +4 -0
- data/lib/evilution/parallel/pool.rb +56 -58
- data/lib/evilution/parallel.rb +4 -0
- data/lib/evilution/reporter/cli.rb +99 -101
- data/lib/evilution/reporter/html.rb +242 -244
- data/lib/evilution/reporter/json.rb +57 -59
- data/lib/evilution/reporter/suggestion.rb +326 -313
- data/lib/evilution/reporter.rb +4 -0
- data/lib/evilution/result/mutation_result.rb +43 -46
- data/lib/evilution/result/summary.rb +80 -81
- data/lib/evilution/result.rb +4 -0
- data/lib/evilution/runner.rb +334 -323
- data/lib/evilution/session/store.rb +147 -0
- data/lib/evilution/session.rb +4 -0
- data/lib/evilution/spec_resolver.rb +49 -47
- data/lib/evilution/subject.rb +14 -16
- data/lib/evilution/version.rb +1 -1
- data/lib/evilution.rb +14 -0
- metadata +20 -2
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "securerandom"
|
|
5
|
+
require "time"
|
|
6
|
+
require "fileutils"
|
|
7
|
+
|
|
8
|
+
require_relative "../session"
|
|
9
|
+
|
|
10
|
+
class Evilution::Session::Store
|
|
11
|
+
DEFAULT_DIR = ".evilution/results"
|
|
12
|
+
|
|
13
|
+
def initialize(results_dir: DEFAULT_DIR)
|
|
14
|
+
@results_dir = results_dir
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def save(summary)
|
|
18
|
+
FileUtils.mkdir_p(@results_dir)
|
|
19
|
+
|
|
20
|
+
now = Time.now
|
|
21
|
+
data = build_session_data(summary, now)
|
|
22
|
+
filename = "#{format_timestamp(now)}-#{SecureRandom.hex(4)}.json"
|
|
23
|
+
path = File.join(@results_dir, filename)
|
|
24
|
+
atomic_write(path, JSON.pretty_generate(data))
|
|
25
|
+
path
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def list
|
|
29
|
+
return [] unless Dir.exist?(@results_dir)
|
|
30
|
+
|
|
31
|
+
Dir
|
|
32
|
+
.glob(File.join(@results_dir, "*.json"))
|
|
33
|
+
.sort_by { |f| File.basename(f) }
|
|
34
|
+
.reverse
|
|
35
|
+
.filter_map { |f| build_list_entry(f) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def load(path)
|
|
39
|
+
raise Evilution::Error, "session file not found: #{path}" unless File.exist?(path)
|
|
40
|
+
|
|
41
|
+
JSON.parse(File.read(path))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def gc(older_than:)
|
|
45
|
+
return [] unless Dir.exist?(@results_dir)
|
|
46
|
+
|
|
47
|
+
deleted = []
|
|
48
|
+
Dir.glob(File.join(@results_dir, "*.json")).each do |file|
|
|
49
|
+
timestamp = parse_filename_timestamp(File.basename(file))
|
|
50
|
+
next unless timestamp
|
|
51
|
+
next unless timestamp < older_than
|
|
52
|
+
|
|
53
|
+
File.delete(file)
|
|
54
|
+
deleted << file
|
|
55
|
+
end
|
|
56
|
+
deleted
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def build_session_data(summary, now)
|
|
62
|
+
{
|
|
63
|
+
version: Evilution::VERSION,
|
|
64
|
+
timestamp: now.iso8601,
|
|
65
|
+
git: git_context,
|
|
66
|
+
summary: build_summary(summary),
|
|
67
|
+
survived: summary.survived_results.map { |r| build_mutation_detail(r) },
|
|
68
|
+
killed_count: summary.killed,
|
|
69
|
+
timed_out_count: summary.timed_out,
|
|
70
|
+
error_count: summary.errors,
|
|
71
|
+
neutral_count: summary.neutral,
|
|
72
|
+
equivalent_count: summary.equivalent
|
|
73
|
+
}
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def build_summary(summary)
|
|
77
|
+
{
|
|
78
|
+
total: summary.total,
|
|
79
|
+
killed: summary.killed,
|
|
80
|
+
survived: summary.survived,
|
|
81
|
+
timed_out: summary.timed_out,
|
|
82
|
+
errors: summary.errors,
|
|
83
|
+
neutral: summary.neutral,
|
|
84
|
+
equivalent: summary.equivalent,
|
|
85
|
+
score: summary.score.round(4),
|
|
86
|
+
duration: summary.duration.round(4)
|
|
87
|
+
}
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def build_mutation_detail(result)
|
|
91
|
+
mutation = result.mutation
|
|
92
|
+
{
|
|
93
|
+
operator: mutation.operator_name,
|
|
94
|
+
file: mutation.file_path,
|
|
95
|
+
line: mutation.line,
|
|
96
|
+
subject: mutation.subject.name,
|
|
97
|
+
diff: mutation.diff
|
|
98
|
+
}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def git_context
|
|
102
|
+
sha = `git rev-parse HEAD 2>/dev/null`.strip
|
|
103
|
+
branch = `git rev-parse --abbrev-ref HEAD 2>/dev/null`.strip
|
|
104
|
+
{
|
|
105
|
+
sha: sha.empty? ? nil : sha,
|
|
106
|
+
branch: branch.empty? ? nil : branch
|
|
107
|
+
}
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def parse_filename_timestamp(basename)
|
|
111
|
+
match = basename.match(/\A(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})/)
|
|
112
|
+
return nil unless match
|
|
113
|
+
|
|
114
|
+
Time.new(*match[1..6].map(&:to_i))
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def format_timestamp(time)
|
|
118
|
+
time.strftime("%Y%m%dT%H%M%S")
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def atomic_write(path, content)
|
|
122
|
+
temp_path = "#{path}.tmp-#{Process.pid}-#{SecureRandom.hex(4)}"
|
|
123
|
+
File.write(temp_path, content)
|
|
124
|
+
File.rename(temp_path, path)
|
|
125
|
+
rescue StandardError
|
|
126
|
+
FileUtils.rm_f(temp_path)
|
|
127
|
+
raise
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def build_list_entry(file)
|
|
131
|
+
data = ::JSON.parse(File.read(file))
|
|
132
|
+
summary = data["summary"]
|
|
133
|
+
return nil unless data.is_a?(Hash) && summary.is_a?(Hash)
|
|
134
|
+
|
|
135
|
+
{
|
|
136
|
+
file: file,
|
|
137
|
+
timestamp: data["timestamp"],
|
|
138
|
+
total: summary["total"],
|
|
139
|
+
killed: summary["killed"],
|
|
140
|
+
survived: summary["survived"],
|
|
141
|
+
score: summary["score"],
|
|
142
|
+
duration: summary["duration"]
|
|
143
|
+
}
|
|
144
|
+
rescue ::JSON::ParserError, SystemCallError
|
|
145
|
+
nil
|
|
146
|
+
end
|
|
147
|
+
end
|
|
@@ -1,62 +1,64 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
STRIPPABLE_PREFIXES = %w[lib/ app/].freeze
|
|
3
|
+
class Evilution::SpecResolver
|
|
4
|
+
STRIPPABLE_PREFIXES = %w[lib/ app/].freeze
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
def call(source_path)
|
|
7
|
+
return nil if source_path.nil? || source_path.empty?
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
normalized = normalize_path(source_path)
|
|
10
|
+
candidates = candidate_spec_paths(normalized)
|
|
11
|
+
candidates.find { |path| File.exist?(path) }
|
|
12
|
+
end
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
def resolve_all(source_paths)
|
|
15
|
+
Array(source_paths).filter_map { |path| call(path) }.uniq
|
|
16
|
+
end
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
private
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
def normalize_path(path)
|
|
21
|
+
path = path.delete_prefix("./")
|
|
22
|
+
path = path.delete_prefix("#{Dir.pwd}/") if path.start_with?("/")
|
|
23
|
+
path
|
|
24
|
+
end
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
def candidate_spec_paths(source_path)
|
|
27
|
+
base = source_path.sub(/\.rb\z/, "_spec.rb")
|
|
28
|
+
prefix = STRIPPABLE_PREFIXES.find { |p| source_path.start_with?(p) }
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
candidates = if prefix
|
|
31
|
+
stripped = base.delete_prefix(prefix)
|
|
32
|
+
["spec/#{stripped}", "spec/#{base}"]
|
|
33
|
+
else
|
|
34
|
+
["spec/#{base}"]
|
|
35
|
+
end
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
candidates + fallbacks
|
|
40
|
-
end
|
|
37
|
+
fallbacks = candidates.flat_map { |c| parent_fallback_candidates(c) }.uniq
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
39
|
+
candidates + fallbacks
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def parent_fallback_candidates(spec_path)
|
|
43
|
+
parts = spec_path.split("/")
|
|
44
|
+
# parts: ["spec", "foo", "bar_spec.rb"] — need at least 3 parts for fallback
|
|
45
|
+
return [] if parts.length < 3
|
|
46
|
+
|
|
47
|
+
candidates = []
|
|
48
|
+
# Remove filename, then progressively remove directories
|
|
49
|
+
dir_parts = parts[1..-2] # ["models", "game"]
|
|
50
|
+
|
|
51
|
+
(dir_parts.length - 1).downto(0) do |i|
|
|
52
|
+
file = "#{dir_parts[i]}_spec.rb"
|
|
53
|
+
|
|
54
|
+
if i.zero?
|
|
55
|
+
candidates << "spec/#{file}"
|
|
56
|
+
else
|
|
57
|
+
parent = dir_parts[0...i].join("/")
|
|
58
|
+
candidates << "spec/#{parent}/#{file}"
|
|
58
59
|
end
|
|
59
|
-
candidates
|
|
60
60
|
end
|
|
61
|
+
|
|
62
|
+
candidates
|
|
61
63
|
end
|
|
62
64
|
end
|
data/lib/evilution/subject.rb
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
attr_reader :name, :file_path, :line_number, :source, :node
|
|
3
|
+
class Evilution::Subject
|
|
4
|
+
attr_reader :name, :file_path, :line_number, :source, :node
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
def initialize(name:, file_path:, line_number:, source:, node:)
|
|
7
|
+
@name = name
|
|
8
|
+
@file_path = file_path
|
|
9
|
+
@line_number = line_number
|
|
10
|
+
@source = source
|
|
11
|
+
@node = node
|
|
12
|
+
end
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
def release_node!
|
|
15
|
+
@node = nil
|
|
16
|
+
end
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
end
|
|
18
|
+
def to_s
|
|
19
|
+
"#{name} (#{file_path}:#{line_number})"
|
|
22
20
|
end
|
|
23
21
|
end
|
data/lib/evilution/version.rb
CHANGED
data/lib/evilution.rb
CHANGED
|
@@ -4,10 +4,15 @@ require_relative "evilution/version"
|
|
|
4
4
|
require_relative "evilution/memory"
|
|
5
5
|
require_relative "evilution/config"
|
|
6
6
|
require_relative "evilution/subject"
|
|
7
|
+
require_relative "evilution/result"
|
|
7
8
|
require_relative "evilution/mutation"
|
|
9
|
+
require_relative "evilution/ast"
|
|
10
|
+
require_relative "evilution/parallel"
|
|
8
11
|
require_relative "evilution/ast/source_surgeon"
|
|
9
12
|
require_relative "evilution/ast/parser"
|
|
13
|
+
require_relative "evilution/mutator"
|
|
10
14
|
require_relative "evilution/mutator/base"
|
|
15
|
+
require_relative "evilution/mutator/operator"
|
|
11
16
|
require_relative "evilution/mutator/operator/comparison_replacement"
|
|
12
17
|
require_relative "evilution/mutator/operator/boolean_literal_replacement"
|
|
13
18
|
require_relative "evilution/mutator/operator/integer_literal"
|
|
@@ -35,16 +40,25 @@ require_relative "evilution/mutator/operator/regexp_mutation"
|
|
|
35
40
|
require_relative "evilution/mutator/operator/receiver_replacement"
|
|
36
41
|
require_relative "evilution/mutator/operator/send_mutation"
|
|
37
42
|
require_relative "evilution/mutator/operator/argument_nil_substitution"
|
|
43
|
+
require_relative "evilution/mutator/operator/compound_assignment"
|
|
38
44
|
require_relative "evilution/mutator/registry"
|
|
45
|
+
require_relative "evilution/equivalent"
|
|
46
|
+
require_relative "evilution/equivalent/heuristic"
|
|
39
47
|
require_relative "evilution/equivalent/detector"
|
|
48
|
+
require_relative "evilution/isolation"
|
|
40
49
|
require_relative "evilution/isolation/fork"
|
|
41
50
|
require_relative "evilution/isolation/in_process"
|
|
42
51
|
require_relative "evilution/parallel/pool"
|
|
52
|
+
require_relative "evilution/session"
|
|
53
|
+
require_relative "evilution/session/store"
|
|
54
|
+
require_relative "evilution/git"
|
|
43
55
|
require_relative "evilution/git/changed_files"
|
|
56
|
+
require_relative "evilution/integration"
|
|
44
57
|
require_relative "evilution/integration/base"
|
|
45
58
|
require_relative "evilution/integration/rspec"
|
|
46
59
|
require_relative "evilution/result/mutation_result"
|
|
47
60
|
require_relative "evilution/result/summary"
|
|
61
|
+
require_relative "evilution/reporter"
|
|
48
62
|
require_relative "evilution/reporter/json"
|
|
49
63
|
require_relative "evilution/reporter/cli"
|
|
50
64
|
require_relative "evilution/reporter/html"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: evilution
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.14.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Denis Kiselev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: diff-lcs
|
|
@@ -78,28 +78,40 @@ files:
|
|
|
78
78
|
- claude-swarm.yml
|
|
79
79
|
- exe/evilution
|
|
80
80
|
- lib/evilution.rb
|
|
81
|
+
- lib/evilution/ast.rb
|
|
81
82
|
- lib/evilution/ast/parser.rb
|
|
82
83
|
- lib/evilution/ast/source_surgeon.rb
|
|
83
84
|
- lib/evilution/baseline.rb
|
|
84
85
|
- lib/evilution/cache.rb
|
|
85
86
|
- lib/evilution/cli.rb
|
|
86
87
|
- lib/evilution/config.rb
|
|
88
|
+
- lib/evilution/equivalent.rb
|
|
87
89
|
- lib/evilution/equivalent/detector.rb
|
|
90
|
+
- lib/evilution/equivalent/heuristic.rb
|
|
88
91
|
- lib/evilution/equivalent/heuristic/alias_swap.rb
|
|
89
92
|
- lib/evilution/equivalent/heuristic/dead_code.rb
|
|
90
93
|
- lib/evilution/equivalent/heuristic/method_body_nil.rb
|
|
91
94
|
- lib/evilution/equivalent/heuristic/noop_source.rb
|
|
95
|
+
- lib/evilution/git.rb
|
|
92
96
|
- lib/evilution/git/changed_files.rb
|
|
97
|
+
- lib/evilution/integration.rb
|
|
93
98
|
- lib/evilution/integration/base.rb
|
|
94
99
|
- lib/evilution/integration/rspec.rb
|
|
100
|
+
- lib/evilution/isolation.rb
|
|
95
101
|
- lib/evilution/isolation/fork.rb
|
|
96
102
|
- lib/evilution/isolation/in_process.rb
|
|
103
|
+
- lib/evilution/mcp.rb
|
|
97
104
|
- lib/evilution/mcp/mutate_tool.rb
|
|
98
105
|
- lib/evilution/mcp/server.rb
|
|
106
|
+
- lib/evilution/mcp/session_diff_tool.rb
|
|
107
|
+
- lib/evilution/mcp/session_list_tool.rb
|
|
108
|
+
- lib/evilution/mcp/session_show_tool.rb
|
|
99
109
|
- lib/evilution/memory.rb
|
|
100
110
|
- lib/evilution/memory/leak_check.rb
|
|
101
111
|
- lib/evilution/mutation.rb
|
|
112
|
+
- lib/evilution/mutator.rb
|
|
102
113
|
- lib/evilution/mutator/base.rb
|
|
114
|
+
- lib/evilution/mutator/operator.rb
|
|
103
115
|
- lib/evilution/mutator/operator/argument_nil_substitution.rb
|
|
104
116
|
- lib/evilution/mutator/operator/argument_removal.rb
|
|
105
117
|
- lib/evilution/mutator/operator/arithmetic_replacement.rb
|
|
@@ -109,6 +121,7 @@ files:
|
|
|
109
121
|
- lib/evilution/mutator/operator/boolean_operator_replacement.rb
|
|
110
122
|
- lib/evilution/mutator/operator/collection_replacement.rb
|
|
111
123
|
- lib/evilution/mutator/operator/comparison_replacement.rb
|
|
124
|
+
- lib/evilution/mutator/operator/compound_assignment.rb
|
|
112
125
|
- lib/evilution/mutator/operator/conditional_branch.rb
|
|
113
126
|
- lib/evilution/mutator/operator/conditional_flip.rb
|
|
114
127
|
- lib/evilution/mutator/operator/conditional_negation.rb
|
|
@@ -128,14 +141,19 @@ files:
|
|
|
128
141
|
- lib/evilution/mutator/operator/string_literal.rb
|
|
129
142
|
- lib/evilution/mutator/operator/symbol_literal.rb
|
|
130
143
|
- lib/evilution/mutator/registry.rb
|
|
144
|
+
- lib/evilution/parallel.rb
|
|
131
145
|
- lib/evilution/parallel/pool.rb
|
|
146
|
+
- lib/evilution/reporter.rb
|
|
132
147
|
- lib/evilution/reporter/cli.rb
|
|
133
148
|
- lib/evilution/reporter/html.rb
|
|
134
149
|
- lib/evilution/reporter/json.rb
|
|
135
150
|
- lib/evilution/reporter/suggestion.rb
|
|
151
|
+
- lib/evilution/result.rb
|
|
136
152
|
- lib/evilution/result/mutation_result.rb
|
|
137
153
|
- lib/evilution/result/summary.rb
|
|
138
154
|
- lib/evilution/runner.rb
|
|
155
|
+
- lib/evilution/session.rb
|
|
156
|
+
- lib/evilution/session/store.rb
|
|
139
157
|
- lib/evilution/spec_resolver.rb
|
|
140
158
|
- lib/evilution/subject.rb
|
|
141
159
|
- lib/evilution/version.rb
|