henitai 0.1.10 → 0.2.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +94 -1
  3. data/README.md +33 -7
  4. data/assets/schema/henitai.schema.json +6 -0
  5. data/lib/henitai/cli/clean_command.rb +48 -0
  6. data/lib/henitai/cli/command_support.rb +51 -0
  7. data/lib/henitai/cli/init_command.rb +64 -0
  8. data/lib/henitai/cli/operator_command.rb +95 -0
  9. data/lib/henitai/cli/options.rb +120 -0
  10. data/lib/henitai/cli/run_command.rb +103 -0
  11. data/lib/henitai/cli.rb +17 -327
  12. data/lib/henitai/configuration.rb +26 -12
  13. data/lib/henitai/configuration_validator/rules.rb +143 -0
  14. data/lib/henitai/configuration_validator/scalars.rb +123 -0
  15. data/lib/henitai/configuration_validator.rb +12 -239
  16. data/lib/henitai/coverage_bootstrapper.rb +24 -24
  17. data/lib/henitai/eager_load.rb +36 -5
  18. data/lib/henitai/execution_engine.rb +6 -11
  19. data/lib/henitai/git_diff_analyzer.rb +34 -0
  20. data/lib/henitai/integration/base.rb +171 -0
  21. data/lib/henitai/integration/child_debug_support.rb +115 -0
  22. data/lib/henitai/integration/child_runtime_control.rb +50 -0
  23. data/lib/henitai/integration/coverage_suppression.rb +43 -0
  24. data/lib/henitai/integration/minitest.rb +133 -0
  25. data/lib/henitai/integration/mutant_run_support.rb +77 -0
  26. data/lib/henitai/integration/rspec_child_runner.rb +61 -0
  27. data/lib/henitai/integration/rspec_process_runner.rb +66 -13
  28. data/lib/henitai/integration/rspec_test_selection.rb +135 -0
  29. data/lib/henitai/integration/scenario_log_support.rb +116 -0
  30. data/lib/henitai/integration.rb +43 -519
  31. data/lib/henitai/mutant/activator.rb +13 -79
  32. data/lib/henitai/mutant/parameter_source.rb +98 -0
  33. data/lib/henitai/mutant.rb +14 -2
  34. data/lib/henitai/mutant_generator.rb +21 -2
  35. data/lib/henitai/mutant_history_store/sql.rb +72 -0
  36. data/lib/henitai/mutant_history_store.rb +12 -91
  37. data/lib/henitai/mutant_identity.rb +34 -0
  38. data/lib/henitai/parallel_execution_runner.rb +29 -11
  39. data/lib/henitai/per_test_coverage_collector.rb +3 -1
  40. data/lib/henitai/process_wakeup.rb +49 -0
  41. data/lib/henitai/process_worker_runner.rb +148 -0
  42. data/lib/henitai/reporter.rb +96 -11
  43. data/lib/henitai/result.rb +49 -16
  44. data/lib/henitai/runner.rb +96 -30
  45. data/lib/henitai/scenario_execution_result.rb +16 -3
  46. data/lib/henitai/slot_scheduler/draining.rb +140 -0
  47. data/lib/henitai/slot_scheduler/process_control.rb +43 -0
  48. data/lib/henitai/slot_scheduler.rb +214 -0
  49. data/lib/henitai/static_filter.rb +10 -3
  50. data/lib/henitai/survivor_activation_cache.rb +81 -0
  51. data/lib/henitai/survivor_loader.rb +140 -0
  52. data/lib/henitai/survivor_rerun_strategy.rb +195 -0
  53. data/lib/henitai/survivor_selector.rb +36 -0
  54. data/lib/henitai/survivor_test_filter.rb +72 -0
  55. data/lib/henitai/unparse_helper.rb +5 -2
  56. data/lib/henitai/version.rb +1 -1
  57. data/lib/henitai.rb +10 -0
  58. data/sig/configuration_validator.rbs +46 -22
  59. data/sig/henitai.rbs +329 -53
  60. metadata +46 -2
data/sig/henitai.rbs CHANGED
@@ -73,6 +73,71 @@ module Henitai
73
73
  module Operators
74
74
  end
75
75
 
