@3f-consulting/spec-controller-core 0.1.0-alpha.7 → 0.1.0-alpha.70
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.
- package/README.md +3 -3
- package/dist/assemble/evidenceReconciliationFromSources.d.ts +5 -40
- package/dist/assemble/evidenceReconciliationFromSources.d.ts.map +1 -1
- package/dist/assemble/evidenceReconciliationFromSources.js +30 -325
- package/dist/assemble/evidenceReconciliationFromSources.js.map +1 -1
- package/dist/assemble/renderInput.d.ts +7 -73
- package/dist/assemble/renderInput.d.ts.map +1 -1
- package/dist/assemble/renderInput.js +3 -45
- package/dist/assemble/renderInput.js.map +1 -1
- package/dist/census/evidenceObligations.d.ts +11 -46
- package/dist/census/evidenceObligations.d.ts.map +1 -1
- package/dist/census/evidenceObligations.js +19 -25
- package/dist/census/evidenceObligations.js.map +1 -1
- package/dist/domain/evidenceOrder.d.ts +3 -0
- package/dist/domain/evidenceOrder.d.ts.map +1 -0
- package/dist/domain/evidenceOrder.js +15 -0
- package/dist/domain/evidenceOrder.js.map +1 -0
- package/dist/domain/evidenceReconciliation.d.ts +21 -391
- package/dist/domain/evidenceReconciliation.d.ts.map +1 -1
- package/dist/domain/evidenceReconciliation.js +87 -382
- package/dist/domain/evidenceReconciliation.js.map +1 -1
- package/dist/domain/featureCode.d.ts +4 -0
- package/dist/domain/featureCode.d.ts.map +1 -0
- package/dist/domain/featureCode.js +12 -0
- package/dist/domain/featureCode.js.map +1 -0
- package/dist/domain/journal.d.ts +8 -393
- package/dist/domain/journal.d.ts.map +1 -1
- package/dist/domain/journal.js +6 -118
- package/dist/domain/journal.js.map +1 -1
- package/dist/domain/ledger.d.ts +8 -328
- package/dist/domain/ledger.d.ts.map +1 -1
- package/dist/domain/ledger.js +23 -326
- package/dist/domain/ledger.js.map +1 -1
- package/dist/domain/messages.d.ts +213 -0
- package/dist/domain/messages.d.ts.map +1 -0
- package/dist/domain/messages.js +313 -0
- package/dist/domain/messages.js.map +1 -0
- package/dist/domain/outcome.d.ts +3 -0
- package/dist/domain/outcome.d.ts.map +1 -0
- package/dist/domain/outcome.js +2 -0
- package/dist/domain/outcome.js.map +1 -0
- package/dist/domain/posting.d.ts +8 -105
- package/dist/domain/posting.d.ts.map +1 -1
- package/dist/domain/posting.js +4 -56
- package/dist/domain/posting.js.map +1 -1
- package/dist/domain/qualityCheckFault.d.ts +3 -43
- package/dist/domain/qualityCheckFault.d.ts.map +1 -1
- package/dist/domain/qualityCheckFault.js +0 -24
- package/dist/domain/qualityCheckFault.js.map +1 -1
- package/dist/domain/qualityCheckReconciliation.d.ts +7 -280
- package/dist/domain/qualityCheckReconciliation.d.ts.map +1 -1
- package/dist/domain/qualityCheckReconciliation.js +63 -463
- package/dist/domain/qualityCheckReconciliation.js.map +1 -1
- package/dist/domain/qualityCheckReconciliationFault.d.ts +0 -19
- package/dist/domain/qualityCheckReconciliationFault.d.ts.map +1 -1
- package/dist/domain/qualityCheckReconciliationFault.js +1 -24
- package/dist/domain/qualityCheckReconciliationFault.js.map +1 -1
- package/dist/domain/scenarioCodeError.d.ts +16 -0
- package/dist/domain/scenarioCodeError.d.ts.map +1 -0
- package/dist/domain/scenarioCodeError.js +4 -0
- package/dist/domain/scenarioCodeError.js.map +1 -0
- package/dist/domain/scenarioReconciliation.d.ts +2 -207
- package/dist/domain/scenarioReconciliation.d.ts.map +1 -1
- package/dist/domain/scenarioReconciliation.js +4 -101
- package/dist/domain/scenarioReconciliation.js.map +1 -1
- package/dist/domain/scnAllocation.d.ts +27 -0
- package/dist/domain/scnAllocation.d.ts.map +1 -0
- package/dist/domain/scnAllocation.js +33 -0
- package/dist/domain/scnAllocation.js.map +1 -0
- package/dist/domain/verdictCode.d.ts +10 -0
- package/dist/domain/verdictCode.d.ts.map +1 -0
- package/dist/domain/verdictCode.js +16 -0
- package/dist/domain/verdictCode.js.map +1 -0
- package/dist/index.d.ts +14 -40
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -88
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +3 -27
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +3 -94
- package/dist/internal.js.map +1 -1
- package/dist/lib/bareTerm.d.ts +0 -39
- package/dist/lib/bareTerm.d.ts.map +1 -1
- package/dist/lib/bareTerm.js +0 -39
- package/dist/lib/bareTerm.js.map +1 -1
- package/dist/lib/portablePath.d.ts.map +1 -1
- package/dist/lib/portablePath.js +2 -16
- package/dist/lib/portablePath.js.map +1 -1
- package/dist/lib/scnCitation.d.ts +0 -32
- package/dist/lib/scnCitation.d.ts.map +1 -1
- package/dist/lib/scnCitation.js +2 -42
- package/dist/lib/scnCitation.js.map +1 -1
- package/dist/model.d.ts +0 -23
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +0 -23
- package/dist/model.js.map +1 -1
- package/dist/parse/checkScriptsRunInCI.d.ts +5 -168
- package/dist/parse/checkScriptsRunInCI.d.ts.map +1 -1
- package/dist/parse/checkScriptsRunInCI.js +11 -171
- package/dist/parse/checkScriptsRunInCI.js.map +1 -1
- package/dist/parse/ciStepRecord.d.ts +4 -118
- package/dist/parse/ciStepRecord.d.ts.map +1 -1
- package/dist/parse/ciStepRecord.js +18 -225
- package/dist/parse/ciStepRecord.js.map +1 -1
- package/dist/parse/commandRuns.d.ts +0 -39
- package/dist/parse/commandRuns.d.ts.map +1 -1
- package/dist/parse/commandRuns.js +6 -67
- package/dist/parse/commandRuns.js.map +1 -1
- package/dist/parse/cucumber.d.ts +0 -53
- package/dist/parse/cucumber.d.ts.map +1 -1
- package/dist/parse/cucumber.js +42 -146
- package/dist/parse/cucumber.js.map +1 -1
- package/dist/parse/discoveryScope.d.ts +1 -46
- package/dist/parse/discoveryScope.d.ts.map +1 -1
- package/dist/parse/discoveryScope.js +2 -57
- package/dist/parse/discoveryScope.js.map +1 -1
- package/dist/parse/fitnessCitations.d.ts +1 -72
- package/dist/parse/fitnessCitations.d.ts.map +1 -1
- package/dist/parse/fitnessCitations.js +3 -55
- package/dist/parse/fitnessCitations.js.map +1 -1
- package/dist/parse/reconcilerSteps.d.ts +0 -46
- package/dist/parse/reconcilerSteps.d.ts.map +1 -1
- package/dist/parse/reconcilerSteps.js +2 -64
- package/dist/parse/reconcilerSteps.js.map +1 -1
- package/dist/parse/runningFitnessFunctions.d.ts +9 -0
- package/dist/parse/runningFitnessFunctions.d.ts.map +1 -0
- package/dist/parse/runningFitnessFunctions.js +57 -0
- package/dist/parse/runningFitnessFunctions.js.map +1 -0
- package/dist/parse/scenarioCodeErrors.d.ts +11 -0
- package/dist/parse/scenarioCodeErrors.d.ts.map +1 -0
- package/dist/parse/scenarioCodeErrors.js +78 -0
- package/dist/parse/scenarioCodeErrors.js.map +1 -0
- package/dist/parse/scenarios.d.ts +3 -228
- package/dist/parse/scenarios.d.ts.map +1 -1
- package/dist/parse/scenarios.js +20 -457
- package/dist/parse/scenarios.js.map +1 -1
- package/dist/parse/stepAccounting.d.ts +0 -46
- package/dist/parse/stepAccounting.d.ts.map +1 -1
- package/dist/parse/stepAccounting.js +1 -55
- package/dist/parse/stepAccounting.js.map +1 -1
- package/dist/parse/stepExclusions.d.ts +0 -47
- package/dist/parse/stepExclusions.d.ts.map +1 -1
- package/dist/parse/stepExclusions.js +2 -50
- package/dist/parse/stepExclusions.js.map +1 -1
- package/dist/parse/stepNames.d.ts +0 -27
- package/dist/parse/stepNames.d.ts.map +1 -1
- package/dist/parse/stepNames.js +0 -27
- package/dist/parse/stepNames.js.map +1 -1
- package/dist/parse/targetCorpus.d.ts +1 -78
- package/dist/parse/targetCorpus.d.ts.map +1 -1
- package/dist/parse/targetCorpus.js +4 -46
- package/dist/parse/targetCorpus.js.map +1 -1
- package/dist/parse/targetManifest.d.ts +8 -146
- package/dist/parse/targetManifest.d.ts.map +1 -1
- package/dist/parse/targetManifest.js +48 -198
- package/dist/parse/targetManifest.js.map +1 -1
- package/dist/parse/vitest.d.ts +0 -60
- package/dist/parse/vitest.d.ts.map +1 -1
- package/dist/parse/vitest.js +4 -83
- package/dist/parse/vitest.js.map +1 -1
- package/dist/provenance/provenance.d.ts +2 -110
- package/dist/provenance/provenance.d.ts.map +1 -1
- package/dist/provenance/provenance.js +2 -58
- package/dist/provenance/provenance.js.map +1 -1
- package/dist/render/behaviouralRunners.d.ts +0 -29
- package/dist/render/behaviouralRunners.d.ts.map +1 -1
- package/dist/render/behaviouralRunners.js +6 -69
- package/dist/render/behaviouralRunners.js.map +1 -1
- package/dist/render/configurationNotRead.d.ts +3 -0
- package/dist/render/configurationNotRead.d.ts.map +1 -0
- package/dist/render/configurationNotRead.js +17 -0
- package/dist/render/configurationNotRead.js.map +1 -0
- package/dist/render/discoveryScope.d.ts +0 -37
- package/dist/render/discoveryScope.d.ts.map +1 -1
- package/dist/render/discoveryScope.js +3 -39
- package/dist/render/discoveryScope.js.map +1 -1
- package/dist/render/evidenceGrid.d.ts +1 -35
- package/dist/render/evidenceGrid.d.ts.map +1 -1
- package/dist/render/evidenceGrid.js +21 -103
- package/dist/render/evidenceGrid.js.map +1 -1
- package/dist/render/excludedSteps.d.ts +0 -26
- package/dist/render/excludedSteps.d.ts.map +1 -1
- package/dist/render/excludedSteps.js +4 -32
- package/dist/render/excludedSteps.js.map +1 -1
- package/dist/render/fitnessFunctions.d.ts +3 -0
- package/dist/render/fitnessFunctions.d.ts.map +1 -0
- package/dist/render/fitnessFunctions.js +12 -0
- package/dist/render/fitnessFunctions.js.map +1 -0
- package/dist/render/json.d.ts +0 -11
- package/dist/render/json.d.ts.map +1 -1
- package/dist/render/json.js +0 -11
- package/dist/render/json.js.map +1 -1
- package/dist/render/markdown.d.ts +1 -55
- package/dist/render/markdown.d.ts.map +1 -1
- package/dist/render/markdown.js +128 -467
- package/dist/render/markdown.js.map +1 -1
- package/dist/render/provenanceSection.d.ts +0 -22
- package/dist/render/provenanceSection.d.ts.map +1 -1
- package/dist/render/provenanceSection.js +10 -53
- package/dist/render/provenanceSection.js.map +1 -1
- package/dist/render/reconcilerSteps.d.ts +0 -25
- package/dist/render/reconcilerSteps.d.ts.map +1 -1
- package/dist/render/reconcilerSteps.js +5 -30
- package/dist/render/reconcilerSteps.js.map +1 -1
- package/dist/render/runVerdict.d.ts +0 -38
- package/dist/render/runVerdict.d.ts.map +1 -1
- package/dist/render/runVerdict.js +62 -129
- package/dist/render/runVerdict.js.map +1 -1
- package/dist/render/scenarioCodeErrorsSection.d.ts +3 -0
- package/dist/render/scenarioCodeErrorsSection.d.ts.map +1 -0
- package/dist/render/scenarioCodeErrorsSection.js +45 -0
- package/dist/render/scenarioCodeErrorsSection.js.map +1 -0
- package/dist/render/stepAccounting.d.ts +0 -36
- package/dist/render/stepAccounting.d.ts.map +1 -1
- package/dist/render/stepAccounting.js +5 -49
- package/dist/render/stepAccounting.js.map +1 -1
- package/dist/render/testVolume.d.ts +0 -25
- package/dist/render/testVolume.d.ts.map +1 -1
- package/dist/render/testVolume.js +4 -35
- package/dist/render/testVolume.js.map +1 -1
- package/package.json +4 -1
- package/dist/domain/checkCharacteristics.d.ts +0 -88
- package/dist/domain/checkCharacteristics.d.ts.map +0 -1
- package/dist/domain/checkCharacteristics.js +0 -109
- package/dist/domain/checkCharacteristics.js.map +0 -1
- package/dist/domain/fitnessChecks.d.ts +0 -79
- package/dist/domain/fitnessChecks.d.ts.map +0 -1
- package/dist/domain/fitnessChecks.js +0 -81
- package/dist/domain/fitnessChecks.js.map +0 -1
- package/dist/domain/qualityCheckFaultMessages.d.ts +0 -43
- package/dist/domain/qualityCheckFaultMessages.d.ts.map +0 -1
- package/dist/domain/qualityCheckFaultMessages.js +0 -38
- package/dist/domain/qualityCheckFaultMessages.js.map +0 -1
- package/dist/lib/featureCode.d.ts +0 -21
- package/dist/lib/featureCode.d.ts.map +0 -1
- package/dist/lib/featureCode.js +0 -24
- package/dist/lib/featureCode.js.map +0 -1
- package/dist/parse/corpusCodeFaults.d.ts +0 -76
- package/dist/parse/corpusCodeFaults.d.ts.map +0 -1
- package/dist/parse/corpusCodeFaults.js +0 -121
- package/dist/parse/corpusCodeFaults.js.map +0 -1
- package/dist/parse/corpusFaults.d.ts +0 -124
- package/dist/parse/corpusFaults.d.ts.map +0 -1
- package/dist/parse/corpusFaults.js +0 -72
- package/dist/parse/corpusFaults.js.map +0 -1
- package/dist/parse/corpusGrammarFaults.d.ts +0 -71
- package/dist/parse/corpusGrammarFaults.d.ts.map +0 -1
- package/dist/parse/corpusGrammarFaults.js +0 -292
- package/dist/parse/corpusGrammarFaults.js.map +0 -1
- package/dist/parse/runningStaticChecks.d.ts +0 -125
- package/dist/parse/runningStaticChecks.d.ts.map +0 -1
- package/dist/parse/runningStaticChecks.js +0 -316
- package/dist/parse/runningStaticChecks.js.map +0 -1
- package/dist/render/staticChecks.d.ts +0 -23
- package/dist/render/staticChecks.d.ts.map +0 -1
- package/dist/render/staticChecks.js +0 -69
- package/dist/render/staticChecks.js.map +0 -1
package/dist/parse/scenarios.js
CHANGED
|
@@ -1,360 +1,65 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The SCENARIO reader — parse spec-controller's own `features/**\/*.feature` source
|
|
3
|
-
* into evidence obligations: per scenario, `{ scnId, evidenceObligations }`, with
|
|
4
|
-
* each (kind, level) drawn from the scenario's evidence tags (@unit → runtime/unit,
|
|
5
|
-
* @integration → runtime/integration, @e2e → runtime/e2e, @performance →
|
|
6
|
-
* runtime/performance — the evidence-obligation reading).
|
|
7
|
-
*
|
|
8
|
-
* One of the three separated inputs to the reconciler (obligations / observations /
|
|
9
|
-
* static checks) — the embryonic obligation-side adapter, deliberately not a registry (v1).
|
|
10
|
-
*
|
|
11
|
-
* Approach: scan TAG LINES (a line whose first non-blank char is `@` and whose
|
|
12
|
-
* every whitespace-separated token is a tag) for an @SCN-<FFF>-<NNN> id and any
|
|
13
|
-
* co-located evidence-level tags. A scenario's @SCN id and its level tags sit on
|
|
14
|
-
* the same accumulated tag block immediately above the Scenario keyword, so a tag
|
|
15
|
-
* line carrying an @SCN id contributes that scenario's evidenceObligations from the level
|
|
16
|
-
* tags found across the contiguous tag block.
|
|
17
|
-
*
|
|
18
|
-
* The `lint` quality-check is raised by a scenario's REGISTERED bare check tag, STEPS OR NONE
|
|
19
|
-
* (`fitnessObligationsOf`, @SCN-LNT-006): the tag says which axis a scenario is on and the steps say
|
|
20
|
-
* nothing about it (3F-3115). The retired `@lint=<guard>` form — where the scenario
|
|
21
|
-
* named a runnable npm script and the run was matched back to it BY NAME — raises nothing
|
|
22
|
-
* (@SCN-LNT-007): it supplies no citation, so anything it raised could never be credited under
|
|
23
|
-
* the one posting rule and would read `missing` for ever. The form is inert in the READER, which
|
|
24
|
-
* is what makes it retired rather than merely unused.
|
|
25
|
-
*
|
|
26
|
-
* Parent: @SCN-LDG-001.
|
|
27
|
-
*/
|
|
28
1
|
import { AstBuilder, GherkinClassicTokenMatcher, Parser } from "@cucumber/gherkin";
|
|
29
2
|
import { IdGenerator } from "@cucumber/messages";
|
|
30
3
|
import { bareTerm } from "../lib/bareTerm.js";
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
* (the `@` stripped) that DEFERS an obligation to a later slice. Exact-match keyed, so the
|
|
35
|
-
* `pending` suffix is significant: `integrationpending` is NOT `integration`, and an
|
|
36
|
-
* unrecognised `<x>pending` (or bare `pending`) is absent from the map → ignored. Unlike
|
|
37
|
-
* `TAG_TO_QUALITY_CHECK`, this covers ALL FIVE quality-checks including `lint` (a pending
|
|
38
|
-
* lint obligation is one-sided — no `staticCheck` payload).
|
|
39
|
-
*/
|
|
4
|
+
import { SCN_ID_SOURCE } from "../domain/featureCode.js";
|
|
5
|
+
import { CORE_MESSAGES, CoreMessage } from "../domain/messages.js";
|
|
6
|
+
export const SCN_CODE = new RegExp(`^${SCN_ID_SOURCE}$`);
|
|
40
7
|
const PENDING_TAG_TO_QUALITY_CHECK = {
|
|
41
|
-
|
|
8
|
+
fitnesspending: "fitness",
|
|
42
9
|
unitpending: "unit",
|
|
43
10
|
integrationpending: "integration",
|
|
44
11
|
e2epending: "e2e",
|
|
45
12
|
performancepending: "performance",
|
|
46
13
|
};
|
|
47
|
-
/**
|
|
48
|
-
* Recognise a `<quality-check>pending` tag (evidence-manifesto §11B) — return its deferred
|
|
49
|
-
* quality-check, or `null` when the bare tag is not one of the five recognised `<qc>pending`
|
|
50
|
-
* (a bare tier tag, an unknown `<x>pending`, or bare `pending`). The pure per-tag helper
|
|
51
|
-
* `parseScenarios` uses to derive a pending obligation.
|
|
52
|
-
*/
|
|
53
14
|
export function pendingQualityCheck(tag) {
|
|
54
15
|
return PENDING_TAG_TO_QUALITY_CHECK[tag] ?? null;
|
|
55
16
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Every recognised `<quality-check>pending` spelling, derived from the map above rather than
|
|
58
|
-
* listed again (@SCN-STG-002, 3F-3302).
|
|
59
|
-
*
|
|
60
|
-
* WHY A LIST AND NOT JUST THE PREDICATE. `pendingQualityCheck` answers "is THIS tag one", which
|
|
61
|
-
* is all an obligation needs. The tag-grammar rule needs the other direction too — the words to
|
|
62
|
-
* measure an unrecognised tag AGAINST, so it can name the tier a typo resembles — and a list
|
|
63
|
-
* written out over there would agree with this map by diligence and then drift the first time a
|
|
64
|
-
* quality-check is added.
|
|
65
|
-
*/
|
|
66
|
-
export const PENDING_QUALITY_CHECK_TAGS = Object.keys(PENDING_TAG_TO_QUALITY_CHECK);
|
|
67
17
|
const TAG_TO_QUALITY_CHECK = {
|
|
68
18
|
unit: "unit",
|
|
69
19
|
integration: "integration",
|
|
70
20
|
e2e: "e2e",
|
|
71
21
|
performance: "performance",
|
|
72
22
|
};
|
|
73
|
-
/**
|
|
74
|
-
* The bare tags that name a RUNTIME evidence tier, derived from the map above (@SCN-STG-002,
|
|
75
|
-
* 3F-3302). Exported for the same reason as the pending list beside it, and kept beneath the map
|
|
76
|
-
* it reads so the two can never be edited apart.
|
|
77
|
-
*/
|
|
78
|
-
export const RUNTIME_QUALITY_CHECK_TAGS = Object.keys(TAG_TO_QUALITY_CHECK);
|
|
79
|
-
/** Is a trimmed line a genuine Gherkin TAG LINE? Return its bare tags, else null. */
|
|
80
23
|
function tagLineTags(line) {
|
|
81
|
-
if (!line.startsWith("@"))
|
|
82
|
-
return null;
|
|
83
24
|
const tokens = line.split(/\s+/);
|
|
84
25
|
if (!tokens.every((t) => t.startsWith("@")))
|
|
85
26
|
return null;
|
|
86
27
|
return tokens.map((t) => t.slice(1));
|
|
87
28
|
}
|
|
88
|
-
|
|
89
|
-
* `@SCN-FFF-NNN` — a raw scenario-id occurrence ANYWHERE in the source (tag line OR
|
|
90
|
-
* the non-tag context — prose, comments, step text — the tag-line parser ignores).
|
|
91
|
-
* The global flag counts every occurrence (@SCN-RPT-008).
|
|
92
|
-
*/
|
|
93
|
-
const SCN_OCCURRENCE = /@SCN-[A-Z0-9]+-\d+/g;
|
|
94
|
-
/**
|
|
95
|
-
* Count every raw `@SCN-FFF-NNN` occurrence across the WHOLE source — including the
|
|
96
|
-
* non-tag-line context (prose, comments, step text) the tag-line `parseScenarios`
|
|
97
|
-
* deliberately ignores. A sibling read over the same source; `parseScenarios` is
|
|
98
|
-
* unchanged. Each scenario contributes exactly one tag-line occurrence, so
|
|
99
|
-
* the delta against `parseScenarios(...).length` is precisely the ids seen in non-tag
|
|
100
|
-
* context.
|
|
101
|
-
*/
|
|
29
|
+
const SCN_OCCURRENCE = new RegExp(`@${SCN_ID_SOURCE}`, "g");
|
|
102
30
|
export function countScnOccurrences(source) {
|
|
103
31
|
return (source.match(SCN_OCCURRENCE) ?? []).length;
|
|
104
32
|
}
|
|
105
|
-
/**
|
|
106
|
-
* The PROSE-ONLY @SCN codes (@SCN-RPT-015) — codes that appear in non-tag
|
|
107
|
-
* context (prose / comments / step text) but are NEVER an @SCN tag ANYWHERE in the
|
|
108
|
-
* corpus: dangling references. A CROSS-CORPUS set difference `proseCodes − tagCodes`
|
|
109
|
-
* over ALL sources (unique, sorted): per source each line is inspected — a tag line
|
|
110
|
-
* contributes its @SCN tokens to the TAG set; any other line contributes its @SCN
|
|
111
|
-
* matches (the leading `@` stripped) to the PROSE set. The union across files is
|
|
112
|
-
* load-bearing: a code tagged in one file but mentioned in prose in another is NOT
|
|
113
|
-
* prose-only. Distinct from `countScnOccurrences`'s raw count (occurrences, not unique
|
|
114
|
-
* dangling codes). The bare code (e.g. `SCN-FOO-001`) is its own locator.
|
|
115
|
-
*/
|
|
116
|
-
export function proseOnlyCodes(sources) {
|
|
117
|
-
const tag = new Set();
|
|
118
|
-
const prose = new Set();
|
|
119
|
-
for (const source of sources) {
|
|
120
|
-
for (const rawLine of source.split(/\r?\n/)) {
|
|
121
|
-
const line = rawLine.trim();
|
|
122
|
-
const tags = line === "" ? null : tagLineTags(line);
|
|
123
|
-
if (tags) {
|
|
124
|
-
for (const t of tags)
|
|
125
|
-
if (SCN_CODE.test(t))
|
|
126
|
-
tag.add(t);
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
for (const m of line.matchAll(SCN_OCCURRENCE))
|
|
130
|
-
prose.add(m[0].slice(1));
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return [...prose].filter((code) => !tag.has(code)).sort();
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* A Gherkin scenario-header line: `Scenario:` / `Scenario Outline:` / `Scenario
|
|
138
|
-
* Template:` / `Example:` (the synonym for Scenario), capturing the name after the
|
|
139
|
-
* colon. The colon is anchored immediately after the keyword, so `Examples:` (plural —
|
|
140
|
-
* the Scenario Outline DATA TABLE, not a scenario) does NOT match. Longer keywords lead
|
|
141
|
-
* the alternation for clarity.
|
|
142
|
-
*/
|
|
143
33
|
const SCENARIO_HEADER = /^(?:Scenario Outline|Scenario Template|Scenario|Example):\s*(.*)$/;
|
|
144
|
-
/**
|
|
145
|
-
* Parse the UNTAGGED scenarios — Gherkin scenario headers whose preceding contiguous
|
|
146
|
-
* tag block carries no `@SCN` id (@SCN-RPT-014). Mirrors `parseScenarios`'s
|
|
147
|
-
* tag-block accumulation: a tag line accumulates the block; any non-tag line closes it.
|
|
148
|
-
* At each scenario header, the just-accumulated block is checked for an `@SCN` — if it
|
|
149
|
-
* has none, the scenario is untagged (returns its name). The obligation-side counterpart
|
|
150
|
-
* to the evidenceObservations aggregate's anomaly terms: a scenario with no evidence anchor.
|
|
151
|
-
*/
|
|
152
34
|
export function parseUntaggedScenarios(source) {
|
|
153
35
|
const untagged = [];
|
|
154
36
|
let blockTags = [];
|
|
155
37
|
for (const rawLine of source.split(/\r?\n/)) {
|
|
156
38
|
const line = rawLine.trim();
|
|
157
|
-
const tags =
|
|
39
|
+
const tags = tagLineTags(line);
|
|
158
40
|
if (tags) {
|
|
159
41
|
blockTags.push(...tags);
|
|
160
42
|
continue;
|
|
161
43
|
}
|
|
162
44
|
const header = SCENARIO_HEADER.exec(line);
|
|
163
45
|
if (header && !blockTags.some((t) => SCN_CODE.test(t))) {
|
|
164
|
-
untagged.push(header[1]
|
|
46
|
+
untagged.push(header[1]);
|
|
165
47
|
}
|
|
166
|
-
// Any non-tag line (a scenario header, a step, a blank, Feature:/Rule:) closes the block.
|
|
167
48
|
blockTags = [];
|
|
168
49
|
}
|
|
169
50
|
return untagged;
|
|
170
51
|
}
|
|
171
|
-
/**
|
|
172
|
-
* THE FITNESS OBLIGATIONS a scenario's tags raise (@SCN-LNT-006) — one per REGISTERED bare check
|
|
173
|
-
* tag it carries, whether or not the scenario carries steps.
|
|
174
|
-
*
|
|
175
|
-
* THE TECHNIQUE LEAVES THE TAG. Under name-match the DEBIT cited: a scenario carried
|
|
176
|
-
* `@lint=<handle>` and a run was matched back to it by name, so an obligation could only be raised
|
|
177
|
-
* by naming a runnable script — which put one technique in front of a whole class of fitness
|
|
178
|
-
* functions, and is why `complexity`, `typecheck` and `vocab` all had to spell themselves
|
|
179
|
-
* `lint:something` to be seen at all. A bare tag drops it: `@complexity` is a flat peer of `@unit`
|
|
180
|
-
* exactly as `@unit` is a flat peer of `@integration`. There is no `@behavioural=unit`, so there is
|
|
181
|
-
* no `@fitness=complexity` (canon 2026-08-07, the bare-tags Correction).
|
|
182
|
-
*
|
|
183
|
-
* THE TAG IS THE DISCRIMINATOR, AND THE STEPS ARE NOT (3F-3115). A scenario carrying a registered
|
|
184
|
-
* bare check owes that check from the row that carries it; a scenario carrying a tier tag owes its
|
|
185
|
-
* tier. Steps say how a scenario is WRITTEN, not which axis it is ON, so a fitness scenario handed
|
|
186
|
-
* a runnable example keeps the characteristic it was written to hold instead of swapping axes.
|
|
187
|
-
*
|
|
188
|
-
* THE `stepless` CONDITION THAT USED TO STAND HERE WAS A PROXY, AND IT READ THE WRONG SIGNAL —
|
|
189
|
-
* having nothing to exemplify is why a fitness scenario usually carries no steps, a correlate of
|
|
190
|
-
* being non-behavioural rather than the thing itself. The CREDIT side never read it: the citation
|
|
191
|
-
* seam has always reached a stepped row, so the debit alone stopped short and such a row produced a
|
|
192
|
-
* credit with no obligation to post to (3F-3092). Removing the condition removes that asymmetry;
|
|
193
|
-
* no compensating rule is added on the credit side, and none is needed.
|
|
194
|
-
*
|
|
195
|
-
* AND THE FIELD THAT OUTLIVED THE CONDITION IS GONE WITH IT (3F-3369). `TaggedScenario` carried a
|
|
196
|
-
* `stepless` boolean on after the rule stopped reading it, kept by a reason that was wrong twice
|
|
197
|
-
* (3F-3134): it named `parse/scnTags.ts` as the surviving reader, which is not a path in this
|
|
198
|
-
* repository, and the corpus check it meant computed its own steplessness off its own line parser
|
|
199
|
-
* and never read this one. Both rules that reason named read the tag instead (@SCN-STG-005, and
|
|
200
|
-
* the one-check rule until it left with the measured axis; 3F-3126, 3F-3516). So nothing asked
|
|
201
|
-
* the walk for a scenario's SHAPE, and the walk stopped answering: steplessness is derived
|
|
202
|
-
* nowhere in this tree, and a scenario's axis is its tag.
|
|
203
|
-
*
|
|
204
|
-
* SUPPLIED, NOT INFERRED. `checkTags` is the caller's set of recognised check tags, taken as
|
|
205
|
-
* data. Without it every unrecognised tag would be a candidate check and `@smoke` would owe one;
|
|
206
|
-
* with a prefix heuristic instead, `typecheck` would be missed, which is the reading 3F-2495 already
|
|
207
|
-
* disproved on the discovery side. An empty set raises nothing, so this is inert on a corpus
|
|
208
|
-
* that has not been swept.
|
|
209
|
-
*
|
|
210
|
-
* `seen` CARRIES THE CHECKS ALREADY RAISED, and is mutated here: a scenario's effective tags are
|
|
211
|
-
* its own plus its `Rule:`'s and its `Feature:`'s (@SCN-LDG-020), so one check can reach one
|
|
212
|
-
* scenario twice and is owed once. Two obligations for one check would leave the second `missing`
|
|
213
|
-
* for ever — one run is one credit and can cite one `@SCN`.
|
|
214
|
-
*/
|
|
215
|
-
function fitnessObligationsOf(tags, checkTags, seen) {
|
|
216
|
-
const registered = new Set(checkTags);
|
|
217
|
-
const raised = [];
|
|
218
|
-
for (const tag of tags) {
|
|
219
|
-
if (!registered.has(tag) || seen.has(tag))
|
|
220
|
-
continue;
|
|
221
|
-
seen.add(tag);
|
|
222
|
-
raised.push({ qualityCheck: "lint", staticCheck: tag });
|
|
223
|
-
}
|
|
224
|
-
return raised;
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* The one word a CONVERTED check's scenario carries — the axis, and nothing about the subject.
|
|
228
|
-
*
|
|
229
|
-
* It is a literal rather than a registered tag because it names no characteristic: `checkTags` is
|
|
230
|
-
* the answer to "which words are checks here", and this word is the answer to "which axis is this
|
|
231
|
-
* scenario on", which is the same question `unit` and `integration` answer for the other axis. A
|
|
232
|
-
* target does not get to spell it differently for the reason nobody spells `@unit` differently.
|
|
233
|
-
*/
|
|
234
52
|
export const FITNESS_AXIS_TAG = "fitness";
|
|
235
|
-
|
|
236
|
-
* The obligation a CONVERTED check's scenario raises (@SCN-LNT-018) — the characteristic its
|
|
237
|
-
* CONFIGURED ROW names, once.
|
|
238
|
-
*
|
|
239
|
-
* THE TAG NAMES THE AXIS AND THE ROW NAMES THE SUBJECT. A bare characteristic tag answered both at
|
|
240
|
-
* once; the tier tags answer only the first, and nobody mints `@unit-parser`. So a converted
|
|
241
|
-
* scenario carries `@fitness` alone and the characteristic is looked up by the scenario's own
|
|
242
|
-
* `@SCN` — which is the row's KEY, so a row cannot name one scenario and be read against another.
|
|
243
|
-
*
|
|
244
|
-
* NOT A SECOND OBLIGATION SHAPE. What comes back is the same
|
|
245
|
-
* `{ qualityCheck: "lint", staticCheck: <characteristic> }` the registered-tag arm raises, so the
|
|
246
|
-
* pair key, the reconciler's static arm and the roll-up are untouched: only where the word came
|
|
247
|
-
* from changed.
|
|
248
|
-
*
|
|
249
|
-
* NO REGISTRY HOP, and that is what conversion retires. An unconverted static check is discovered
|
|
250
|
-
* as a script handle, and a handle does not know what it is for — hence the (now-retired)
|
|
251
|
-
* registry, and hence the corpus lookup behind it. This route reads the citation off the row
|
|
252
|
-
* rather than resolving it onto one.
|
|
253
|
-
*
|
|
254
|
-
* `seen` IS THE ARM ABOVE'S OWN SET, and shared deliberately. A check is owed once however it was
|
|
255
|
-
* named: the axis tag can reach one scenario twice through its `Rule:` and its `Feature:`
|
|
256
|
-
* (@SCN-LDG-020), and a row whose characteristic a bare tag on the same scenario already raised
|
|
257
|
-
* owes nothing further. Two obligations for one characteristic would leave the second `missing`
|
|
258
|
-
* for ever, since one run is one credit and can cite one `@SCN`.
|
|
259
|
-
*/
|
|
260
|
-
function convertedFitnessObligationsOf(tags, fitnessChecks, seen, scnId) {
|
|
53
|
+
function convertedFitnessObligationsOf(tags) {
|
|
261
54
|
if (!tags.includes(FITNESS_AXIS_TAG))
|
|
262
55
|
return [];
|
|
263
|
-
|
|
264
|
-
if (row === undefined || seen.has(row.characteristic))
|
|
265
|
-
return [];
|
|
266
|
-
seen.add(row.characteristic);
|
|
267
|
-
return [{ qualityCheck: "lint", staticCheck: row.characteristic }];
|
|
56
|
+
return [{ qualityCheck: "fitness" }];
|
|
268
57
|
}
|
|
269
|
-
|
|
270
|
-
* The scenarios ON the fitness axis that no configured row NAMES (@SCN-LNT-020) — a corpus that has
|
|
271
|
-
* half-converted a check: the tag moved and the row was never written.
|
|
272
|
-
*
|
|
273
|
-
* IT RAISES NOTHING AND THAT IS NOT NEGOTIABLE. Such a scenario has said which axis it is on and
|
|
274
|
-
* then said nothing about what it asserts; there is no characteristic to raise an obligation FOR,
|
|
275
|
-
* and reaching for the nearest word is the near-match courtesy the portfolio roster already
|
|
276
|
-
* refuses. So `convertedFitnessObligationsOf` above answers the empty list, and this reads the same
|
|
277
|
-
* two facts — the axis tag, and the row's absence — to say WHO.
|
|
278
|
-
*
|
|
279
|
-
* THE RUN ALREADY REDS ON IT, through no rule of this function's. A converted check's scenario
|
|
280
|
-
* carries the axis tag and its `@SCN` and nothing else, so a scenario no row names reconciles to
|
|
281
|
-
* zero rows on BOTH sides and is out of balance through the degenerate `both-missing` item — canon's
|
|
282
|
-
* row for exactly this profile (Scenario Exists, Evidence Obligation None, Evidence Observation
|
|
283
|
-
* None). No outcome is minted here, and none is needed.
|
|
284
|
-
*
|
|
285
|
-
* WHAT IS ADDED IS THE SENTENCE. That degenerate item cannot say WHY: its own gloss is about a
|
|
286
|
-
* scenario carrying no `@SCN`, and this one carries one. So the run NAMES these, count and id, where
|
|
287
|
-
* it already names the other corpus-shape faults — facts only, no prescribed cure, and the reader
|
|
288
|
-
* is left with the one remedy there is, which is to write the row.
|
|
289
|
-
*
|
|
290
|
-
* IT READS THE WALK IT IS HANDED rather than taking a source of its own, and it reads the same
|
|
291
|
-
* `FITNESS_AXIS_TAG` and the same registry the obligation rule reads. A second walk would be free to
|
|
292
|
-
* disagree about which scenario it is looking at, and a corpus naming one scenario while the rule
|
|
293
|
-
* raised nothing for another is precisely the disagreement `parseTaggedScenarios` was extracted to
|
|
294
|
-
* foreclose.
|
|
295
|
-
*
|
|
296
|
-
* NAMED ONCE however many of a scenario's effective tags name the axis (@SCN-LDG-020) — naming it
|
|
297
|
-
* twice would put one remedy on the report twice and make the count say there are two
|
|
298
|
-
* half-converted checks where there is one.
|
|
299
|
-
*/
|
|
300
|
-
export function unconfiguredFitnessScenarios(scenarios, fitnessChecks) {
|
|
301
|
-
const unconfigured = [];
|
|
302
|
-
for (const scenario of scenarios) {
|
|
303
|
-
if (!scenario.tags.includes(FITNESS_AXIS_TAG))
|
|
304
|
-
continue;
|
|
305
|
-
if (fitnessChecks.has(scenario.scnId))
|
|
306
|
-
continue;
|
|
307
|
-
if (!unconfigured.includes(scenario.scnId))
|
|
308
|
-
unconfigured.push(scenario.scnId);
|
|
309
|
-
}
|
|
310
|
-
return unconfigured;
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* THE CONFIGURED ROWS THE CORPUS CARRIES NO SCENARIO FOR (3F-3472, @SCN-LNT-027) — the mirror of
|
|
314
|
-
* `unconfiguredFitnessScenarios` directly above, in MANIFEST order.
|
|
315
|
-
*
|
|
316
|
-
* THE RUN DOES NOT ALREADY RED ON IT, WHICH IS THE WHOLE DIFFERENCE BETWEEN THE TWO. Its mirror
|
|
317
|
-
* adds only a sentence, because a scenario no row names already reconciles to zero rows on both
|
|
318
|
-
* sides and is out of balance through the degenerate item. A row no scenario names raised NOTHING:
|
|
319
|
-
* the obligations travel with the scenarios, so a row with no scenario contributed a characteristic
|
|
320
|
-
* nobody asked for and the run read balanced over a check that was declared and never specified.
|
|
321
|
-
* `double-entry-manifesto.md` names that shape exactly — a ledger catches a credit that never
|
|
322
|
-
* arrived and is blind to a debit that was never raised.
|
|
323
|
-
*
|
|
324
|
-
* IT READS THE WALK IT IS HANDED, for its mirror's reason: a second walk would be free to disagree
|
|
325
|
-
* about which scenarios the corpus holds, and a row raised against a corpus the obligations were
|
|
326
|
-
* not taken from is the phantom-row fault (@SCN-LNT-009) reached from the manifest side.
|
|
327
|
-
*
|
|
328
|
-
* EVERY `@SCN`-CARRYING SCENARIO COUNTS, NOT THE `@fitness` ONES ALONE. The claim is that the
|
|
329
|
-
* corpus carries no scenario for the row — so a scenario carrying the row's code and saying nothing
|
|
330
|
-
* about the fitness axis is still a scenario somebody wrote under that code, and minting a debit
|
|
331
|
-
* beside it would report a check nobody has specified where one has been started.
|
|
332
|
-
*/
|
|
333
|
-
export function unspecifiedFitnessRows(scenarios, fitnessChecks) {
|
|
334
|
-
const carried = new Set(scenarios.map((scenario) => scenario.scnId));
|
|
335
|
-
const unspecified = [];
|
|
336
|
-
for (const [scnId, row] of fitnessChecks) {
|
|
337
|
-
if (carried.has(scnId))
|
|
338
|
-
continue;
|
|
339
|
-
unspecified.push({ scnId, characteristic: row.characteristic });
|
|
340
|
-
}
|
|
341
|
-
return unspecified;
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* Derive a scenario's evidence obligations from its EFFECTIVE tags — its own PLUS everything it
|
|
345
|
-
* inherits from its `Feature:` and any enclosing `Rule:` (@SCN-LDG-020). Unchanged in substance
|
|
346
|
-
* from the tag-block reading it replaces; what changed is WHICH tags reach it.
|
|
347
|
-
*/
|
|
348
|
-
function obligationsFromTags(tags, deferralTags, checkTags, scnId, fitnessChecks) {
|
|
58
|
+
function obligationsFromTags(tags, deferralTags) {
|
|
349
59
|
const evidenceObligations = [];
|
|
350
60
|
const seenQualityChecks = new Set();
|
|
351
61
|
const seenPending = new Set();
|
|
352
|
-
const seenChecks = new Set();
|
|
353
62
|
for (const t of tags) {
|
|
354
|
-
// A `<quality-check>pending` tag derives a DEFERRED, one-sided obligation
|
|
355
|
-
// `{ qualityCheck, pending: true }` (no `staticCheck` payload). Tracked in its own set so
|
|
356
|
-
// it is neither blocked by nor blocks a bare tier of the same quality-check, and
|
|
357
|
-
// recognised SEPARATELY from the bare tier tag (the `pending` suffix is significant).
|
|
358
63
|
const pendingCheck = pendingQualityCheck(t);
|
|
359
64
|
if (pendingCheck && !seenPending.has(pendingCheck)) {
|
|
360
65
|
seenPending.add(pendingCheck);
|
|
@@ -368,30 +73,9 @@ function obligationsFromTags(tags, deferralTags, checkTags, scnId, fitnessChecks
|
|
|
368
73
|
continue;
|
|
369
74
|
}
|
|
370
75
|
}
|
|
371
|
-
|
|
372
|
-
// below, so a deferred fitness scenario defers like any other rather than escaping through a later
|
|
373
|
-
// arm. `seenChecks` keeps a check from being owed twice however many of a scenario's effective
|
|
374
|
-
// tags name it.
|
|
375
|
-
evidenceObligations.push(...fitnessObligationsOf(tags, checkTags, seenChecks),
|
|
376
|
-
// The CONVERTED route (@SCN-LNT-018), on the same `seen` set and after the registered-tag arm:
|
|
377
|
-
// a characteristic is owed once whichever of the two named it.
|
|
378
|
-
...convertedFitnessObligationsOf(tags, fitnessChecks, seenChecks, scnId));
|
|
379
|
-
// SCENARIO-SCOPE community deferral (@SCN-PND-016): when the tag block carries a
|
|
380
|
-
// RECOGNISED community deferral tag (a bare tag ∈ the injected `deferralTags` set —
|
|
381
|
-
// empty by default; the app passes its starter policy ∪ config), the whole scenario is
|
|
382
|
-
// deferred: mark EVERY obligation `pending: true`, overriding its observation-derived
|
|
383
|
-
// outcome. Applied AFTER the
|
|
384
|
-
// obligation list is built, so it composes with the `<qc>pending` recognition and covers
|
|
385
|
-
// every obligation kind (runtime tiers AND the fitness ones). Idempotent on an
|
|
386
|
-
// already-pending obligation.
|
|
76
|
+
evidenceObligations.push(...convertedFitnessObligationsOf(tags));
|
|
387
77
|
if (tags.some((t) => deferralTags.includes(t))) {
|
|
388
78
|
if (evidenceObligations.length === 0) {
|
|
389
|
-
// INTERPRETATION 2 (@SCN-PND-022): a deferred scenario raising ZERO obligations (a
|
|
390
|
-
// bare `@wip` — no evidence tag) synthesises ONE scenario-scope pending obligation:
|
|
391
|
-
// `{ pending: true }` with NO `qualityCheck` (undefined = scenario-scope) and no `staticCheck`.
|
|
392
|
-
// The reconcile partition routes it to one `qualityCheck`-less Pending Item, so the
|
|
393
|
-
// scenario is deferred (pending) — the both-missing guard (fires only on zero pending
|
|
394
|
-
// items) leaves it balanced, not the degenerate both-missing row.
|
|
395
79
|
evidenceObligations.push({ pending: true });
|
|
396
80
|
}
|
|
397
81
|
else {
|
|
@@ -401,15 +85,6 @@ function obligationsFromTags(tags, deferralTags, checkTags, scnId, fitnessChecks
|
|
|
401
85
|
}
|
|
402
86
|
return evidenceObligations;
|
|
403
87
|
}
|
|
404
|
-
/**
|
|
405
|
-
* Parse one feature source into cucumber's own AST, or THROW.
|
|
406
|
-
*
|
|
407
|
-
* An UNPARSEABLE source never yields an empty corpus. Silently returning zero scenarios is the
|
|
408
|
-
* precise shape of the false-green this tool exists to prevent: an empty debit side balances against
|
|
409
|
-
* anything. The app refuses an unreadable feature file at the ingest edge long before this
|
|
410
|
-
* (@SCN-CLI-016: exit 2, halting before any reconcile), so the throw is unreachable in a real run —
|
|
411
|
-
* it is the floor that keeps a future caller from re-opening the hole quietly.
|
|
412
|
-
*/
|
|
413
88
|
function parseFeatureDocument(source) {
|
|
414
89
|
const parser = new Parser(new AstBuilder(IdGenerator.uuid()), new GherkinClassicTokenMatcher());
|
|
415
90
|
try {
|
|
@@ -417,150 +92,38 @@ function parseFeatureDocument(source) {
|
|
|
417
92
|
}
|
|
418
93
|
catch (err) {
|
|
419
94
|
const message = err instanceof Error ? err.message : String(err);
|
|
420
|
-
throw new Error(
|
|
421
|
-
`Reconciling an empty corpus would balance against anything — so this fails loudly ` +
|
|
422
|
-
`rather than silently. Cause: ${message}`);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
/** A blank line, or one carrying only a `#` comment — what a block's extent is trimmed back over. */
|
|
426
|
-
const BLANK_OR_COMMENT = /^\s*(?:#.*)?$/;
|
|
427
|
-
/**
|
|
428
|
-
* Where a Gherkin block STARTS: its first own tag line if it has one, else its keyword line. Own
|
|
429
|
-
* tags only — a tag inherited from an enclosing `Rule:` or from the `Feature:` sits in another
|
|
430
|
-
* block's text, and claiming it here would give two blocks the same lines.
|
|
431
|
-
*/
|
|
432
|
-
function blockStart(block) {
|
|
433
|
-
return Math.min(block.location.line, ...(block.tags ?? []).map((t) => t.location.line));
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* Every block start in the document, ascending — the BOUNDARIES one block's text ends at. Untagged
|
|
437
|
-
* scenarios count: a block's extent has to stop at the next block whether or not that block is one
|
|
438
|
-
* anybody can name.
|
|
439
|
-
*/
|
|
440
|
-
function collectBlockStarts(children, starts) {
|
|
441
|
-
for (const child of children) {
|
|
442
|
-
if (child.rule) {
|
|
443
|
-
starts.push(blockStart(child.rule));
|
|
444
|
-
collectBlockStarts(child.rule.children, starts);
|
|
445
|
-
continue;
|
|
446
|
-
}
|
|
447
|
-
if (child.background)
|
|
448
|
-
starts.push(blockStart(child.background));
|
|
449
|
-
if (child.scenario)
|
|
450
|
-
starts.push(blockStart(child.scenario));
|
|
95
|
+
throw new Error(CORE_MESSAGES[CoreMessage.FeatureSourceNotGherkin](message));
|
|
451
96
|
}
|
|
452
97
|
}
|
|
453
|
-
/**
|
|
454
|
-
* Every block start in the document, ASCENDING — the boundaries `blockEnd` measures against. Read
|
|
455
|
-
* off the SAME parse the tags come from (@SCN-SSM-010): one Gherkin parse, two walks of its
|
|
456
|
-
* children, never a second read of the source.
|
|
457
|
-
*/
|
|
458
|
-
function documentBlockStarts(document) {
|
|
459
|
-
const starts = [];
|
|
460
|
-
collectBlockStarts((document.feature?.children ?? []), starts);
|
|
461
|
-
return starts.sort((a, b) => a - b);
|
|
462
|
-
}
|
|
463
|
-
/**
|
|
464
|
-
* Where the block starting at `start` ENDS: the line before the next boundary, or EOF, trimmed back
|
|
465
|
-
* over trailing blank and comment lines so the gap between two scenarios belongs to neither.
|
|
466
|
-
*/
|
|
467
|
-
function blockEnd(start, starts, lines) {
|
|
468
|
-
const next = starts.find((boundary) => boundary > start);
|
|
469
|
-
let end = Math.min(next !== undefined ? next - 1 : lines.length, lines.length);
|
|
470
|
-
while (end > start && BLANK_OR_COMMENT.test(lines[end - 1] ?? ""))
|
|
471
|
-
end -= 1;
|
|
472
|
-
return end;
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* Read every `@SCN`-carrying scenario with its EFFECTIVE tags — the corpus walk `parseScenarios`
|
|
476
|
-
* is built on, and the same walk any other whole-corpus tag question is answered from.
|
|
477
|
-
*
|
|
478
|
-
* The obligation rule is deliberately NOT applied here: what a scenario TAGS and what it OWES are
|
|
479
|
-
* different questions, and the second is `obligationsFromTags`'. Keeping them apart is what lets
|
|
480
|
-
* the citation seam ask the first without inheriting a reading of the second.
|
|
481
|
-
*
|
|
482
|
-
* WHY THE WALK IS THE AST'S AND NOT A SCAN'S. This was a hand-rolled TAG-LINE SCAN that saw only
|
|
483
|
-
* the contiguous tag block directly above a `Scenario:`. Gherkin does not work that way — a
|
|
484
|
-
* scenario INHERITS the tags of its `Feature:` and of any enclosing `Rule:`. Two bugs followed,
|
|
485
|
-
* and both were false-greens:
|
|
486
|
-
*
|
|
487
|
-
* UNDER-READ. An evidence tier hoisted to the Feature/Rule line — idiomatic, valid Gherkin,
|
|
488
|
-
* exactly what an author does with a tier shared by every scenario beneath — was INVISIBLE. The
|
|
489
|
-
* obligation was never RAISED, so its missing evidence could never reconcile `missing`, and the
|
|
490
|
-
* run read BALANCED (exit 0) while cucumber named a tier nothing proved. Unlike the corrupt-
|
|
491
|
-
* file false-green (3F-1767), this one fires on WELL-WRITTEN files — which makes it likelier.
|
|
492
|
-
*
|
|
493
|
-
* OVER-READ. Any non-tag line flushed the accumulated block, so a tag block above a `Rule:` was
|
|
494
|
-
* emitted AS IF it were a scenario. The corpus did not merely miss scenarios — it INVENTED them.
|
|
495
|
-
*
|
|
496
|
-
* EVERY tag inherits, `@SCN` included: parity with cucumber is the goal, and excluding one would
|
|
497
|
-
* invent a rule cucumber does not have. A hoisted `@SCN` therefore gives every scenario beneath it
|
|
498
|
-
* the same id — a corpus-authoring fault, but a VISIBLE one (whether it should red is a deferred
|
|
499
|
-
* policy question, 3F-1774's sibling).
|
|
500
|
-
*
|
|
501
|
-
* An UNPARSEABLE source THROWS, from `parseFeatureDocument` — it never yields an empty corpus, for
|
|
502
|
-
* the reason recorded there.
|
|
503
|
-
*/
|
|
504
98
|
export function parseTaggedScenarios(source) {
|
|
505
|
-
const
|
|
99
|
+
const { feature } = parseFeatureDocument(source);
|
|
100
|
+
if (feature === undefined)
|
|
101
|
+
return [];
|
|
506
102
|
const tagged = [];
|
|
507
|
-
// The parser tokenises, so no whitespace ever reaches `tag.name` and this was never a defect —
|
|
508
|
-
// it takes the shared reading anyway so the count of readings stays at one (@SCN-TRM-001).
|
|
509
103
|
const bare = (tags) => tags.map((t) => bareTerm(t.name));
|
|
510
|
-
const featureTags = bare(
|
|
511
|
-
const lines = source.split(/\r?\n/);
|
|
512
|
-
const starts = documentBlockStarts(document);
|
|
104
|
+
const featureTags = bare(feature.tags);
|
|
513
105
|
const collect = (children, inherited) => {
|
|
514
106
|
for (const child of children) {
|
|
515
107
|
if (child.rule) {
|
|
516
|
-
// A Rule's tags cascade to every scenario beneath it — cucumber applies them, so we must.
|
|
517
108
|
collect(child.rule.children, [...inherited, ...bare(child.rule.tags)]);
|
|
518
109
|
continue;
|
|
519
110
|
}
|
|
520
111
|
if (!child.scenario)
|
|
521
112
|
continue;
|
|
522
|
-
// The EFFECTIVE tag set: the scenario's OWN tags, then everything it inherits from its Rule
|
|
523
|
-
// and Feature. This is the whole fix — the old scan saw only the first of the three. Own
|
|
524
|
-
// tags lead so a scenario's obligations read in the order its tags name them, and a
|
|
525
|
-
// file using NO inheritance yields a byte-identical corpus to the one the scan produced.
|
|
526
113
|
const effective = [...bare(child.scenario.tags), ...inherited];
|
|
527
114
|
const scnTag = effective.find((t) => SCN_CODE.test(t));
|
|
528
115
|
if (scnTag === undefined)
|
|
529
116
|
continue;
|
|
530
|
-
|
|
531
|
-
tagged.push({
|
|
532
|
-
scnId: scnTag,
|
|
533
|
-
tags: effective,
|
|
534
|
-
startLine,
|
|
535
|
-
endLine: blockEnd(startLine, starts, lines),
|
|
536
|
-
});
|
|
117
|
+
tagged.push({ scnId: scnTag, tags: effective, name: child.scenario.name });
|
|
537
118
|
}
|
|
538
119
|
};
|
|
539
|
-
collect(
|
|
120
|
+
collect(feature.children, featureTags);
|
|
540
121
|
return tagged;
|
|
541
122
|
}
|
|
542
|
-
|
|
543
|
-
* Parse the SCENARIO CORPUS — the ledger's DEBIT side — from the REAL Gherkin AST (@SCN-LDG-020,
|
|
544
|
-
* 3F-1775), the same parser cucumber uses. So the scenarios spec-controller reconciles carry
|
|
545
|
-
* EXACTLY the tags cucumber gives them: one reading of the file, not two.
|
|
546
|
-
*
|
|
547
|
-
* The corpus walk is `parseTaggedScenarios`'; this is the OBLIGATION rule applied over it. An
|
|
548
|
-
* unparseable source still THROWS from the walk rather than yielding an empty corpus.
|
|
549
|
-
*
|
|
550
|
-
* `checkTags` — the registry's bare check tags (@SCN-LNT-006) — is ADDITIVE and defaults to none, so
|
|
551
|
-
* `parseScenarios` keeps its place on the v1 barrel and every existing caller
|
|
552
|
-
* reads exactly the corpus it read before. A target that has registered nothing raises no fitness
|
|
553
|
-
* obligations, which is what lets the bare-tag reading land ahead of the corpus sweep that uses it.
|
|
554
|
-
*
|
|
555
|
-
* `fitnessChecks` — the target's CONFIGURED ROWS (@SCN-LNT-018) — is trailing and optional for the
|
|
556
|
-
* same reason, and carries the scenario's own `scnId` into the obligation rule: a converted check's
|
|
557
|
-
* characteristic is keyed by the row it is owed on, so the rule cannot be applied to a tag set
|
|
558
|
-
* alone. Empty by default, so a target that has converted nothing raises nothing on this route.
|
|
559
|
-
*/
|
|
560
|
-
export function parseScenarios(source, deferralTags = [], checkTags = [], fitnessChecks = new Map()) {
|
|
123
|
+
export function parseScenarios(source, deferralTags = []) {
|
|
561
124
|
return parseTaggedScenarios(source).map((scenario) => ({
|
|
562
125
|
scnId: scenario.scnId,
|
|
563
|
-
evidenceObligations: obligationsFromTags(scenario.tags, deferralTags
|
|
126
|
+
evidenceObligations: obligationsFromTags(scenario.tags, deferralTags),
|
|
564
127
|
}));
|
|
565
128
|
}
|
|
566
129
|
//# sourceMappingURL=scenarios.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenarios.js","sourceRoot":"","sources":["../../src/parse/scenarios.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scenarios.js","sourceRoot":"","sources":["../../src/parse/scenarios.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,WAAW,EAA2C,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGnE,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,IAAI,aAAa,GAAG,CAAC,CAAC;AAEzD,MAAM,4BAA4B,GAAiC;IACjE,cAAc,EAAE,SAAS;IACzB,WAAW,EAAE,MAAM;IACnB,kBAAkB,EAAE,aAAa;IACjC,UAAU,EAAE,KAAK;IACjB,kBAAkB,EAAE,aAAa;CAClC,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,OAAO,4BAA4B,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;AACnD,CAAC;AAED,MAAM,oBAAoB,GAAwC;IAChE,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,aAAa;IAC1B,GAAG,EAAE,KAAK;IACV,WAAW,EAAE,aAAa;CAC3B,CAAC;AAEF,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACzD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,cAAc,GAAG,IAAI,MAAM,CAAC,IAAI,aAAa,EAAE,EAAE,GAAG,CAAC,CAAC;AAE5D,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;AACrD,CAAC;AAED,MAAM,eAAe,GACnB,mEAAmE,CAAC;AAEtE,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,SAAS,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,IAAI,EAAE,CAAC;YACT,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;YACxB,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC;QAC5B,CAAC;QACD,SAAS,GAAG,EAAE,CAAC;IACjB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAS,CAAC;AAE1C,SAAS,6BAA6B,CAAC,IAAuB;IAC5D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAAE,OAAO,EAAE,CAAC;IAChD,OAAO,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,mBAAmB,CAC1B,IAAuB,EACvB,YAA+B;IAE/B,MAAM,mBAAmB,GAAyB,EAAE,CAAC;IACrD,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAuB,CAAC;IACzD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAgB,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,YAAY,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAI,YAAY,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YACnD,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC9B,mBAAmB,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACxE,SAAS;QACX,CAAC;QACD,MAAM,YAAY,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,YAAY,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YACzD,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACpC,mBAAmB,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;YAC3C,SAAS;QACX,CAAC;IACH,CAAC;IACD,mBAAmB,CAAC,IAAI,CAAC,GAAG,6BAA6B,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,IAAI,mBAAmB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,mBAAmB,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,UAAU,IAAI,mBAAmB;gBAAE,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;QAC1E,CAAC;IACH,CAAC;IACD,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAQD,SAAS,oBAAoB,CAAC,MAAc;IAC1C,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,0BAA0B,EAAE,CAAC,CAAC;IAChG,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,MAAM,EAAE,OAAO,EAAE,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAErC,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,CAAC,IAAiC,EAAY,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEhG,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC,MAAM,OAAO,GAAG,CAAC,QAAiC,EAAE,SAAmB,EAAQ,EAAE;QAC/E,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAA0B,EAAE,CAAC,GAAG,SAAS,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACzF,SAAS;YACX,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,QAAQ;gBAAE,SAAS;YAE9B,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACvD,IAAI,MAAM,KAAK,SAAS;gBAAE,SAAS;YAEnC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CAAC,OAAO,CAAC,QAA0B,EAAE,WAAW,CAAC,CAAC;IAEzD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,eAAkC,EAAE;IAEpC,OAAO,oBAAoB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACrD,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,mBAAmB,EAAE,mBAAmB,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;KACtE,CAAC,CAAC,CAAC;AACN,CAAC"}
|