henitai 0.5.3 → 0.6.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.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +222 -1
  3. data/README.md +100 -13
  4. data/assets/schema/henitai.schema.json +20 -0
  5. data/lib/henitai/arid_node_filter.rb +4 -19
  6. data/lib/henitai/bootstrap_error_message.rb +20 -0
  7. data/lib/henitai/canonical_report_merger.rb +23 -2
  8. data/lib/henitai/cli/run_command.rb +25 -7
  9. data/lib/henitai/cli/run_options.rb +1 -1
  10. data/lib/henitai/cli.rb +4 -1
  11. data/lib/henitai/configuration.rb +4 -1
  12. data/lib/henitai/configuration_validator/rules.rb +8 -0
  13. data/lib/henitai/configuration_validator/scalars.rb +9 -0
  14. data/lib/henitai/configuration_validator.rb +2 -1
  15. data/lib/henitai/constant_path.rb +48 -0
  16. data/lib/henitai/control_run.rb +73 -0
  17. data/lib/henitai/coverage_bootstrapper.rb +36 -10
  18. data/lib/henitai/coverage_formatter.rb +26 -3
  19. data/lib/henitai/coverage_report_reader.rb +21 -0
  20. data/lib/henitai/equivalence_detector/operand_predicates.rb +16 -0
  21. data/lib/henitai/equivalence_detector.rb +46 -38
  22. data/lib/henitai/example_summary.rb +24 -0
  23. data/lib/henitai/execution_engine/fork_server_scope.rb +57 -0
  24. data/lib/henitai/execution_engine.rb +75 -60
  25. data/lib/henitai/fidelity_check.rb +173 -0
  26. data/lib/henitai/flaky_detection_baseline.rb +61 -0
  27. data/lib/henitai/flaky_mutant_retrier.rb +43 -0
  28. data/lib/henitai/flaky_retry_decision.rb +23 -0
  29. data/lib/henitai/flaky_test_registry.rb +63 -0
  30. data/lib/henitai/fork_server/client.rb +231 -0
  31. data/lib/henitai/fork_server/group_killer.rb +48 -0
  32. data/lib/henitai/fork_server/group_terminator.rb +47 -0
  33. data/lib/henitai/fork_server/launcher.rb +38 -0
  34. data/lib/henitai/fork_server/mutant_runner.rb +141 -0
  35. data/lib/henitai/fork_server/protocol.rb +73 -0
  36. data/lib/henitai/fork_server/reaper.rb +24 -0
  37. data/lib/henitai/fork_server/runtime.rb +109 -0
  38. data/lib/henitai/fork_server/server.rb +108 -0
  39. data/lib/henitai/fork_server/server_process.rb +73 -0
  40. data/lib/henitai/fork_server/status.rb +52 -0
  41. data/lib/henitai/fork_server.rb +43 -0
  42. data/lib/henitai/generated_artifacts.rb +3 -0
  43. data/lib/henitai/git_diff_analyzer.rb +28 -11
  44. data/lib/henitai/incremental_filter.rb +20 -10
  45. data/lib/henitai/integration/base.rb +72 -5
  46. data/lib/henitai/integration/capped_log_sink.rb +34 -0
  47. data/lib/henitai/integration/child_bootstrap.rb +7 -0
  48. data/lib/henitai/integration/child_report_store.rb +36 -0
  49. data/lib/henitai/integration/minitest.rb +7 -5
  50. data/lib/henitai/integration/minitest_autorun.rb +20 -0
  51. data/lib/henitai/integration/minitest_outcome_reporter.rb +28 -0
  52. data/lib/henitai/integration/minitest_preload.rb +30 -0
  53. data/lib/henitai/integration/minitest_runnable_filter.rb +61 -0
  54. data/lib/henitai/integration/minitest_test_runner.rb +32 -15
  55. data/lib/henitai/integration/mutant_run_support.rb +73 -13
  56. data/lib/henitai/integration/rspec_child_runner.rb +44 -9
  57. data/lib/henitai/integration/rspec_preload.rb +35 -0
  58. data/lib/henitai/integration/rspec_process_runner.rb +4 -1
  59. data/lib/henitai/integration/scenario_log_support.rb +31 -18
  60. data/lib/henitai/integration.rb +16 -3
  61. data/lib/henitai/minitest_coverage_reporter.rb +22 -6
  62. data/lib/henitai/minitest_result_file.rb +62 -0
  63. data/lib/henitai/mutant/activation.rb +32 -0
  64. data/lib/henitai/mutant/activator.rb +75 -55
  65. data/lib/henitai/mutant/def_injection.rb +136 -0
  66. data/lib/henitai/mutant/lexical_scope_check.rb +120 -0
  67. data/lib/henitai/mutant/lexical_target.rb +105 -0
  68. data/lib/henitai/mutant/replacement.rb +52 -0
  69. data/lib/henitai/mutant.rb +27 -8
  70. data/lib/henitai/mutant_generator.rb +62 -18
  71. data/lib/henitai/mutant_history_store/verdict_cache.rb +12 -11
  72. data/lib/henitai/mutant_history_store.rb +14 -4
  73. data/lib/henitai/mutant_identity.rb +5 -1
  74. data/lib/henitai/mutant_verdict.rb +71 -0
  75. data/lib/henitai/operators/array_declaration.rb +4 -0
  76. data/lib/henitai/operators/assignment_expression.rb +2 -0
  77. data/lib/henitai/operators/conditional_expression.rb +21 -1
  78. data/lib/henitai/operators/hash_literal.rb +7 -4
  79. data/lib/henitai/operators/method_expression.rb +14 -3
  80. data/lib/henitai/operators/regex_metacharacters.rb +89 -0
  81. data/lib/henitai/operators/regex_mutator.rb +23 -28
  82. data/lib/henitai/operators/return_value.rb +1 -1
  83. data/lib/henitai/operators.rb +1 -0
  84. data/lib/henitai/per_test_coverage.rb +11 -7
  85. data/lib/henitai/per_test_coverage_collector.rb +30 -31
  86. data/lib/henitai/per_test_coverage_delta.rb +60 -0
  87. data/lib/henitai/per_test_coverage_selector.rb +26 -13
  88. data/lib/henitai/process_wakeup.rb +8 -3
  89. data/lib/henitai/process_worker_runner.rb +19 -5
  90. data/lib/henitai/reporter.rb +15 -8
  91. data/lib/henitai/result.rb +32 -16
  92. data/lib/henitai/reuse_context.rb +50 -0
  93. data/lib/henitai/rspec_coverage_formatter.rb +4 -0
  94. data/lib/henitai/rspec_outcomes.rb +72 -0
  95. data/lib/henitai/runner.rb +58 -19
  96. data/lib/henitai/runner_dependencies.rb +22 -1
  97. data/lib/henitai/sampling_strategy.rb +36 -6
  98. data/lib/henitai/scenario_execution_result.rb +28 -5
  99. data/lib/henitai/signature_line.rb +21 -0
  100. data/lib/henitai/slot_scheduler/draining.rb +12 -2
  101. data/lib/henitai/slot_scheduler/process_control.rb +33 -0
  102. data/lib/henitai/slot_scheduler/retry_policy.rb +8 -6
  103. data/lib/henitai/slot_scheduler.rb +47 -8
  104. data/lib/henitai/source_file_selection.rb +1 -1
  105. data/lib/henitai/source_parser.rb +29 -9
  106. data/lib/henitai/static_filter.rb +45 -14
  107. data/lib/henitai/stillborn_filter.rb +70 -2
  108. data/lib/henitai/subject.rb +8 -3
  109. data/lib/henitai/subject_resolver.rb +65 -31
  110. data/lib/henitai/suite_boot_clock.rb +48 -0
  111. data/lib/henitai/survivor_activation_cache.rb +18 -11
  112. data/lib/henitai/survivor_rerun_strategy.rb +47 -43
  113. data/lib/henitai/test_file_outcomes.rb +79 -0
  114. data/lib/henitai/timeout_calibrator.rb +31 -9
  115. data/lib/henitai/timeout_ceiling.rb +37 -0
  116. data/lib/henitai/verdict_fingerprint.rb +29 -30
  117. data/lib/henitai/version.rb +1 -1
  118. data/lib/henitai.rb +17 -1
  119. data/sig/configuration_validator.rbs +1 -0
  120. data/sig/henitai.rbs +225 -45
  121. metadata +46 -3
  122. data/lib/henitai/survivor_test_filter.rb +0 -72
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: henitai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Otten
@@ -115,6 +115,7 @@ files:
115
115
  - lib/henitai.rb