76
+ module Integration::ChildDebugSupport
77
+ private
78
+
79
+ def debug_child_puts: (String) -> void
80
+ def debug_child?: () -> bool
81
+ def debug_child_rspec_trace: (
82
+ test_files: Array[String],
83
+ rspec_options: Array[String],
84
+ rspec_argv: Array[String]
85
+ ) -> void
86
+ def debug_child_rspec_exit: (untyped) -> void
87
+ def debug_child_example_count: (String) -> void
88
+ def debug_child_activation_start: (String) -> void
89
+ def debug_child_activation_end: (untyped, test_files: Array[String]) -> void
90
+ def debug_child_mutant_meta: (Mutant) -> void
91
+ def debug_child_activation_check: () -> void
92
+ def loaded_feature_map: (Array[String]) -> Array[[String, bool]]
93
+ def loaded_feature?: (String) -> bool
94
+ def rspec_world_example_count: () -> Integer?
95
+ def pause: (Float) -> void
96
+ end
97
+
98
+ module Integration::ChildRuntimeControl
99
+ private
100
+
101
+ def suppress_simplecov!: () -> void
102
+ def suppress_coverage!: () -> void
103
+ def debug_child_timeout_dump: (Integer) -> void
104
+ def install_debug_timeout_trap: () -> void
105
+ def debug_child_thread_dump: (String) -> void
106
+ end
107
+
108
+ module Integration::RspecChildRunner
109
+ private
110
+
111
+ def run_rspec_runner: (Array[String]) -> untyped
112
+ def build_rspec_runner: () -> untyped
113
+ def configure_rspec_runner: (untyped) -> void
114
+ def load_rspec_spec_files: (Array[String]) -> void
115
+ def run_rspec_specs: (untyped) -> untyped
116
+ end
117
+
118
+ module Integration::RspecTestSelection
119
+ REQUIRE_DIRECTIVE_PATTERN: Regexp
120
+
121
+ def select_tests: (Subject) -> Array[String]
122
+
123
+ private
124
+
125
+ def spec_files: () -> Array[String]
126
+ def fallback_spec_files: (Subject) -> Array[String]
127
+ def excluded_spec_files: () -> Array[String]
128
+ def rspec_exclude_patterns: () -> Array[String]
129
+ def rspec_config_lines: () -> Array[String]
130
+ def rspec_config_path: () -> String
131
+ def selection_patterns: (Subject) -> Array[String]
132
+ def requires_source_file?: (String, String) -> bool
133
+ def requires_source_file_transitively?: (String, String, ?Array[String]) -> bool
134
+ def required_files: (String) -> Array[String]
135
+ def resolve_required_file: (String, String, String) -> String?
136
+ def relative_candidates: (String, String) -> Array[String]
137
+ def require_candidates: (String, String) -> Array[String]
138
+ def expand_candidates: (String, String) -> Array[String]
139
+ end
140
+
76
141
  class Configuration
77
142
  DEFAULT_TIMEOUT: Float
78
143
  DEFAULT_OPERATORS: Symbol
@@ -86,6 +151,7 @@ module Henitai
86
151
 
87
152
  attr_reader integration: untyped
88
153
  attr_reader includes: Array[String]
154
+ attr_reader excludes: Array[String]
89
155
  attr_reader operators: Symbol
90
156
  attr_reader timeout: Float
91
157
  attr_reader ignore_patterns: Array[untyped]
@@ -106,11 +172,14 @@ module Henitai
106
172
  private
107
173
 
108
174
  def load_raw_configuration: (String) -> Hash[Symbol, untyped]
175
+ def detect_integration: () -> String
109
176
  def apply_defaults: (Hash[Symbol, untyped]) -> void
110
177
  def apply_general_defaults: (Hash[Symbol, untyped]) -> void
111
178
  def apply_mutation_defaults: (Hash[Symbol, untyped]) -> void
112
179
  def apply_analysis_defaults: (Hash[Symbol, untyped]) -> void
113
180
  def merge_defaults: (Hash[Symbol, untyped], Hash[Symbol, untyped]?) -> Hash[Symbol, untyped]
181
+ def resolve_integration_default: (untyped) -> untyped
182
+ def default_dashboard: (Hash[Symbol, untyped]?) -> Hash[Symbol, untyped]
114
183
  def symbolize_keys: (untyped) -> untyped
115
184
  end
116
185
 
@@ -171,8 +240,11 @@ module Henitai
171
240
  attr_accessor duration: Float?
172
241
  attr_accessor covered_by: Array[String]?
173
242
  attr_accessor tests_completed: Integer?
243
+ attr_reader precomputed_stable_id: String?
244
+ attr_reader precomputed_activation_source: String?
174
245
 
