henitai 0.1.2 → 0.1.3
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/CHANGELOG.md +82 -1
- data/README.md +3 -1
- data/assets/schema/henitai.schema.json +0 -4
- data/lib/henitai/arid_node_filter.rb +3 -0
- data/lib/henitai/available_cpu_count.rb +79 -0
- data/lib/henitai/cli.rb +7 -4
- data/lib/henitai/configuration.rb +3 -5
- data/lib/henitai/configuration_validator.rb +1 -11
- data/lib/henitai/coverage_bootstrapper.rb +112 -7
- data/lib/henitai/coverage_report_reader.rb +67 -0
- data/lib/henitai/eager_load.rb +11 -0
- data/lib/henitai/equivalence_detector.rb +60 -1
- data/lib/henitai/execution_engine.rb +34 -22
- data/lib/henitai/integration/rspec_process_runner.rb +58 -0
- data/lib/henitai/integration.rb +192 -90
- data/lib/henitai/mutant.rb +3 -1
- data/lib/henitai/mutant_generator.rb +25 -48
- data/lib/henitai/operator.rb +6 -1
- data/lib/henitai/operators/assignment_expression.rb +7 -23
- data/lib/henitai/operators/conditional_expression.rb +1 -7
- data/lib/henitai/operators/method_chain_unwrap.rb +41 -0
- data/lib/henitai/operators/regex_mutator.rb +89 -0
- data/lib/henitai/operators/unary_operator.rb +36 -0
- data/lib/henitai/operators/update_operator.rb +70 -0
- data/lib/henitai/operators.rb +4 -0
- data/lib/henitai/parallel_execution_runner.rb +135 -0
- data/lib/henitai/per_test_coverage_selector.rb +60 -0
- data/lib/henitai/result.rb +16 -4
- data/lib/henitai/runner.rb +75 -11
- data/lib/henitai/source_parser.rb +12 -1
- data/lib/henitai/static_filter.rb +20 -41
- data/lib/henitai/version.rb +1 -1
- data/lib/henitai.rb +3 -0
- data/sig/henitai.rbs +59 -10
- metadata +16 -3
|
@@ -12,12 +12,23 @@ module Henitai
|
|
|
12
12
|
class SourceParser
|
|
13
13
|
DEFAULT_PATH = "(string)"
|
|
14
14
|
|
|
15
|
+
@cache = {}
|
|
16
|
+
|
|
15
17
|
def self.parse(source, path: DEFAULT_PATH)
|
|
16
18
|
new.parse(source, path:)
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
# Returns the parsed AST for +path+, re-using a cached result when the
|
|
22
|
+
# file's mtime has not changed. This avoids parsing the same file twice
|
|
23
|
+
# across pipeline phases (e.g. SubjectResolver then MutantGenerator).
|
|
19
24
|
def self.parse_file(path)
|
|
20
|
-
|
|
25
|
+
key = [path, File.mtime(path)]
|
|
26
|
+
@cache[key] ||= new.parse_file(path)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Clears the parse cache. Intended for test isolation.
|
|
30
|
+
def self.clear_cache!
|
|
31
|
+
@cache.clear
|
|
21
32
|
end
|
|
22
33
|
|
|
23
34
|
def parse(source, path: DEFAULT_PATH)
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require_relative "coverage_report_reader"
|
|
4
4
|
|
|
5
5
|
module Henitai
|
|
6
6
|
# Applies static, pre-execution filtering to generated mutants.
|
|
7
7
|
class StaticFilter
|
|
8
|
-
DEFAULT_COVERAGE_REPORT_PATH =
|
|
9
|
-
DEFAULT_PER_TEST_COVERAGE_REPORT_PATH =
|
|
8
|
+
DEFAULT_COVERAGE_REPORT_PATH = CoverageReportReader::DEFAULT_COVERAGE_REPORT_PATH
|
|
9
|
+
DEFAULT_PER_TEST_COVERAGE_REPORT_PATH = CoverageReportReader::DEFAULT_PER_TEST_COVERAGE_REPORT_PATH
|
|
10
|
+
|
|
11
|
+
def initialize(coverage_report_reader: CoverageReportReader.new)
|
|
12
|
+
@coverage_report_reader = coverage_report_reader
|
|
13
|
+
end
|
|
10
14
|
|
|
11
15
|
# This method is the gate-level filter orchestrator.
|
|
12
16
|
def apply(mutants, config)
|
|
@@ -41,31 +45,17 @@ module Henitai
|
|
|
41
45
|
end
|
|
42
46
|
|
|
43
47
|
def coverage_lines_by_file(path = DEFAULT_COVERAGE_REPORT_PATH)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
coverage = Hash.new { |hash, key| hash[key] = [] }
|
|
47
|
-
JSON.parse(File.read(path)).each_value do |result|
|
|
48
|
-
result.fetch("coverage", {}).each do |file, file_coverage|
|
|
49
|
-
coverage[normalize_path(file)].concat(covered_lines(file_coverage))
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
coverage.transform_values(&:uniq).transform_values(&:sort)
|
|
48
|
+
coverage_report_reader.coverage_lines_by_file(path)
|
|
54
49
|
end
|
|
55
50
|
|
|
56
51
|
def test_lines_by_file(path = DEFAULT_PER_TEST_COVERAGE_REPORT_PATH)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
parsed = JSON.parse(File.read(path))
|
|
60
|
-
return {} unless parsed.is_a?(Hash)
|
|
61
|
-
|
|
62
|
-
parsed.transform_values do |coverage|
|
|
63
|
-
normalize_test_coverage(coverage)
|
|
64
|
-
end
|
|
52
|
+
coverage_report_reader.test_lines_by_file(path)
|
|
65
53
|
end
|
|
66
54
|
|
|
67
55
|
private
|
|
68
56
|
|
|
57
|
+
attr_reader :coverage_report_reader
|
|
58
|
+
|
|
69
59
|
def ignored?(mutant, config)
|
|
70
60
|
source = source_for(mutant)
|
|
71
61
|
return false unless source
|
|
@@ -151,23 +141,6 @@ module Henitai
|
|
|
151
141
|
(m.captures.first.to_i..m.captures.last.to_i)
|
|
152
142
|
end
|
|
153
143
|
|
|
154
|
-
def covered_lines(file_coverage)
|
|
155
|
-
Array(file_coverage["lines"]).each_with_index.filter_map do |count, index|
|
|
156
|
-
index + 1 if count.to_i.positive?
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def normalize_test_coverage(coverage)
|
|
161
|
-
case coverage
|
|
162
|
-
when Hash
|
|
163
|
-
coverage.transform_values do |lines|
|
|
164
|
-
Array(lines).grep(Integer).uniq.sort
|
|
165
|
-
end
|
|
166
|
-
else
|
|
167
|
-
Array(coverage).grep(Integer).uniq.sort
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
|
|
171
144
|
def coverage_lines_from_test_lines(test_lines)
|
|
172
145
|
coverage = Hash.new { |hash, key| hash[key] = [] }
|
|
173
146
|
|
|
@@ -183,10 +156,16 @@ module Henitai
|
|
|
183
156
|
end
|
|
184
157
|
|
|
185
158
|
def normalize_path(path)
|
|
159
|
+
@normalize_path_cache ||= {}
|
|
160
|
+
return @normalize_path_cache[path] if @normalize_path_cache.key?(path)
|
|
161
|
+
|
|
186
162
|
expanded = File.expand_path(path)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
163
|
+
resolved = begin
|
|
164
|
+
File.realpath(expanded)
|
|
165
|
+
rescue Errno::ENOENT, Errno::ENOTDIR
|
|
166
|
+
expanded
|
|
167
|
+
end
|
|
168
|
+
@normalize_path_cache[path] = resolved
|
|
190
169
|
end
|
|
191
170
|
|
|
192
171
|
def equivalence_detector
|
data/lib/henitai/version.rb
CHANGED
data/lib/henitai.rb
CHANGED
|
@@ -22,6 +22,8 @@ module Henitai
|
|
|
22
22
|
|
|
23
23
|
autoload :Configuration, "henitai/configuration"
|
|
24
24
|
autoload :CoverageBootstrapper, "henitai/coverage_bootstrapper"
|
|
25
|
+
autoload :CoverageReportReader, "henitai/coverage_report_reader"
|
|
26
|
+
autoload :PerTestCoverageSelector, "henitai/per_test_coverage_selector"
|
|
25
27
|
autoload :Subject, "henitai/subject"
|
|
26
28
|
autoload :Mutant, "henitai/mutant"
|
|
27
29
|
autoload :Operator, "henitai/operator"
|
|
@@ -33,6 +35,7 @@ module Henitai
|
|
|
33
35
|
autoload :MutantGenerator, "henitai/mutant_generator"
|
|
34
36
|
autoload :MutantHistoryStore, "henitai/mutant_history_store"
|
|
35
37
|
autoload :AridNodeFilter, "henitai/arid_node_filter"
|
|
38
|
+
autoload :AvailableCpuCount, "henitai/available_cpu_count"
|
|
36
39
|
autoload :EquivalenceDetector, "henitai/equivalence_detector"
|
|
37
40
|
autoload :StaticFilter, "henitai/static_filter"
|
|
38
41
|
autoload :StillbornFilter, "henitai/stillborn_filter"
|
data/sig/henitai.rbs
CHANGED
|
@@ -154,6 +154,8 @@ module Henitai
|
|
|
154
154
|
attr_accessor status: Symbol
|
|
155
155
|
attr_accessor killing_test: String?
|
|
156
156
|
attr_accessor duration: Float?
|
|
157
|
+
attr_accessor covered_by: Array[String]?
|
|
158
|
+
attr_accessor tests_completed: Integer?
|
|
157
159
|
|
|
158
160
|
def initialize: (subject: Subject, operator: String, nodes: Hash[Symbol, untyped], description: String, location: Hash[Symbol, untyped]) -> void
|
|
159
161
|
def killed?: () -> bool
|
|
@@ -223,15 +225,30 @@ module Henitai
|
|
|
223
225
|
def test_files: () -> Array[String]
|
|
224
226
|
def run_mutant: (mutant: Mutant, test_files: Array[String], timeout: Float) -> ScenarioExecutionResult
|
|
225
227
|
def run_suite: (Array[String], ?timeout: Float) -> ScenarioExecutionResult
|
|
228
|
+
def per_test_coverage_supported?: () -> bool
|
|
229
|
+
def wait_with_timeout: (Integer, Float) -> untyped
|
|
230
|
+
def reap_child: (Integer) -> void
|
|
231
|
+
def cleanup_process_group: (Integer) -> void
|
|
226
232
|
|
|
227
233
|
private
|
|
228
234
|
|
|
229
235
|
def pause: (Float) -> void
|
|
236
|
+
def handle_timeout: (Integer) -> Symbol
|
|
237
|
+
def cleanup_child_process: (Integer) -> void
|
|
238
|
+
def rspec_options: () -> Array[String]
|
|
239
|
+
def subprocess_env: () -> Hash[String, String]
|
|
240
|
+
def scenario_log_support: () -> ScenarioLogSupport
|
|
241
|
+
def with_subprocess_env: () { () -> untyped } -> untyped
|
|
242
|
+
def restore_subprocess_env: (Hash[String, String?]) -> void
|
|
243
|
+
def spawn_suite_process: (Array[String], Hash[Symbol, String]) -> Integer
|
|
230
244
|
end
|
|
231
245
|
|
|
232
246
|
class ScenarioLogSupport
|
|
233
247
|
def capture_child_output: (Hash[Symbol, String]) { () -> untyped } -> untyped
|
|
234
248
|
def with_coverage_dir: (String) { () -> untyped } -> untyped
|
|
249
|
+
def read_log_file: (String) -> String
|
|
250
|
+
def write_combined_log: (String, String, String) -> void
|
|
251
|
+
def combined_log: (String, String) -> String
|
|
235
252
|
|
|
236
253
|
private
|
|
237
254
|
|
|
@@ -248,6 +265,11 @@ module Henitai
|
|
|
248
265
|
def stderr_stream: () -> IO
|
|
249
266
|
end
|
|
250
267
|
|
|
268
|
+
class RspecProcessRunner
|
|
269
|
+
def run_mutant: (Rspec, mutant: Mutant, test_files: Array[String], timeout: Float) -> ScenarioExecutionResult
|
|
270
|
+
def run_suite: (Rspec, Array[String], timeout: Float) -> ScenarioExecutionResult
|
|
271
|
+
end
|
|
272
|
+
|
|
251
273
|
class Rspec < Base
|
|
252
274
|
REQUIRE_DIRECTIVE_PATTERN: Regexp
|
|
253
275
|
DEFAULT_SUITE_TIMEOUT: Float
|
|
@@ -256,13 +278,12 @@ module Henitai
|
|
|
256
278
|
def test_files: () -> Array[String]
|
|
257
279
|
def run_mutant: (mutant: Mutant, test_files: Array[String], timeout: Float) -> ScenarioExecutionResult
|
|
258
280
|
def run_suite: (Array[String], ?timeout: Float) -> ScenarioExecutionResult
|
|
281
|
+
def per_test_coverage_supported?: () -> bool
|
|
259
282
|
|
|
260
283
|
private
|
|
261
284
|
|
|
262
285
|
def run_in_child: (mutant: Mutant, test_files: Array[String], log_paths: Hash[Symbol, String]) -> Integer
|
|
263
286
|
def suite_command: (Array[String]) -> Array[String]
|
|
264
|
-
def wait_with_timeout: (Integer, Float) -> untyped
|
|
265
|
-
def handle_timeout: (Integer) -> Symbol
|
|
266
287
|
def build_result: (untyped, Hash[Symbol, String]) -> ScenarioExecutionResult
|
|
267
288
|
def scenario_status: (untyped) -> Symbol
|
|
268
289
|
def exit_status_for: (untyped) -> Integer?
|
|
@@ -271,8 +292,7 @@ module Henitai
|
|
|
271
292
|
def combined_log: (String, String) -> String
|
|
272
293
|
def scenario_log_paths: (String) -> Hash[Symbol, String]
|
|
273
294
|
def run_tests: (Array[String]) -> Integer
|
|
274
|
-
def
|
|
275
|
-
def rspec_options: () -> Array[String]
|
|
295
|
+
def with_subprocess_env: () { () -> untyped } -> untyped
|
|
276
296
|
def spec_files: () -> Array[String]
|
|
277
297
|
def fallback_spec_files: (Subject) -> Array[String]
|
|
278
298
|
def selection_patterns: (Subject) -> Array[String]
|
|
@@ -283,7 +303,6 @@ module Henitai
|
|
|
283
303
|
def relative_candidates: (String, String) -> Array[String]
|
|
284
304
|
def require_candidates: (String, String) -> Array[String]
|
|
285
305
|
def expand_candidates: (String, String) -> Array[String]
|
|
286
|
-
def reap_child: (Integer) -> void
|
|
287
306
|
end
|
|
288
307
|
|
|
289
308
|
class Minitest < Rspec
|
|
@@ -293,11 +312,11 @@ module Henitai
|
|
|
293
312
|
private
|
|
294
313
|
|
|
295
314
|
def run_in_child: (mutant: Mutant, test_files: Array[String], log_paths: Hash[Symbol, String]) -> Integer
|
|
296
|
-
def suite_command: (Array[String]) -> Array[String]
|
|
297
315
|
def run_tests: (Array[String]) -> Integer
|
|
298
316
|
def preload_environment: () -> void
|
|
299
317
|
def setup_load_path: () -> void
|
|
300
318
|
def subprocess_env: () -> Hash[String, String]
|
|
319
|
+
def cleanup_suite_process: (Integer?, untyped) -> void
|
|
301
320
|
def spec_files: () -> Array[String]
|
|
302
321
|
end
|
|
303
322
|
end
|
|
@@ -347,13 +366,29 @@ module Henitai
|
|
|
347
366
|
def fallback_source: (untyped) -> String
|
|
348
367
|
end
|
|
349
368
|
|
|
369
|
+
class CoverageReportReader
|
|
370
|
+
def coverage_lines_by_file: (?String) -> Hash[String, Array[Integer]]
|
|
371
|
+
def test_lines_by_file: (?String) -> Hash[String, Hash[String, Array[Integer]]]
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
class ParallelExecutionRunner
|
|
375
|
+
def initialize: (worker_count: Integer) -> void
|
|
376
|
+
def run: (Array[Mutant], untyped, untyped, untyped, ?Hash[Symbol, untyped]) -> void
|
|
377
|
+
end
|
|
378
|
+
|
|
350
379
|
class StaticFilter
|
|
380
|
+
def initialize: (?coverage_report_reader: CoverageReportReader) -> void
|
|
351
381
|
def apply: (Array[Mutant], untyped) -> Array[Mutant]
|
|
352
382
|
def coverage_lines_for: (untyped) -> Hash[String, Array[Integer]]
|
|
353
383
|
def coverage_lines_by_file: (?String) -> Hash[String, Array[Integer]]
|
|
354
384
|
def test_lines_by_file: (?String) -> Hash[String, Hash[String, Array[Integer]]]
|
|
355
385
|
end
|
|
356
386
|
|
|
387
|
+
class PerTestCoverageSelector
|
|
388
|
+
def initialize: (?coverage_report_reader: CoverageReportReader) -> void
|
|
389
|
+
def filter: (Array[String], Mutant, reports_dir: String) -> Array[String]
|
|
390
|
+
end
|
|
391
|
+
|
|
357
392
|
class ExecutionEngine
|
|
358
393
|
def run: (Array[Mutant], untyped, untyped, ?progress_reporter: untyped) -> Array[Mutant]
|
|
359
394
|
|
|
@@ -363,6 +398,8 @@ module Henitai
|
|
|
363
398
|
def worker_count: (untyped) -> Integer
|
|
364
399
|
def run_linear: (Array[Mutant], untyped, untyped, untyped?, untyped) -> void
|
|
365
400
|
def run_parallel: (Array[Mutant], untyped, untyped, untyped?, untyped) -> void
|
|
401
|
+
def pipe_stdin?: () -> bool
|
|
402
|
+
def start_stdin_watcher: () { () -> void } -> Thread
|
|
366
403
|
def process_mutant: (Mutant, untyped, untyped, untyped?, ?untyped) -> void
|
|
367
404
|
def prioritized_tests_for: (Mutant, untyped, untyped) -> Array[String]
|
|
368
405
|
def test_prioritizer: () -> TestPrioritizer
|
|
@@ -507,12 +544,14 @@ module Henitai
|
|
|
507
544
|
include UnparseHelper
|
|
508
545
|
|
|
509
546
|
SCHEMA_VERSION: String
|
|
547
|
+
DEFAULT_THRESHOLDS: Hash[Symbol, Integer]
|
|
510
548
|
|
|
511
549
|
attr_reader mutants: Array[Mutant]
|
|
512
550
|
attr_reader started_at: Time
|
|
513
551
|
attr_reader finished_at: Time
|
|
552
|
+
attr_reader thresholds: Hash[Symbol, Integer]
|
|
514
553
|
|
|
515
|
-
def initialize: (mutants: Array[Mutant], started_at: Time, finished_at: Time) -> void
|
|
554
|
+
def initialize: (mutants: Array[Mutant], started_at: Time, finished_at: Time, ?thresholds: Hash[Symbol, Integer]?) -> void
|
|
516
555
|
def killed: () -> Integer
|
|
517
556
|
def survived: () -> Integer
|
|
518
557
|
def equivalent: () -> Integer
|
|
@@ -527,6 +566,7 @@ module Henitai
|
|
|
527
566
|
|
|
528
567
|
def build_files_section: () -> Hash[Symbol, untyped]
|
|
529
568
|
def mutant_to_schema: (Mutant) -> Hash[Symbol, untyped]
|
|
569
|
+
def coverage_schema: (Mutant) -> Hash[Symbol, untyped]
|
|
530
570
|
def replacement_for: (Mutant) -> String
|
|
531
571
|
def location_for: (Mutant) -> Hash[Symbol, untyped]
|
|
532
572
|
def line_column: (Mutant, Symbol) -> Hash[Symbol, Integer]
|
|
@@ -566,19 +606,28 @@ module Henitai
|
|
|
566
606
|
|
|
567
607
|
def build_result: (Array[Mutant], Time, Time) -> Result
|
|
568
608
|
def persist_history: (Result, Time) -> void
|
|
569
|
-
def
|
|
609
|
+
def refresh_coverage_for_targeted_run: (Array[Mutant], Array[String]) -> Array[Mutant]
|
|
610
|
+
def bootstrap_coverage: (Array[String], ?Array[String]?) -> void
|
|
611
|
+
def bootstrap_mutants: (Array[String], Array[Subject]) -> Thread
|
|
612
|
+
def mutants_for: (Array[Subject], Array[String]) -> Array[Mutant]
|
|
613
|
+
def scoped_bootstrap_test_files: (Array[Subject]) -> Array[String]?
|
|
614
|
+
def targeted_run?: () -> bool
|
|
615
|
+
def retry_full_bootstrap?: (Array[Mutant]) -> bool
|
|
570
616
|
def with_reports_dir: () { () -> untyped } -> untyped
|
|
617
|
+
def result_thresholds: () -> Hash[Symbol, Integer]?
|
|
571
618
|
end
|
|
572
619
|
|
|
573
620
|
class CoverageBootstrapper
|
|
574
621
|
def initialize: (?static_filter: StaticFilter) -> void
|
|
575
|
-
def ensure!: (source_files: Array[String], config: Configuration, integration: Integration::Base) -> void
|
|
622
|
+
def ensure!: (source_files: Array[String], config: Configuration, integration: Integration::Base, ?test_files: Array[String]?) -> void
|
|
576
623
|
|
|
577
624
|
private
|
|
578
625
|
|
|
579
626
|
def static_filter: () -> StaticFilter
|
|
580
627
|
def coverage_available?: (Array[String], Configuration) -> bool
|
|
581
|
-
def
|
|
628
|
+
def coverage_fresh?: (Array[String], Configuration, Integration::Base, Array[String]?) -> bool
|
|
629
|
+
def coverage_report_path: (Configuration) -> String
|
|
630
|
+
def bootstrap_coverage: (Integration::Base, Configuration, ?Array[String]?) -> void
|
|
582
631
|
def source_file_paths: (Array[String]) -> Array[String]
|
|
583
632
|
end
|
|
584
633
|
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: henitai
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Martin Otten
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: exe
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-04-13 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: prism
|
|
@@ -88,15 +89,19 @@ files:
|
|
|
88
89
|
- exe/henitai
|
|
89
90
|
- lib/henitai.rb
|
|
90
91
|
- lib/henitai/arid_node_filter.rb
|
|
92
|
+
- lib/henitai/available_cpu_count.rb
|
|
91
93
|
- lib/henitai/cli.rb
|
|
92
94
|
- lib/henitai/configuration.rb
|
|
93
95
|
- lib/henitai/configuration_validator.rb
|
|
94
96
|
- lib/henitai/coverage_bootstrapper.rb
|
|
95
97
|
- lib/henitai/coverage_formatter.rb
|
|
98
|
+
- lib/henitai/coverage_report_reader.rb
|
|
99
|
+
- lib/henitai/eager_load.rb
|
|
96
100
|
- lib/henitai/equivalence_detector.rb
|
|
97
101
|
- lib/henitai/execution_engine.rb
|
|
98
102
|
- lib/henitai/git_diff_analyzer.rb
|
|
99
103
|
- lib/henitai/integration.rb
|
|
104
|
+
- lib/henitai/integration/rspec_process_runner.rb
|
|
100
105
|
- lib/henitai/minitest_simplecov.rb
|
|
101
106
|
- lib/henitai/mutant.rb
|
|
102
107
|
- lib/henitai/mutant/activator.rb
|
|
@@ -113,13 +118,19 @@ files:
|
|
|
113
118
|
- lib/henitai/operators/equality_operator.rb
|
|
114
119
|
- lib/henitai/operators/hash_literal.rb
|
|
115
120
|
- lib/henitai/operators/logical_operator.rb
|
|
121
|
+
- lib/henitai/operators/method_chain_unwrap.rb
|
|
116
122
|
- lib/henitai/operators/method_expression.rb
|
|
117
123
|
- lib/henitai/operators/pattern_match.rb
|
|
118
124
|
- lib/henitai/operators/range_literal.rb
|
|
125
|
+
- lib/henitai/operators/regex_mutator.rb
|
|
119
126
|
- lib/henitai/operators/return_value.rb
|
|
120
127
|
- lib/henitai/operators/safe_navigation.rb
|
|
121
128
|
- lib/henitai/operators/string_literal.rb
|
|
129
|
+
- lib/henitai/operators/unary_operator.rb
|
|
130
|
+
- lib/henitai/operators/update_operator.rb
|
|
131
|
+
- lib/henitai/parallel_execution_runner.rb
|
|
122
132
|
- lib/henitai/parser_current.rb
|
|
133
|
+
- lib/henitai/per_test_coverage_selector.rb
|
|
123
134
|
- lib/henitai/reporter.rb
|
|
124
135
|
- lib/henitai/result.rb
|
|
125
136
|
- lib/henitai/rspec_coverage_formatter.rb
|
|
@@ -149,6 +160,7 @@ metadata:
|
|
|
149
160
|
homepage_uri: https://github.com/martinotten/henitai
|
|
150
161
|
source_code_uri: https://github.com/martinotten/henitai/tree/v0.1.2
|
|
151
162
|
rubygems_mfa_required: 'true'
|
|
163
|
+
post_install_message:
|
|
152
164
|
rdoc_options: []
|
|
153
165
|
require_paths:
|
|
154
166
|
- lib
|
|
@@ -163,7 +175,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
163
175
|
- !ruby/object:Gem::Version
|
|
164
176
|
version: '0'
|
|
165
177
|
requirements: []
|
|
166
|
-
rubygems_version:
|
|
178
|
+
rubygems_version: 3.3.5
|
|
179
|
+
signing_key:
|
|
167
180
|
specification_version: 4
|
|
168
181
|
summary: Mutation testing for Ruby
|
|
169
182
|
test_files: []
|