116
116
  - lib/henitai/arid_node_filter.rb
117
117
  - lib/henitai/available_cpu_count.rb
118
+ - lib/henitai/bootstrap_error_message.rb
118
119
  - lib/henitai/canonical_report_merger.rb
119
120
  - lib/henitai/canonical_report_writer.rb
120
121
  - lib/henitai/checkpoint_reporter.rb
@@ -131,6 +132,8 @@ files:
131
132
  - lib/henitai/configuration_validator.rb
132
133
  - lib/henitai/configuration_validator/rules.rb
133
134
  - lib/henitai/configuration_validator/scalars.rb
135
+ - lib/henitai/constant_path.rb
136
+ - lib/henitai/control_run.rb
134
137
  - lib/henitai/coverage_bootstrapper.rb
135
138
  - lib/henitai/coverage_formatter.rb
136
139
  - lib/henitai/coverage_report_reader.rb
@@ -138,41 +141,74 @@ files:
138
141
  - lib/henitai/eager_load.rb
139
142
  - lib/henitai/equivalence_detector.rb
140
143
  - lib/henitai/equivalence_detector/operand_predicates.rb
144
+ - lib/henitai/example_summary.rb
141
145
  - lib/henitai/excluded_test_filter.rb
142
146
  - lib/henitai/execution_engine.rb