175
- def initialize: (subject: Subject, operator: String, nodes: Hash[Symbol, untyped], description: String, location: Hash[Symbol, untyped]) -> void
246
+ def initialize: (subject: Subject, operator: String, nodes: Hash[Symbol, untyped], description: String, location: Hash[Symbol, untyped], ?precomputed_stable_id: String?, ?precomputed_activation_source: String?) -> void
247
+ def stable_id: () -> String
176
248
  def killed?: () -> bool
177
249
  def survived?: () -> bool
178
250
  def pending?: () -> bool
@@ -256,9 +328,13 @@ module Henitai
256
328
  def self.for: (String) -> untyped
257
329
 
258
330
  class Base
331
+ include ChildDebugSupport
332
+ include ChildRuntimeControl
333
+
259
334
  def select_tests: (Subject) -> Array[String]
260
335
  def test_files: () -> Array[String]
261
336
  def run_mutant: (mutant: Mutant, test_files: Array[String], timeout: Float) -> ScenarioExecutionResult
337
+ def spawn_mutant: (mutant: Mutant, test_files: Array[String]) -> ChildHandle
262
338
  def run_suite: (Array[String], ?timeout: Float) -> ScenarioExecutionResult
263
339
  def per_test_coverage_supported?: () -> bool
264
340
  def wait_with_timeout: (Integer, Float) -> untyped
@@ -268,14 +344,41 @@ module Henitai
268
344
  private
269
345
 
270
346
  def pause: (Float) -> void
347
+ def wait_nonblocking: (Integer) -> untyped
271
348
  def handle_timeout: (Integer) -> Symbol
272
349
  def cleanup_child_process: (Integer) -> void
273
- def rspec_options: () -> Array[String]
350
+ def suppress_simplecov!: () -> void
351
+ def suppress_coverage!: () -> void
352
+ def debug_child?: () -> bool
353
+ def debug_child_puts: (String) -> void
354
+ def debug_child_rspec_trace: (test_files: Array[String], rspec_options: Array[String], rspec_argv: Array[String]) -> void
355
+ def debug_child_rspec_exit: (untyped status) -> void
356
+ def debug_child_activation_start: (String mutant_id) -> void
357
+ def debug_child_activation_end: (untyped activation_result, test_files: Array[String]) -> void
358
+ def debug_child_mutant_meta: (Mutant) -> void
359
+ def debug_child_activation_check: () -> void
360
+ def debug_child_example_count: (String) -> void
361
+ def loaded_feature_map: (Array[String]) -> Array[[String, bool]]
362
+ def loaded_feature?: (String) -> bool
363
+ def rspec_world_example_count: () -> Integer?
364
+ def with_non_interactive_stdin: () { () -> untyped } -> untyped
274
365
  def subprocess_env: () -> Hash[String, String]
275
366
  def scenario_log_support: () -> ScenarioLogSupport
276
367
  def with_subprocess_env: () { () -> untyped } -> untyped
277
368
  def restore_subprocess_env: (Hash[String, String?]) -> void
278
- def spawn_suite_process: (Array[String], Hash[Symbol, String]) -> Integer
369
+ end
370
+
371
+ module MutantRunSupport
372
+ def spawn_mutant: (mutant: Mutant, test_files: Array[String]) -> ChildHandle
373
+ def run_mutant: (mutant: Mutant, test_files: Array[String], timeout: Float) -> ScenarioExecutionResult
374
+ def scenario_log_paths: (String) -> Hash[Symbol, String]
375
+ def build_result: (untyped, Hash[Symbol, String]) -> ScenarioExecutionResult
376
+ def run_in_child: (mutant: Mutant, test_files: Array[String], log_paths: Hash[Symbol, String]) -> Integer
377
+ def mutant_log_name: (Mutant) -> String
378
+
379
+ private
380
+
381
+ def run_child_activation_and_tests: (mutant: Mutant, test_files: Array[String], log_paths: Hash[Symbol, String]) -> Integer
279
382
  end
280
383
 
281
384
  class ScenarioLogSupport
@@ -300,66 +403,81 @@ module Henitai
300
403
  def stderr_stream: () -> IO
301
404
  end
302
405
 
