asDocument
re-export| Package | @formscript/conformance |
|---|---|
| Specification | 17.2, 18, 18.1, 18.2, 18.3, 18.4, 18.5 |
| Depends on | analyzer, ast, decimal, engine, errors, evaluator, lexer, parser, types |
@formscript/conformance
The conformance suite of the FormScript Language Specification 1.0.0 , §18 — and the runner that executes it.
§18 is not a description of a suite; it is the suite, written in the specification. This package extracts those rows from the specification text and runs them against the reference implementation, so the claim "the suite is executed, not asserted" is a fact with a test result behind it.
The five sections
| Section | What it checks | How |
|---|---|---|
| §18.1 | Documents that must parse | The lexer and the parser produce no diagnostic |
| §18.2 | Documents that must be rejected | The reported set contains the expected code |
| §18.3 | Evaluation semantics | The value and the static type |
| §18.4 | Documents that must compile | The lexer, the parser and the analyzer are all clean |
| §18.5 | The §17.2 flagship document | One output document, end to end |
Two rows that are easy to get wrong
§18.3 distinguishes result type from result value. The row 1 + 1 →
2 and the row 1 + 1.0 → 2.0 have the same value and different types. The
runner therefore compares the value with strictEquals and the static type
with the analyzer's inferType. A runner that only checked the value would
pass a runtime that computed integers where decimals were required.
§18.5 asserts the keys that must be absent. The flagship's output
document omits an inapplicable entity, so the expected result names
postcode, guarantor.guarantor_name and guarantor.guarantor_consent as
absent (Spec-4.35). A runtime that emitted an inapplicable field as null
would fail this row.
The flagship's inputs are raw text
FLAGSHIP_ASSIGNMENTS assigns '30000', not 30000. The engine rejects a
JavaScript double for a number field, which is correct for a decimal data
plane: the input of a form is text, and Spec-5.3 governs its coercion.
Public API
const suite = readSuite('FormScript-Language-Specification.md');
const report = runSuite(suite);
report.passed; // 101
report.failed; // 0
report.totals; // { '18.1': { passed: 46, failed: 0 }, ... }
report.failures; // one entry per failing row
Also exported: extractSuite, parseEvaluationTable, parseRejectTable,
splitDocuments, diagnose, reportedDiagnostics, literalValue,
runEvaluationCase, runFlagship, flattenOutput, FLAGSHIP_ASSIGNMENTS,
FLAGSHIP_OUTPUT, FLAGSHIP_ABSENT_KEYS and FLAGSHIP_OUTPUT_KEYS.
Running it
npm run conformance
# or, through the command line, with the same output:
npm run formscript -- conformance
The runner reports each section, then the failures with the expected and the actual result, and exits non-zero if any row failed.
Judgement calls
- The rows are read from the specification, not duplicated here. A row added to §18.3 of the specification is picked up by the next run; there is no second copy to keep in step.
- §18.2 checks that the expected code is among the reported codes, not that it is the only one. The specification's rows each isolate a defect, but a document that also trips an unrelated rule still demonstrates the behaviour the row claims to test.
- The stage order of Spec-2.5 is applied to the §18.2 rows. The reported set is the errors of the earliest non-empty stage plus every warning, so a lexical error is not masked by a semantic one further down.
- The §18.5 fixture is the §17.2 document verbatim. It is extracted from the specification, so the flagship that is tested is the flagship that is published.
Public API
33 exported symbols.
ConformanceFailure
interfaceConformanceReport
interfaceConformanceSuite
interfacediagnose
re-exportEvaluationBinding
interface
A name bound to an absence, as the §18.3 rows declare them.
EvaluationCase
interfaceEvaluationExpectation
typeEvaluationOutcome
interfaceextractSuite
re-exportFLAGSHIP_ABSENT_KEYS
const
The output keys that must be **absent**: their entity is inapplicable, so they were never asked (Spec-4.35).
FLAGSHIP_ASSIGNMENTS
const
The input sequence the fixture is run with, as the raw text a user would type.
FLAGSHIP_OUTPUT
const
The output document the fixture must produce. A `number` is carried as its canonical decimal text (Spec-4.36); an applicable but unanswered field is an expli…
FLAGSHIP_OUTPUT_KEYS
const
The keys the §17.2 `output` block declares.
FlagshipOutcome
interfaceflattenOutput
function
Flattens a nested output document into dotted keys (Spec-4.35).
isPrimaryDiagnostic
function
Spec-18.2/Spec-18.3: the stated code must be the first error reported for the row, not merely one of them. "First" means the first diagnostic of the stage-fi…
literalValue
function
The value a §18.3 literal denotes.
MustParseCase
interfaceMustRejectCase
interfaceparseDiagnostics
function
The lexical and syntactic diagnostics only — what §18.1 constrains.
parseEvaluationTable
re-exportparseRejectTable
re-exportreadSuite
re-exportreportedDiagnostics
re-exportrunEvaluationCase
function
Runs one §18.3 row.
runFlagship
function
Runs the flagship document through the pipeline of §18.5.
runMustReject
re-exportrunSuite
re-exportsectionBody
function
The body of a section, up to the next heading of any level. Stopping only at `## ` would swallow every `### ` subsection that follows, and a table from the n…
splitCells
function
Splits a markdown table row into its cells. A pipe inside a code span is part of the cell, not a delimiter — the row `value = 1 || 2` has four pipes in it an…
splitDocuments
re-exportUnreadableRow
interface