143
147
  - lib/henitai/execution_engine/env_scope.rb
148
+ - lib/henitai/execution_engine/fork_server_scope.rb
149
+ - lib/henitai/fidelity_check.rb
150
+ - lib/henitai/flaky_detection_baseline.rb
151
+ - lib/henitai/flaky_mutant_retrier.rb
152
+ - lib/henitai/flaky_retry_decision.rb
153
+ - lib/henitai/flaky_test_registry.rb
154
+ - lib/henitai/fork_server.rb
155
+ - lib/henitai/fork_server/client.rb
156
+ - lib/henitai/fork_server/group_killer.rb
157
+ - lib/henitai/fork_server/group_terminator.rb
158
+ - lib/henitai/fork_server/launcher.rb
159
+ - lib/henitai/fork_server/mutant_runner.rb
160
+ - lib/henitai/fork_server/protocol.rb
161
+ - lib/henitai/fork_server/reaper.rb
162
+ - lib/henitai/fork_server/runtime.rb
163
+ - lib/henitai/fork_server/server.rb
164
+ - lib/henitai/fork_server/server_process.rb
165
+ - lib/henitai/fork_server/status.rb
144
166
  - lib/henitai/generated_artifacts.rb
145
167
  - lib/henitai/git_diff_analyzer.rb
146
168
  - lib/henitai/incremental_filter.rb
147
169
  - lib/henitai/inherited_fd_registry.rb
148
170
  - lib/henitai/integration.rb
149
171
  - lib/henitai/integration/base.rb
172
+ - lib/henitai/integration/capped_log_sink.rb
150
173
  - lib/henitai/integration/child_bootstrap.rb
151
174
  - lib/henitai/integration/child_debug_log.rb
175
+ - lib/henitai/integration/child_report_store.rb
152
176
  - lib/henitai/integration/child_runtime_control.rb
153
177
  - lib/henitai/integration/coverage_suppression.rb
154
178
  - lib/henitai/integration/loaded_features.rb
155
179
  - lib/henitai/integration/minitest.rb
180
+ - lib/henitai/integration/minitest_autorun.rb
156
181
  - lib/henitai/integration/minitest_load_path.rb
182
+ - lib/henitai/integration/minitest_outcome_reporter.rb
183
+ - lib/henitai/integration/minitest_preload.rb
184
+ - lib/henitai/integration/minitest_runnable_filter.rb
157
185
  - lib/henitai/integration/minitest_suite_command.rb