406
+ module SchedulerDiagnostics
407
+ def self.enabled?: () -> bool
408
+ def self.child_started: (Integer?) -> void
409
+ def self.child_ended: (Integer?) -> void
410
+ def self.summary: () -> Hash[Symbol, untyped]
411
+ def self.reset!: () -> void
412
+ end
413
+
414
+ class ChildHandle
415
+ attr_accessor pid: Integer?
416
+ attr_accessor log_paths: Hash[Symbol, String]
417
+
418
+ def initialize: (pid: Integer?, log_paths: Hash[Symbol, String]) -> void
419
+ end
420
+
303
421
  class RspecProcessRunner
304
- def run_mutant: (Rspec, mutant: Mutant, test_files: Array[String], timeout: Float) -> ScenarioExecutionResult
305
- def run_suite: (Rspec, Array[String], timeout: Float) -> ScenarioExecutionResult
422
+ def run_mutant: (Base, mutant: Mutant, test_files: Array[String], timeout: Float) -> ScenarioExecutionResult
423
+ def run_suite: (Base, Array[String], timeout: Float) -> ScenarioExecutionResult
424
+ def spawn_mutant: (Base, mutant: Mutant, test_files: Array[String], log_paths: Hash[Symbol, String]) -> ChildHandle
306
425
  end
307
426
 
308
427
  class Rspec < Base
309
- REQUIRE_DIRECTIVE_PATTERN: Regexp
428
+ include MutantRunSupport
429
+ include RspecChildRunner
430
+ include RspecTestSelection
431
+
310
432
  DEFAULT_SUITE_TIMEOUT: Float
311
433
 
312
- def select_tests: (Subject) -> Array[String]
313
434
  def test_files: () -> Array[String]
314
- def run_mutant: (mutant: Mutant, test_files: Array[String], timeout: Float) -> ScenarioExecutionResult
315
435
  def run_suite: (Array[String], ?timeout: Float) -> ScenarioExecutionResult
316
436
  def per_test_coverage_supported?: () -> bool
437
+ def suite_command: (Array[String]) -> Array[String]
438
+ def rspec_suite_runner_script: () -> String
439
+ def spawn_suite_process: (Array[String], Hash[Symbol, String]) -> Integer
317
440
 
318
441
  private
319
442
 
320
- def run_in_child: (mutant: Mutant, test_files: Array[String], log_paths: Hash[Symbol, String]) -> Integer
321
- def suite_command: (Array[String]) -> Array[String]
322
- def build_result: (untyped, Hash[Symbol, String]) -> ScenarioExecutionResult
323
- def scenario_status: (untyped) -> Symbol
324
- def exit_status_for: (untyped) -> Integer?
325
- def read_log_file: (String) -> String
326
- def write_combined_log: (String, String, String) -> void
327
- def combined_log: (String, String) -> String
328
- def scenario_log_paths: (String) -> Hash[Symbol, String]
329
443
  def run_tests: (Array[String]) -> Integer
330
- def with_subprocess_env: () { () -> untyped } -> untyped
331
- def spec_files: () -> Array[String]
332
- def fallback_spec_files: (Subject) -> Array[String]
333
- def excluded_spec_files: () -> Array[String]
334
- def rspec_exclude_patterns: () -> Array[String]
335
- def rspec_config_lines: () -> Array[String]
336
- def rspec_config_path: () -> String
337
- def selection_patterns: (Subject) -> Array[String]
338
- def requires_source_file?: (String, String) -> bool
339
- def requires_source_file_transitively?: (String, String, ?Array[String]) -> bool
340
- def required_files: (String) -> Array[String]
341
- def resolve_required_file: (String, String, String) -> String?
342
- def relative_candidates: (String, String) -> Array[String]
343
- def require_candidates: (String, String) -> Array[String]
344
- def expand_candidates: (String, String) -> Array[String]
444
+ end
445
+
446
+ module CoverageRuntimeSuppressors
447
+ def self.suppress_simplecov!: () -> void
448
+ def self.suppress_coverage!: () -> void
345
449
  end
346
450
 
347
451
  module SimpleCovStartSuppressor
348
452
  def start: (*untyped) -> nil
349
453
  end
350
454
 
351
- class Minitest < Rspec
455
+ module CoverageStartSuppressor
456
+ def start: (*untyped) -> nil
457
+ end
458
+
459
+ class Minitest < Base
460
+ include MutantRunSupport
461
+ include RspecTestSelection
462
+
463
+ DEFAULT_SUITE_TIMEOUT: Float
464
+
465
+ def test_files: () -> Array[String]
466
+ def per_test_coverage_supported?: () -> bool
352
467
  def run_mutant: (mutant: Mutant, test_files: Array[String], timeout: Float) -> ScenarioExecutionResult
