branchproof 0.5.0 → 0.7.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/CHANGELOG.md +20 -0
- data/README.md +129 -31
- data/doc/Branchproof/CoverageIndex.md +3 -0
- data/doc/Branchproof/DecisionSyntax.md +20 -0
- data/doc/Branchproof/FlowInstrumentation.md +7 -0
- data/doc/Branchproof/Instrumenter.md +1 -0
- data/doc/Branchproof/Report.md +10 -0
- data/doc/Branchproof/Runtime.md +19 -0
- data/doc/Branchproof/RuntimeFlow.md +27 -0
- data/doc/Branchproof/SavedReport.md +6 -0
- data/doc/Branchproof/Source.md +1 -0
- data/doc/Branchproof.md +6 -2
- data/doc/CHANGELOG.md +20 -0
- data/doc/README.md +129 -31
- data/lib/branchproof/analyzer.rb +273 -13
- data/lib/branchproof/cli.rb +2 -2
- data/lib/branchproof/comparison.rb +1 -1
- data/lib/branchproof/coverage_index.rb +90 -2
- data/lib/branchproof/decision_syntax.rb +294 -0
- data/lib/branchproof/evidence.rb +54 -9
- data/lib/branchproof/flow_instrumentation.rb +107 -0
- data/lib/branchproof/focused_report.rb +102 -21
- data/lib/branchproof/instrumenter.rb +28 -13
- data/lib/branchproof/report.rb +348 -31
- data/lib/branchproof/runtime.rb +3 -0
- data/lib/branchproof/runtime_flow.rb +58 -0
- data/lib/branchproof/saved_report.rb +245 -6
- data/lib/branchproof/source.rb +191 -35
- data/lib/branchproof/version.rb +1 -1
- data/llms.txt +6 -2
- data/sig/branchproof.rbs +7 -0
- metadata +7 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c4c0c87db7babd3785baf2ea439a90ec852253e7ade2837becec235ee9ac7055
|
|
4
|
+
data.tar.gz: 29b5cd02d6ab9419343af3c9c1d49fd07a77c2487eaf2631aafbc90bafdf4296
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bffba10f09dc43d851a79373b1e3ec8b2457179a2f69da8b8076d1f48c002f3a8f6a88e7a30f8c970c5f9960a73abbec4829dfcbee2581da61c5ff3cd1e233f4
|
|
7
|
+
data.tar.gz: c808687e23a8b27ed794d723d4a390f8296d5ade907fb6255660ac025e657530eff850d578d7d600b1177076dcf2376d577b15a4310e620cd618bf4598f626fc
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.7.0] - 2026-09-10
|
|
4
|
+
|
|
5
|
+
- Discover Boolean loop predicates, subjectless case candidates, standalone
|
|
6
|
+
short-circuit expressions, and pattern predicates through Prism.
|
|
7
|
+
- Analyze unary NOT and keyword `and`/`or` with Ruby's parsed precedence.
|
|
8
|
+
- Attribute selected paths for ordinary case, unguarded case/in, safe navigation,
|
|
9
|
+
and conditional assignments without adding them to MC/DC denominators.
|
|
10
|
+
- Expose decision kinds, contexts, alternative evidence, and explicit unsupported
|
|
11
|
+
constructs in schema 1.2 reports while retaining older saved-report support.
|
|
12
|
+
|
|
13
|
+
## [0.6.0] - 2026-09-10
|
|
14
|
+
|
|
15
|
+
- Report Decision, Condition, and Condition/Decision Coverage alongside
|
|
16
|
+
existing MC/DC evidence from one test execution.
|
|
17
|
+
- Show explicit coverage counts, supporting tests, and missing Boolean
|
|
18
|
+
observations in decision, condition, and test views and JSON reports.
|
|
19
|
+
- Calculate the same coverage criteria at every reporting level and retain
|
|
20
|
+
analysis in level-1 snapshots for offline inspection at higher detail.
|
|
21
|
+
Continue to support legacy snapshots without analysis at level 1.
|
|
22
|
+
|
|
3
23
|
## [0.5.0] - 2026-09-10
|
|
4
24
|
|
|
5
25
|
- Show source filenames beside diagnostics in decision, condition, and test
|
data/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Branchproof
|
|
2
2
|
|
|
3
|
-
Branchproof measures modified condition/decision
|
|
4
|
-
serial Minitest run. It
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
Branchproof measures decision, condition, and modified condition/decision
|
|
4
|
+
coverage (MC/DC) from one serial Minitest run. It discovers Ruby decisions
|
|
5
|
+
through Prism, records their runtime paths, and attributes evidence to tests.
|
|
6
|
+
Boolean decisions receive the coverage ladder; `case`, pattern alternatives,
|
|
7
|
+
safe navigation, and conditional assignments receive alternative coverage.
|
|
8
8
|
|
|
9
9
|
The gem and primary command are named `branchproof`. The `mcdc` command and
|
|
10
10
|
`MCDC` namespace remain compatibility aliases with the same behavior.
|
|
@@ -126,6 +126,50 @@ Additional tests outside this MC/DC evidence set may improve coverage.
|
|
|
126
126
|
The test execution still runs once for the selected level. Use `--format
|
|
127
127
|
json` when a consumer needs the complete identifiers and versioned schema.
|
|
128
128
|
|
|
129
|
+
### Coverage ladder
|
|
130
|
+
|
|
131
|
+
Each successful `analyze` run calculates four criteria from the same completed
|
|
132
|
+
observations. The report shows their status for each supported decision and
|
|
133
|
+
aggregate counts with explicit denominators:
|
|
134
|
+
|
|
135
|
+
| Criterion | Requirement | Aggregate denominator |
|
|
136
|
+
| --- | --- | --- |
|
|
137
|
+
| Decision | The decision produced both true and false | Supported decisions |
|
|
138
|
+
| Condition | Every atomic condition evaluated both true and false | Two required truth values per supported condition |
|
|
139
|
+
| Condition/Decision | Both Decision and Condition Coverage hold for a decision | Supported decisions |
|
|
140
|
+
| MC/DC | Every condition has an independence witness pair | Supported conditions |
|
|
141
|
+
|
|
142
|
+
For `logged_in? && admin?`, observations `[F-] => F` and `[TT] => T` give:
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
Decision PASS
|
|
146
|
+
Condition FAIL (3/4 values observed)
|
|
147
|
+
Condition/Decision FAIL
|
|
148
|
+
MC/DC FAIL (1/2 conditions proven)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The skipped `admin?` in `[F-]` counts as neither true nor false. Conditions
|
|
152
|
+
that did evaluate count toward Condition Coverage even when their value was
|
|
153
|
+
masked by another condition. Here, the two observations prove independence
|
|
154
|
+
for `logged_in?`; `admin?` still needs `[TF] => F`.
|
|
155
|
+
|
|
156
|
+
Decision and Condition Coverage are calculated independently from the captured
|
|
157
|
+
evidence. Condition/Decision requires both; MC/DC adds independence evidence.
|
|
158
|
+
Unsupported decisions are excluded from every denominator, while
|
|
159
|
+
unexecuted supported decisions remain in scope. Empty denominators are N/A.
|
|
160
|
+
|
|
161
|
+
Reports retain the observations and owning tests for each decision outcome
|
|
162
|
+
and condition value. Missing values describe required runtime observations,
|
|
163
|
+
not application inputs or a guarantee that the path is reachable. Unattributed
|
|
164
|
+
observations can provide truth-value evidence without identifying a test;
|
|
165
|
+
the report's completeness and diagnostics still apply.
|
|
166
|
+
|
|
167
|
+
JSON stores aggregate counts under `analysis.coverage`, per-decision results
|
|
168
|
+
under `analysis.decisions[].coverage`, and condition value evidence under
|
|
169
|
+
`analysis.decisions[].condition_results[].coverage`. Existing MC/DC witness
|
|
170
|
+
pairs, counterpart constraints, and raw vectors remain available. Statuses
|
|
171
|
+
distinguish `covered`, `partial`, `unexecuted`, and `unsupported` results.
|
|
172
|
+
|
|
129
173
|
### Find missing cases
|
|
130
174
|
|
|
131
175
|
Use `--missing-only` to focus the terminal report on conditions that still
|
|
@@ -175,15 +219,17 @@ test inputs; they do not by themselves prove a bug in the application.
|
|
|
175
219
|
|
|
176
220
|
The levels select how much of the one-run result is displayed:
|
|
177
221
|
|
|
178
|
-
* Level 1 reports observed vectors grouped by their
|
|
222
|
+
* Level 1 reports the coverage ladder and observed vectors grouped by their
|
|
223
|
+
raw decision outcomes.
|
|
179
224
|
* Level 2 includes the smallest supporting sets found for vectors and tests.
|
|
180
225
|
* Level 3 (the default) includes condition independence witnesses and
|
|
181
226
|
counterpart constraints, as well as the Level 1 and 2 evidence.
|
|
182
227
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
228
|
+
All levels calculate the same criteria from one captured run. The level
|
|
229
|
+
controls displayed evidence, not the coverage criterion; JSON retains the
|
|
230
|
+
analysis even at Level 1. A failed, unsupported, or incomplete run is reported
|
|
231
|
+
with its status and diagnostics and cannot become a successful coverage
|
|
232
|
+
result by changing the display level.
|
|
187
233
|
|
|
188
234
|
### Focused condition and test views
|
|
189
235
|
|
|
@@ -232,7 +278,8 @@ artifacts when you need to retain multiple runs.
|
|
|
232
278
|
The `report` command reads the saved document without loading the application
|
|
233
279
|
or running tests. It uses locations and metadata captured in the report, so
|
|
234
280
|
rendering remains useful after the original checkout has moved or been
|
|
235
|
-
removed.
|
|
281
|
+
removed. New snapshots retain the ladder at every level. Legacy snapshots
|
|
282
|
+
without analysis can still be rendered at Level 1; levels 2 and 3 require
|
|
236
283
|
analysis in the saved report. The repository ignores `.branchproof/`; choose a
|
|
237
284
|
different path and CI artifact policy when a project needs to retain reports.
|
|
238
285
|
Saved JSON includes existing raw metadata such as test names and expressions;
|
|
@@ -274,26 +321,77 @@ short-circuited or masked rather than fixed to the same observed values. For exa
|
|
|
274
321
|
short-circuits it once, but does not prove `right`; `[TF]` is also required.
|
|
275
322
|
The condition and test views preserve that distinction.
|
|
276
323
|
|
|
277
|
-
### Supported
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
324
|
+
### Supported decision forms
|
|
325
|
+
|
|
326
|
+
Every decision has a stable `kind` and `context` in JSON. The Boolean ladder
|
|
327
|
+
applies to the following forms:
|
|
328
|
+
|
|
329
|
+
| Construct | Kind | Context |
|
|
330
|
+
| --- | --- | --- |
|
|
331
|
+
| `if`, modifier `if`, `elsif`, `unless`, ternary | `boolean` | `if`, `elsif`, `unless`, `ternary` |
|
|
332
|
+
| `while`, `until`, including modifier and post-test loops | `boolean` | `while`, `until` |
|
|
333
|
+
| Each subjectless `case` candidate | `boolean` | `case_when` |
|
|
334
|
+
| Standalone `value in pattern` | `boolean` | `pattern_in` |
|
|
335
|
+
| Evaluated pattern guard predicate | `boolean` | `pattern_guard` |
|
|
336
|
+
| Standalone `&&`, `||`, `and`, `or` | `boolean` | `short_circuit` |
|
|
337
|
+
|
|
338
|
+
Prism determines precedence. `!` and `not` appear as NOT nodes in the Boolean
|
|
339
|
+
tree; their operands remain the conditions. Short-circuited operands remain
|
|
340
|
+
not evaluated. A Boolean subtree already decomposed in a decision is not
|
|
341
|
+
inventoried again as a standalone decision.
|
|
342
|
+
|
|
343
|
+
Loop outcomes describe the predicate as written: an `until` predicate that
|
|
344
|
+
returns true ends the loop. Every predicate evaluation receives an execution
|
|
345
|
+
ID. Repeated equivalent executions aggregate into a vector's `count`, retaining
|
|
346
|
+
the supporting tests. Ternary outcomes likewise describe the predicate, not
|
|
347
|
+
the value returned by the chosen branch.
|
|
348
|
+
|
|
349
|
+
Other constructs use alternative coverage, separate from MC/DC:
|
|
350
|
+
|
|
351
|
+
| Construct | Kind | Context | Required alternatives |
|
|
352
|
+
| --- | --- | --- | --- |
|
|
353
|
+
| `case subject` | `multiway` | `case` | Each `when` candidate and `else` (or implicit no-match path) |
|
|
354
|
+
| `case/in` | `pattern` | `case_in` | Each pattern clause and explicit `else`, if present |
|
|
355
|
+
| `receiver&.method` | `implicit` | `safe_navigation` | Receiver nil / non-nil |
|
|
356
|
+
| `lhs ||= rhs` | `implicit` | `or_assignment` | RHS skipped / executed |
|
|
357
|
+
| `lhs &&= rhs` | `implicit` | `and_assignment` | RHS skipped / executed |
|
|
358
|
+
|
|
359
|
+
Each safe-navigation operation in a chain is a distinct decision. Assignment
|
|
360
|
+
instrumentation preserves Ruby's native local, instance, class, global,
|
|
361
|
+
constant, method, and indexed assignment operations, including receiver and
|
|
362
|
+
index evaluation order. Safe navigation distinguishes nil from false.
|
|
363
|
+
|
|
364
|
+
For multiway decisions, vector values mean selected (`true`), evaluated but
|
|
365
|
+
not selected (`false`), and skipped (`null`). Later alternatives remain skipped
|
|
366
|
+
when an earlier candidate matches. Implicit vectors record the selected path
|
|
367
|
+
and its unselected complement. Their `outcome` is a selection marker, not the
|
|
368
|
+
truthiness of the application's return value. Reports label these as paths,
|
|
369
|
+
not Boolean outcomes. Each alternative exposes selected, not-selected, and
|
|
370
|
+
skipped evidence with test and vector IDs. The alternative denominator is the
|
|
371
|
+
number of supported selectable alternatives; these decisions do not enter
|
|
372
|
+
Boolean-ladder or MC/DC denominators.
|
|
373
|
+
|
|
374
|
+
A `case/in` without `else` retains Ruby's native no-match exception. An execution
|
|
375
|
+
that fails before choosing a branch is aborted, not counted as a selected
|
|
376
|
+
alternative. Selected branches and assignment paths remain observed even when
|
|
377
|
+
their bodies or right-hand sides subsequently raise or return.
|
|
378
|
+
|
|
379
|
+
Unsupported syntax stays visible and outside coverage denominators. Current
|
|
380
|
+
exclusions include guarded `case/in` (`unsupported_pattern_guard`), dynamic
|
|
381
|
+
`when` splats (`unsupported_case_splat`), safe-navigation compound assignment
|
|
382
|
+
(`unsupported_assignment_target`), and rescue alternatives
|
|
383
|
+
(`unsupported_rescue_control_flow`). A guard predicate can still supply Boolean
|
|
384
|
+
evidence when Ruby evaluates it; an unsupported guarded case does not claim
|
|
385
|
+
pattern-match coverage from that evidence. Flip-flops remain
|
|
386
|
+
`unsupported_flip_flop`. Decisions inside `defined?`, contextual regular
|
|
387
|
+
expressions, heredocs, unsafe predicates, and limit overflows retain explicit
|
|
388
|
+
exclusions. Ruby-defined custom `!` methods keep their runtime behavior;
|
|
389
|
+
evidence that contradicts Boolean negation is rejected instead of proving
|
|
390
|
+
coverage with an invalid logical model.
|
|
391
|
+
|
|
392
|
+
New reports use schema `1.2`; saved schema `1.0` and `1.1` reports remain
|
|
393
|
+
readable. Expanded discovery changes coverage denominators, so compare reports
|
|
394
|
+
with their supported syntax scope in mind.
|
|
297
395
|
|
|
298
396
|
### Limits
|
|
299
397
|
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
Derives condition- and test-oriented rows from one report document.
|
|
9
9
|
|
|
10
10
|
## Attributes
|
|
11
|
+
### `alternatives` [R] <a id="attribute-i-alternatives"></a> <a id="alternatives-instance_method"></a>
|
|
12
|
+
Returns the value of attribute alternatives.
|
|
13
|
+
|
|
11
14
|
### `conditions` [R] <a id="attribute-i-conditions"></a> <a id="conditions-instance_method"></a>
|
|
12
15
|
Returns the value of attribute conditions.
|
|
13
16
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Module Branchproof::DecisionSyntax <a id="module-Branchproof-DecisionSyntax"></a>
|
|
2
|
+
|
|
3
|
+
| | |
|
|
4
|
+
| --- | --- |
|
|
5
|
+
| **Defined in** | lib/branchproof/decision_syntax.rb |
|
|
6
|
+
|
|
7
|
+
Discovers control-flow expressions whose truth is not represented by an
|
|
8
|
+
ordinary Prism IfNode. The records intentionally contain byte ranges and
|
|
9
|
+
scalar metadata only; Prism nodes must not escape the source pass.
|
|
10
|
+
|
|
11
|
+
## Constants
|
|
12
|
+
### `AND_WRITE_NODE_NAMES` <a id="constant-AND_WRITE_NODE_NAMES"></a> <a id="AND_WRITE_NODE_NAMES-constant"></a>
|
|
13
|
+
Not documented.
|
|
14
|
+
|
|
15
|
+
### `OR_WRITE_NODE_NAMES` <a id="constant-OR_WRITE_NODE_NAMES"></a> <a id="OR_WRITE_NODE_NAMES-constant"></a>
|
|
16
|
+
Not documented.
|
|
17
|
+
|
|
18
|
+
## Public Instance Methods
|
|
19
|
+
### `flow_decisions_for(program, bytes, source_id, file_reasons = [], encoding = "UTF-8")` <a id="method-i-flow_decisions_for"></a> <a id="flow_decisions_for-instance_method"></a>
|
|
20
|
+
Not documented.
|
data/doc/Branchproof/Report.md
CHANGED
|
@@ -19,9 +19,19 @@ Not documented.
|
|
|
19
19
|
Not documented.
|
|
20
20
|
|
|
21
21
|
## Public Instance Methods
|
|
22
|
+
### `condition_coverage_evidence(decision_id:, condition_id:)` <a id="method-i-condition_coverage_evidence"></a> <a id="condition_coverage_evidence-instance_method"></a>
|
|
23
|
+
Returns condition-value evidence for focused renderers without exposing the
|
|
24
|
+
report's internal document traversal or mutating saved records.
|
|
25
|
+
|
|
22
26
|
### `condition_explanation(decision_id:, condition_id:)` <a id="method-i-condition_explanation"></a> <a id="condition_explanation-instance_method"></a>
|
|
23
27
|
Shares the existing missing-case wording with focused terminal views.
|
|
24
28
|
|
|
29
|
+
### `coverage_ladder_lines()` <a id="method-i-coverage_ladder_lines"></a> <a id="coverage_ladder_lines-instance_method"></a>
|
|
30
|
+
Render the shared ladder in every terminal view.
|
|
31
|
+
|
|
32
|
+
### `coverage_status_label(status)` <a id="method-i-coverage_status_label"></a> <a id="coverage_status_label-instance_method"></a>
|
|
33
|
+
Not documented.
|
|
34
|
+
|
|
25
35
|
### `diagnostic_message(diagnostic)` <a id="method-i-diagnostic_message"></a> <a id="diagnostic_message-instance_method"></a>
|
|
26
36
|
Formats source context consistently in live and saved terminal views.
|
|
27
37
|
|
data/doc/Branchproof/Runtime.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
| | |
|
|
4
4
|
| --- | --- |
|
|
5
|
+
| **Extended by** | [Branchproof::RuntimeFlow](RuntimeFlow.md) |
|
|
5
6
|
| **Defined in** | lib/branchproof/runtime.rb |
|
|
6
7
|
|
|
7
8
|
Process-local execution recorder. It deliberately never coerces or stores
|
|
@@ -27,6 +28,24 @@ Not documented.
|
|
|
27
28
|
### `finish(decision_id, value)` <a id="method-c-finish"></a> <a id="finish-class_method"></a>
|
|
28
29
|
Not documented.
|
|
29
30
|
|
|
31
|
+
### `flow_candidate(decision_id, index)` <a id="method-c-flow_candidate"></a> <a id="flow_candidate-class_method"></a>
|
|
32
|
+
Not documented.
|
|
33
|
+
|
|
34
|
+
### `flow_finish(decision_id, value, default_path = nil)` <a id="method-c-flow_finish"></a> <a id="flow_finish-class_method"></a>
|
|
35
|
+
Not documented.
|
|
36
|
+
|
|
37
|
+
### `flow_path(decision_id, index)` <a id="method-c-flow_path"></a> <a id="flow_path-class_method"></a>
|
|
38
|
+
Not documented.
|
|
39
|
+
|
|
40
|
+
### `flow_receiver(decision_id, receiver)` <a id="method-c-flow_receiver"></a> <a id="flow_receiver-class_method"></a>
|
|
41
|
+
Not documented.
|
|
42
|
+
|
|
43
|
+
### `flow_select(decision_id, index)` <a id="method-c-flow_select"></a> <a id="flow_select-class_method"></a>
|
|
44
|
+
Not documented.
|
|
45
|
+
|
|
46
|
+
### `flow_selected(decision_id)` <a id="method-c-flow_selected"></a> <a id="flow_selected-class_method"></a>
|
|
47
|
+
Not documented.
|
|
48
|
+
|
|
30
49
|
### `leave(decision_id)` <a id="method-c-leave"></a> <a id="leave-class_method"></a>
|
|
31
50
|
Not documented.
|
|
32
51
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Module Branchproof::RuntimeFlow <a id="module-Branchproof-RuntimeFlow"></a>
|
|
2
|
+
|
|
3
|
+
| | |
|
|
4
|
+
| --- | --- |
|
|
5
|
+
| **Defined in** | lib/branchproof/runtime_flow.rb |
|
|
6
|
+
|
|
7
|
+
Records native Ruby path selection without evaluating application values
|
|
8
|
+
twice.
|
|
9
|
+
|
|
10
|
+
## Public Instance Methods
|
|
11
|
+
### `flow_candidate(decision_id, index)` <a id="method-i-flow_candidate"></a> <a id="flow_candidate-instance_method"></a>
|
|
12
|
+
Not documented.
|
|
13
|
+
|
|
14
|
+
### `flow_finish(decision_id, value, default_path = nil)` <a id="method-i-flow_finish"></a> <a id="flow_finish-instance_method"></a>
|
|
15
|
+
Not documented.
|
|
16
|
+
|
|
17
|
+
### `flow_path(decision_id, index)` <a id="method-i-flow_path"></a> <a id="flow_path-instance_method"></a>
|
|
18
|
+
Not documented.
|
|
19
|
+
|
|
20
|
+
### `flow_receiver(decision_id, receiver)` <a id="method-i-flow_receiver"></a> <a id="flow_receiver-instance_method"></a>
|
|
21
|
+
Not documented.
|
|
22
|
+
|
|
23
|
+
### `flow_select(decision_id, index)` <a id="method-i-flow_select"></a> <a id="flow_select-instance_method"></a>
|
|
24
|
+
Not documented.
|
|
25
|
+
|
|
26
|
+
### `flow_selected(decision_id)` <a id="method-i-flow_selected"></a> <a id="flow_selected-instance_method"></a>
|
|
27
|
+
Not documented.
|
|
@@ -14,6 +14,12 @@ Not documented.
|
|
|
14
14
|
### `CRITERION_VERSION` <a id="constant-CRITERION_VERSION"></a> <a id="CRITERION_VERSION-constant"></a>
|
|
15
15
|
Not documented.
|
|
16
16
|
|
|
17
|
+
### `DECISION_KINDS` <a id="constant-DECISION_KINDS"></a> <a id="DECISION_KINDS-constant"></a>
|
|
18
|
+
Not documented.
|
|
19
|
+
|
|
20
|
+
### `NONBOOLEAN_KINDS` <a id="constant-NONBOOLEAN_KINDS"></a> <a id="NONBOOLEAN_KINDS-constant"></a>
|
|
21
|
+
Not documented.
|
|
22
|
+
|
|
17
23
|
### `REQUIRED_FIELDS` <a id="constant-REQUIRED_FIELDS"></a> <a id="REQUIRED_FIELDS-constant"></a>
|
|
18
24
|
Not documented.
|
|
19
25
|
|
data/doc/Branchproof/Source.md
CHANGED
data/doc/Branchproof.md
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
| | |
|
|
4
4
|
| --- | --- |
|
|
5
|
-
| **Defined in** | lib/branchproof.rb, lib/branchproof/cli.rb, lib/branchproof/limits.rb, lib/branchproof/loader.rb, lib/branchproof/report.rb, lib/branchproof/source.rb, lib/branchproof/worker.rb, lib/branchproof/project.rb, lib/branchproof/records.rb, lib/branchproof/runtime.rb, lib/branchproof/version.rb, lib/branchproof/analyzer.rb, lib/branchproof/evidence.rb, lib/branchproof/minimizer.rb, lib/branchproof/comparison.rb, lib/branchproof/instrumenter.rb, lib/branchproof/saved_report.rb, lib/branchproof/rails_support.rb, lib/branchproof/coverage_index.rb, lib/branchproof/focused_report.rb, lib/branchproof/minitest_adapter.rb, lib/branchproof/comparison_report.rb |
|
|
5
|
+
| **Defined in** | lib/branchproof.rb, lib/branchproof/cli.rb, lib/branchproof/limits.rb, lib/branchproof/loader.rb, lib/branchproof/report.rb, lib/branchproof/source.rb, lib/branchproof/worker.rb, lib/branchproof/project.rb, lib/branchproof/records.rb, lib/branchproof/runtime.rb, lib/branchproof/version.rb, lib/branchproof/analyzer.rb, lib/branchproof/evidence.rb, lib/branchproof/minimizer.rb, lib/branchproof/comparison.rb, lib/branchproof/instrumenter.rb, lib/branchproof/runtime_flow.rb, lib/branchproof/saved_report.rb, lib/branchproof/rails_support.rb, lib/branchproof/coverage_index.rb, lib/branchproof/focused_report.rb, lib/branchproof/decision_syntax.rb, lib/branchproof/minitest_adapter.rb, lib/branchproof/comparison_report.rb, lib/branchproof/flow_instrumentation.rb |
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Keep each bounded source rewrite together so its evaluation order can be
|
|
8
|
+
audited. rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
8
9
|
|
|
9
10
|
## Constants
|
|
10
11
|
### `VERSION` <a id="constant-VERSION"></a> <a id="VERSION-constant"></a>
|
|
@@ -17,8 +18,10 @@ Not documented.
|
|
|
17
18
|
- [Branchproof/Comparison.md](Branchproof/Comparison.md)
|
|
18
19
|
- [Branchproof/ComparisonReport.md](Branchproof/ComparisonReport.md)
|
|
19
20
|
- [Branchproof/CoverageIndex.md](Branchproof/CoverageIndex.md)
|
|
21
|
+
- [Branchproof/DecisionSyntax.md](Branchproof/DecisionSyntax.md)
|
|
20
22
|
- [Branchproof/Error.md](Branchproof/Error.md)
|
|
21
23
|
- [Branchproof/Evidence.md](Branchproof/Evidence.md)
|
|
24
|
+
- [Branchproof/FlowInstrumentation.md](Branchproof/FlowInstrumentation.md)
|
|
22
25
|
- [Branchproof/FocusedReport.md](Branchproof/FocusedReport.md)
|
|
23
26
|
- [Branchproof/Instrumenter.md](Branchproof/Instrumenter.md)
|
|
24
27
|
- [Branchproof/Limits.md](Branchproof/Limits.md)
|
|
@@ -31,6 +34,7 @@ Not documented.
|
|
|
31
34
|
- [Branchproof/Records.md](Branchproof/Records.md)
|
|
32
35
|
- [Branchproof/Report.md](Branchproof/Report.md)
|
|
33
36
|
- [Branchproof/Runtime.md](Branchproof/Runtime.md)
|
|
37
|
+
- [Branchproof/RuntimeFlow.md](Branchproof/RuntimeFlow.md)
|
|
34
38
|
- [Branchproof/SavedReport.md](Branchproof/SavedReport.md)
|
|
35
39
|
- [Branchproof/Source.md](Branchproof/Source.md)
|
|
36
40
|
- [Branchproof/Worker.md](Branchproof/Worker.md)
|
data/doc/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.7.0] - 2026-09-10
|
|
4
|
+
|
|
5
|
+
- Discover Boolean loop predicates, subjectless case candidates, standalone
|
|
6
|
+
short-circuit expressions, and pattern predicates through Prism.
|
|
7
|
+
- Analyze unary NOT and keyword `and`/`or` with Ruby's parsed precedence.
|
|
8
|
+
- Attribute selected paths for ordinary case, unguarded case/in, safe navigation,
|
|
9
|
+
and conditional assignments without adding them to MC/DC denominators.
|
|
10
|
+
- Expose decision kinds, contexts, alternative evidence, and explicit unsupported
|
|
11
|
+
constructs in schema 1.2 reports while retaining older saved-report support.
|
|
12
|
+
|
|
13
|
+
## [0.6.0] - 2026-09-10
|
|
14
|
+
|
|
15
|
+
- Report Decision, Condition, and Condition/Decision Coverage alongside
|
|
16
|
+
existing MC/DC evidence from one test execution.
|
|
17
|
+
- Show explicit coverage counts, supporting tests, and missing Boolean
|
|
18
|
+
observations in decision, condition, and test views and JSON reports.
|
|
19
|
+
- Calculate the same coverage criteria at every reporting level and retain
|
|
20
|
+
analysis in level-1 snapshots for offline inspection at higher detail.
|
|
21
|
+
Continue to support legacy snapshots without analysis at level 1.
|
|
22
|
+
|
|
3
23
|
## [0.5.0] - 2026-09-10
|
|
4
24
|
|
|
5
25
|
- Show source filenames beside diagnostics in decision, condition, and test
|