158
186
  - lib/henitai/integration/minitest_test_runner.rb
159
187
  - lib/henitai/integration/mutant_run_support.rb
160
188
  - lib/henitai/integration/rails_environment_preloader.rb
161
189
  - lib/henitai/integration/rspec_child_runner.rb
190
+ - lib/henitai/integration/rspec_preload.rb
162
191
  - lib/henitai/integration/rspec_process_runner.rb
163
192
  - lib/henitai/integration/rspec_test_selection.rb
164
193
  - lib/henitai/integration/scenario_log_support.rb
165
194
  - lib/henitai/minitest_coverage_hook.rb
166
195
  - lib/henitai/minitest_coverage_reporter.rb
196
+ - lib/henitai/minitest_result_file.rb
167
197
  - lib/henitai/minitest_simplecov.rb
168
198
  - lib/henitai/mutant.rb
199
+ - lib/henitai/mutant/activation.rb
169
200
  - lib/henitai/mutant/activator.rb
201
+ - lib/henitai/mutant/def_injection.rb
202
+ - lib/henitai/mutant/lexical_scope_check.rb
203
+ - lib/henitai/mutant/lexical_target.rb
170
204
  - lib/henitai/mutant/parameter_source.rb
205
+ - lib/henitai/mutant/replacement.rb
171
206
  - lib/henitai/mutant_generator.rb
172
207
  - lib/henitai/mutant_history_store.rb
173
208
  - lib/henitai/mutant_history_store/sql.rb
174
209
  - lib/henitai/mutant_history_store/verdict_cache.rb
175
210
  - lib/henitai/mutant_identity.rb
211
+ - lib/henitai/mutant_verdict.rb
176
212
  - lib/henitai/mutation_skip_directives.rb
177
213
  - lib/henitai/operator.rb
178
214
  - lib/henitai/operators.rb
@@ -191,6 +227,7 @@ files:
191
227
  - lib/henitai/operators/method_expression.rb
192
228
  - lib/henitai/operators/pattern_match.rb
193
229
  - lib/henitai/operators/range_literal.rb
230
+ - lib/henitai/operators/regex_metacharacters.rb
194
231
  - lib/henitai/operators/regex_mutator.rb
195
232
  - lib/henitai/operators/return_value.rb
196
233
  - lib/henitai/operators/safe_navigation.rb
@@ -201,6 +238,7 @@ files:
201
238
  - lib/henitai/parser_current.rb
202
239
  - lib/henitai/per_test_coverage.rb
203
240
  - lib/henitai/per_test_coverage_collector.rb
241
+ - lib/henitai/per_test_coverage_delta.rb
204
242
  - lib/henitai/per_test_coverage_selector.rb
205
243
  - lib/henitai/process_liveness.rb
206
244
  - lib/henitai/process_wakeup.rb
@@ -209,11 +247,14 @@ files:
209
247
  - lib/henitai/reporter/dashboard_metadata_provider.rb
210
248
  - lib/henitai/reports_directory_lock.rb
211
249
  - lib/henitai/result.rb
250
+ - lib/henitai/reuse_context.rb
212
251
  - lib/henitai/rspec_coverage_formatter.rb
252
+ - lib/henitai/rspec_outcomes.rb
213
253
  - lib/henitai/runner.rb
214
254
  - lib/henitai/runner_dependencies.rb
215
255
  - lib/henitai/sampling_strategy.rb
216
256
  - lib/henitai/scenario_execution_result.rb
257
+ - lib/henitai/signature_line.rb
217
258
  - lib/henitai/slot_scheduler.rb
218
259
  - lib/henitai/slot_scheduler/drain_verdict.rb
219
260
  - lib/henitai/slot_scheduler/draining.rb
@@ -229,14 +270,16 @@ files:
229
270
  - lib/henitai/subject.rb
230
271
  - lib/henitai/subject_resolver.rb
231
272
  - lib/henitai/subject_selection.rb
273
+ - lib/henitai/suite_boot_clock.rb
232
274
  - lib/henitai/survivor_activation_cache.rb
233
275
  - lib/henitai/survivor_loader.rb
234
276
  - lib/henitai/survivor_rerun_strategy.rb