468
+ def spawn_mutant: (mutant: Mutant, test_files: Array[String]) -> ChildHandle
469
+ def run_in_child: (mutant: Mutant, test_files: Array[String], log_paths: Hash[Symbol, String]) -> Integer
353
470
  def run_suite: (Array[String], ?timeout: Float) -> ScenarioExecutionResult
354
471
 
355
472
  private
356
473
 
357
- def run_in_child: (mutant: Mutant, test_files: Array[String], log_paths: Hash[Symbol, String]) -> Integer
358
474
  def run_tests: (Array[String]) -> Integer
359
475
  def preload_environment: () -> void
360
476
  def setup_load_path: () -> void
477
+ def suppress_minitest_autorun!: () -> nil
361
478
  def suppress_simplecov!: () -> void
362
479
  def subprocess_env: () -> Hash[String, String]
480
+ def spawn_suite_process: (Array[String], Hash[Symbol, String]) -> Integer
363
481
  def cleanup_suite_process: (Integer?, untyped) -> void
364
482
  def spec_files: () -> Array[String]
365
483
  end
@@ -372,16 +490,31 @@ module Henitai
372
490
 
373
491
  class GitDiffAnalyzer
374
492
  def changed_files: (from: String, to: String, ?dir: String) -> Array[String]
493
+ def working_tree_changed_files: (?dir: String) -> Array[String]
494
+ def head_sha: (?dir: String) -> String?
375
495
  end
376
496
 
377
497
  class MutantGenerator
378
498
  def generate: (Array[Subject], Array[untyped], ?config: untyped) -> Array[Mutant]
379
499
  end
380
500
 
501
+ module MutantIdentity
502
+ def self.stable_id: (Mutant) -> String
503
+ end
504
+
381
505
  class MutantHistoryStore
506
+ attr_reader path: String
507
+
382
508
  def initialize: (path: String) -> void
383
- def record: (Result, version: String, ?recorded_at: Time) -> void
509
+ def record: (untyped, version: String, ?recorded_at: Time) -> void
384
510
  def trend_report: () -> Hash[Symbol, untyped]
511
+
512
+ module Sql
513
+ RUNS_TABLE: String
514
+ MUTANTS_TABLE: String
515
+ INSERT_RUN: String
516
+ UPSERT_MUTANT: String
517
+ end
385
518
  end
386
519
 
387
520
  class EquivalenceDetector
@@ -420,6 +553,44 @@ module Henitai
420
553
  def run: (Array[Mutant], untyped, untyped, untyped, ?Hash[Symbol, untyped]) -> void
421
554
  end
422
555
 
556
+ class ProcessWorkerRunner
557
+ attr_reader worker_count: Integer
558
+ attr_reader runtime: untyped
559
+ attr_reader wakeup: untyped
560
+
561
+ def initialize: (worker_count: Integer, ?runtime: untyped, ?wakeup: untyped) -> void
562
+ def flaky_retry_count: () -> Integer
563
+ def shutdown_requested?: () -> bool
564
+ def request_shutdown: () -> void
565
+ def run: (Array[Mutant], untyped, untyped, untyped?, ?Hash[Symbol, untyped]) -> Array[ScenarioExecutionResult]
566
+ end
567
+
568
+ class SlotScheduler
569
+ PROCESS_DRAIN_WINDOW: Float
570
+
571
+ Slot: untyped
572
+
573
+ attr_reader flaky_retry_count: Integer
574
+ attr_reader results: Array[ScenarioExecutionResult]
575
+
576
+ def initialize: (
577
+ integration: untyped,
578
+ config: untyped,
579
+ progress_reporter: untyped?,
580
+ options: Hash[Symbol, untyped],
581
+ host: untyped
582
+ ) -> void
583
+ def enqueue: (Array[Mutant]) -> Array[Mutant]
584
+ def done?: () -> bool
585
+ def fill_idle_slots: () -> void
586
+ def reap_all_completed_children: () -> void
587
+ def next_event_timeout: () -> Float?
588
+ def check_timeouts: () -> void
589
+ def draining_slots?: () -> bool
590
+ def drain_draining_slots: () -> void
591
+ def interrupt_active_slots: () -> void
592
+ end
593
+
423
594
  class StaticFilter
424
595
  def initialize: (?coverage_report_reader: CoverageReportReader) -> void
425
596
  def apply: (Array[Mutant], untyped) -> Array[Mutant]
@@ -441,9 +612,7 @@ module Henitai
441
612
  def parallel_execution?: (untyped, Array[Mutant]) -> bool
442
613
  def worker_count: (untyped) -> Integer
443
614
  def run_linear: (Array[Mutant], untyped, untyped, untyped?, untyped) -> void
444
- def run_parallel: (Array[Mutant], untyped, untyped, untyped?, untyped) -> void
445
- def pipe_stdin?: () -> bool
446
- def start_stdin_watcher: () { () -> void } -> Thread
615
+ def run_parallel: (Array[Mutant], untyped, untyped, untyped?) -> void
447
616
  def process_mutant: (Mutant, untyped, untyped, untyped?, ?untyped) -> void
448
617
  def prioritized_tests_for: (Mutant, untyped, untyped) -> Array[String]
449
618
  def test_prioritizer: () -> TestPrioritizer
@@ -454,9 +623,8 @@ module Henitai
454
623
  end
455
624
 
456
625
  class Mutant::Activator
457
- SERIALIZER_METHODS: Hash[Symbol, Symbol]
458
-
459
626
  def self.activate!: (untyped) -> Symbol?
627
+ def self.activation_source_for: (Mutant) -> String?
460
628
  def initialize: () -> void
461
629
  def activate!: (untyped) -> Symbol?
462
630
 
@@ -468,6 +636,22 @@ module Henitai
468
636
  def method_source: (Mutant) -> String
469
637
  def body_source: (Mutant) -> String
470
638
  def parameter_source: (Mutant) -> String
639
+ def replace_node: (untyped, untyped, untyped) -> untyped
640
+ def same_node?: (untyped, untyped) -> bool
641
+ def replace_child: (untyped, untyped, untyped) -> untyped
642
+ def method_body: (untyped) -> untyped
643
+ def source_file_from_ast: (Subject) -> String?
644
+ def node_location_signature: (untyped) -> Array[untyped]?
645
+ def compile_safe_unparse: (untyped) -> String
646
+ end
647
+
648
+ class Mutant::ParameterSource
649
+ SERIALIZER_METHODS: Hash[Symbol, Symbol]
650
+
651
+ def build: (untyped) -> String
652
+
653
+ private
654
+
471
655
  def method_arguments: (untyped) -> untyped
472
656
  def parameter_fragment: (untyped) -> String?
473
657
  def argument_parameter_fragment: (untyped) -> String
@@ -479,26 +663,21 @@ module Henitai
479
663
  def block_parameter_fragment: (untyped) -> String
480
664
  def forward_parameter_fragment: (untyped) -> String
481
665
  def prefixed_parameter: (untyped, String) -> String
482
- def replace_node: (untyped, untyped, untyped) -> untyped
483
- def same_node?: (untyped, untyped) -> bool
484
- def replace_child: (untyped, untyped, untyped) -> untyped
485
- def method_body: (untyped) -> untyped
486
- def source_file_from_ast: (Subject) -> String?
487
- def node_location_signature: (untyped) -> Array[untyped]?
488
666
  def compile_safe_unparse: (untyped) -> String
489
667
  end
490
668
 
491
669
  module Reporter
492
- def self.run_all: (names: Array[String], result: Result, config: Configuration) -> void
670
+ def self.run_all: (names: Array[String], result: Result, config: Configuration, ?history_store: MutantHistoryStore?) -> void
493
671
  def self.reporter_class: (String) -> untyped
494
672
 
495
673
  class Base
496
- def initialize: (config: Configuration) -> void
674
+ def initialize: (config: Configuration, ?history_store: MutantHistoryStore?) -> void
497
675
  def report: (Result) -> void
498
676
 
499
677
  private
500
678
 
501
679
  def config: () -> Configuration
680
+ def history_store: () -> MutantHistoryStore?
502
681
  end
503
682
 
504
683
  class Terminal < Base
@@ -512,7 +691,10 @@ module Henitai
512
691
  private
513
692
 
514
693
  def report_lines: (Result) -> Array[String]
515
- def summary_lines: (Result) -> Array[String]
694
+ def summary_lines: (untyped) -> Array[String]
695
+ def full_summary_lines: (untyped) -> Array[String]
696
+ def partial_summary_lines: (untyped) -> Array[String]
697
+ def append_survivor_stats: (Array[String], untyped) -> void
516
698
  def survived_detail_lines: (Result) -> Array[String]