235
277
  - lib/henitai/survivor_selector.rb
236
- - lib/henitai/survivor_test_filter.rb
237
278
  - lib/henitai/syntax_validator.rb
279
+ - lib/henitai/test_file_outcomes.rb
238
280
  - lib/henitai/test_prioritizer.rb
239
281
  - lib/henitai/timeout_calibrator.rb
282
+ - lib/henitai/timeout_ceiling.rb
240
283
  - lib/henitai/unparse_helper.rb
241
284
  - lib/henitai/verdict_fingerprint.rb
242
285
  - lib/henitai/version.rb
@@ -252,7 +295,7 @@ metadata:
252
295
  changelog_uri: https://github.com/martinotten/henitai/blob/main/CHANGELOG.md
253
296
  documentation_uri: https://github.com/martinotten/henitai/blob/main/README.md
254
297
  homepage_uri: https://github.com/martinotten/henitai
255
- source_code_uri: https://github.com/martinotten/henitai/tree/v0.5.3
298
+ source_code_uri: https://github.com/martinotten/henitai/tree/v0.6.0
256
299
  rubygems_mfa_required: 'true'
257
300
  rdoc_options: []
258
301
  require_paths:
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Henitai
4
- # Splits a matched survivor set into stable and pending subsets by consulting
5
- # a git diff against the covering tests from the prior report.
6
- #
7
- # A survivor is **stable** (can skip re-execution) when:
8
- # - it has covering test data in the prior report, AND
9
- # - none of those test files appear in the diff between the prior run's
10
- # git_sha and the current HEAD.
11
- #
12
- # A survivor is **pending** (must execute) when:
13
- # - git_sha is nil (no anchor → conservative), OR
14
- # - its coveredBy data is absent or empty, OR
15
- # - at least one covering test file changed.
16
- #
17
- # On any git error the filter conservatively treats all survivors as pending.
18
- class SurvivorTestFilter
19
- # @param coverage_map [Hash<String, Array<String>>] stableId → [test_files]
20
- # @param git_sha [String, nil] git SHA from the prior report
21
- # @param dirty_source_files [Boolean] true when the current worktree has
22
- # dirty source files and the survivor shortcut must be disabled
23
- # @param worktree_changed_files [Array<String>] dirty tracked/untracked files
24
- # @param diff_analyzer [GitDiffAnalyzer]
25
- def initialize(
26
- coverage_map:,
27
- git_sha:,
28
- dirty_source_files: false,
29
- worktree_changed_files: [],
30
- diff_analyzer: GitDiffAnalyzer.new
31
- )
32
- @coverage_map = coverage_map
33
- @git_sha = git_sha
34
- @dirty_source_files = dirty_source_files
35
- @worktree_changed_files = Array(worktree_changed_files)
36
- @diff_analyzer = diff_analyzer
37
- end
38
-
39
- # @param mutants [Array<Mutant>]
40
- # @return [Hash<Symbol, Array<Mutant>>] { stable: [...], pending: [...] }
41
- def apply(mutants)
42
- return { stable: [], pending: mutants } if @dirty_source_files
43
- return { stable: [], pending: mutants } if @git_sha.nil?
44
-
45
- changed = changed_test_files
46
- return { stable: [], pending: mutants } if changed.nil?
47
-
48
- mutants.each_with_object({ stable: [], pending: [] }) do |mutant, result|
49
- bucket = stable_survivor?(mutant, changed) ? :stable : :pending
50
- result[bucket] << mutant
51
- end
52
- end
53
-
54
- private
55
-
56
- def stable_survivor?(mutant, changed)
57
- covering = @coverage_map[mutant.stable_id]
58
- return false if covering.nil? || covering.empty?
59
-
60
- !changed.intersect?(covering)
61
- end
62
-
63
- # Returns a Set of changed test file paths, or nil on any git error
64
- # (nil triggers conservative fallback in #apply — all survivors pending).
65
- def changed_test_files
66
- committed = @diff_analyzer.changed_files(from: @git_sha, to: "HEAD")
67
- (committed + @worktree_changed_files).to_set
68
- rescue StandardError
69
- nil
70
- end
71
- end
72
- end