517
699
  def survived_mutant_lines: (Mutant) -> Array[String]
518
700
  def survived_mutant_header: (Mutant) -> String
@@ -536,9 +718,15 @@ module Henitai
536
718
 
537
719
  private
538
720
 
539
- def report_path: () -> String
721
+ def write_canonical: (Hash[Symbol, untyped]) -> void
722
+ def write_session_snapshot: (Hash[Symbol, untyped]) -> void
723
+ def write_activation_recipes: (untyped) -> void
724
+ def survived_mutants_for: (untyped) -> Array[Mutant]
725
+ def session_snapshot_path: (String) -> String
726
+ def session_recipe_path: (String) -> String
727
+ def canonical_path: () -> String
540
728
  def write_history_report: () -> void
541
- def history_store_path: () -> String
729
+ def default_history_store: () -> MutantHistoryStore
542
730
  def history_report_path: () -> String
543
731
  end
544
732
 
@@ -595,8 +783,12 @@ module Henitai
595
783
  attr_reader started_at: Time
596
784
  attr_reader finished_at: Time
597
785
  attr_reader thresholds: Hash[Symbol, Integer]
786
+ attr_reader survivor_stats: Hash[Symbol, untyped]?
787
+ attr_reader session_id: String
788
+ attr_reader git_sha: String?
598
789
 
599
- def initialize: (mutants: Array[Mutant], started_at: Time, finished_at: Time, ?thresholds: Hash[Symbol, Integer]?) -> void
790
+ def initialize: (mutants: Array[Mutant], started_at: Time, finished_at: Time, ?thresholds: Hash[Symbol, Integer]?, ?partial_rerun: bool, ?survivor_stats: Hash[Symbol, untyped]?, ?session_id: String, ?git_sha: String?, ?source_provider: ^(String) -> String) -> void
791
+ def partial_rerun?: () -> bool
600
792
  def killed: () -> Integer
601
793
  def survived: () -> Integer
602
794
  def equivalent: () -> Integer
@@ -609,6 +801,8 @@ module Henitai
609
801
 
610
802
  private
611
803
 
804
+ def base_schema: () -> Hash[Symbol, untyped]
805
+ def unmatched_survivor_ids: () -> Array[String]
612
806
  def build_files_section: () -> Hash[Symbol, untyped]
613
807
  def mutant_to_schema: (Mutant) -> Hash[Symbol, untyped]
614
808
  def coverage_schema: (Mutant) -> Hash[Symbol, untyped]
@@ -620,11 +814,56 @@ module Henitai
620
814
  def stryker_status: (Symbol) -> String
621
815
  end
622
816
 
817
+ class SurvivorLoader
818
+ FileNotFoundError: singleton(StandardError)
819
+ InvalidReportError: singleton(StandardError)
820
+ ScopeMismatchError: singleton(StandardError)
821
+
822
+ class Report
823
+ attr_reader survivor_ids: Array[String]
824
+ attr_reader coverage_map: Hash[String, Array[String]]
825
+ attr_reader git_sha: String?
826
+
827
+ def initialize: (survivor_ids: Array[String], coverage_map: Hash[String, Array[String]], git_sha: String?) -> void
828
+ end
829
+
830
+ def initialize: (String, ?include_paths: Array[String]) -> void
831
+ def load: () -> Report
832
+ end
833
+
834
+ class SurvivorTestFilter
835
+ def initialize: (
836
+ coverage_map: Hash[String, Array[String]],
837
+ git_sha: String?,
838
+ ?dirty_source_files: bool,
839
+ ?worktree_changed_files: Array[String],
840
+ ?diff_analyzer: GitDiffAnalyzer
841
+ ) -> void
842
+ def apply: (Array[Mutant]) -> Hash[Symbol, Array[Mutant]]
843
+ end
844
+
845
+ class SurvivorSelector
846
+ DRIFT_THRESHOLD: Float
847
+
848
+ def initialize: (survivor_ids: Array[String]) -> void
849
+ def select: (Array[Mutant]) -> Array[Mutant]
850
+ def unmatched_ids: () -> Array[String]
851
+ def drift_warning?: () -> bool
852
+ end
853
+
854
+ class SurvivorActivationCache
855
+ FILENAME: String
856
+
857
+ def self.compute: (Array[Mutant]) -> Hash[String, Hash[String, untyped]]
858
+ def self.load: (String) -> Hash[String, Hash[String, untyped]]?
859
+ def self.write: (String, Hash[String, Hash[String, untyped]]) -> void
860
+ end
861
+
623
862
  class Runner
624
863
  attr_reader config: Configuration
625
864
  attr_reader result: untyped
626
865
 
627
- def initialize: (?config: Configuration, ?subjects: Array[Subject], ?since: String) -> void
866
+ def initialize: (?config: Configuration, ?subjects: Array[Subject], ?since: String, ?survivors_from: String?) -> void
628
867
  def run: () -> Result
629
868
  def resolve_subjects: (?Array[String]) -> untyped
630
869
  def generate_mutants: (untyped) -> untyped
@@ -643,6 +882,10 @@ module Henitai
643
882
  def history_store: () -> untyped
644
883
  def history_store_path: () -> String
645
884
  def source_files: () -> Array[String]
885
+ def included_source_files: () -> Array[String]
886
+ def reject_excluded: (Array[String]) -> Array[String]
887
+ def excluded_source_files: () -> Array[String]
888
+ def filter_changed: (Array[String]) -> Array[String]
646
889
  def pattern_subjects: () -> Array[Subject]
647
890
  def unique_subjects: (Array[Subject]) -> Array[Subject]
648
891
  def normalize_path: (String) -> String
@@ -650,12 +893,45 @@ module Henitai
650
893
  private
651
894
 
652
895
  def build_result: (Array[Mutant], Time, Time) -> Result
896
+ def source_provider: () -> ^(String) -> String
653
897
  def persist_history: (Result, Time) -> void
654
898
  def bootstrap_coverage: (Array[String], ?Array[String]?) -> void
655
899
  def bootstrap_mutants: (Array[String]) -> Thread
656
900
  def mutants_for: (Array[Subject], Array[String]) -> Array[Mutant]
657
901
  def with_reports_dir: () { () -> untyped } -> untyped
658
902
  def result_thresholds: () -> Hash[Symbol, Integer]?
903
+ def survivor_rerun?: () -> bool
904
+ def survivor_strategy: () -> SurvivorRerunStrategy
905
+ def safe_head_sha: () -> String?
906
+ end
907
+
908
+ class SurvivorRerunStrategy
909
+ attr_reader survivor_stats: Hash[Symbol, untyped]?
910
+
911
+ def initialize: (survivors_from: String?, config: Configuration, git_diff_analyzer: untyped) -> void
912
+ def active?: () -> bool
913
+ def try_recipe_run: () -> Array[Mutant]?
914
+ def apply_selection: (Array[Mutant]) -> Array[Mutant]
915
+
916
+ private
917
+
918
+ def load_survivor_report: () -> SurvivorLoader::Report
919
+ def run_from_recipes: (SurvivorLoader::Report, Array[String]?) -> Array[Mutant]?
920
+ def recipe_fast_path_safe?: (SurvivorLoader::Report, Array[String]?) -> bool
921
+ def recipe_selector_and_stubs: (Array[String], Hash[String, Hash[String, untyped]]) -> [SurvivorSelector, Array[Mutant]]
922
+ def load_activation_recipes: (Array[String]) -> Hash[String, Hash[String, untyped]]?
923
+ def build_stub_mutant: (String, Hash[String, untyped]) -> Mutant
924
+ def stub_subject_from_recipe: (Hash[String, untyped]) -> Subject
925
+ def recipe_location: (Hash[String, untyped]?) -> Hash[Symbol, untyped]
926
+ def finalize_survivor_split: (SurvivorSelector, Array[Mutant], Hash[Symbol, Array[Mutant]]) -> Array[Mutant]
927
+ def dirty_worktree_changed_files: () -> Array[String]?
928
+ def dirty_source_files?: (Array[String]?, ?git_sha: String?) -> bool
929
+ def committed_changed_files: (String?) -> Array[String]
930
+ def in_include_root?: (String, Array[String]) -> bool
931
+ def normalize_path: (String) -> String
932
+ def warn_survivor_drift: (SurvivorSelector) -> void
933
+ def build_survivor_stats: (SurvivorSelector, Array[Mutant], Hash[Symbol, Array[Mutant]]) -> Hash[Symbol, untyped]
934
+ def test_filter: (SurvivorLoader::Report, ?dirty_source_files: bool) -> SurvivorTestFilter
659
935
  end
660
936
 
661
937
  class CoverageBootstrapper