FS FormScript
Package@formscript/property
Specification18, 18.3
Depends onanalyzer, ast, decimal, engine, errors, evaluator, lexer, parser, types

@formscript/property

The property-based and metamorphic tests of the FormScript language.

The specification's own conformance suite (§18) states cases: this document must parse, that expression must give that value. A case holds for one input. A property holds for every input a generator can produce, and that is a different kind of claim.

The corpus found what the language cannot say. This package finds what the language cannot do.

What is here

src/tables.ts the truth tables of Spec-6.12, read out of the specification
src/generators.ts the generators: expressions, documents, operands
src/properties.ts the properties themselves
test/properties.test.ts the run

The truth tables are not copied into this package. The specification prints them; the property reads them from there and compares the implementation against what the document says. A copy would drift, and the drift would be the whole point of the table.

The properties

Each property names the statement of the specification it checks, so a failure says which rule was broken.

Property Statement What it claims
kleene-table Spec-6.12 and and or return what the tables in the specification say, for all twenty-five pairs
kleene-laws Spec-6.12 the logic is commutative and associative, T and F are the identities, De Morgan holds, and the excluded middle holds for a known operand
strict-builtins Spec-6.8 every strict builtin propagates absence instead of failing
determinism Spec-9.1 the same document and the same input always give the same answer
order-independence Spec-9.2 the order of independent declarations does not change the answer
two-planes Spec-12.9 a display value may not be used where a data value is required, and the data plane does not depend on the locale
arithmetic-commutes Spec-6.6 a + b is b + a, and a * b is b * a
arithmetic-exact Spec-5.28 the sum and the product of two decimals are the exact rational values
between-equivalence Spec-6.13 x is between a and b is exactly x >= a and x <= b
output-round-trip Spec-10.6 the output document can be put back in unchanged

Where the domain is finite — the truth tables, the laws — the check is exhaustive. Where it is not, the check is generated, shrunk, and reproducible from a seed.

Running them

bash
npm run property

The seed is fixed in the test file, so a failure is reproducible exactly. Change the seed to look for other counterexamples.

What it found

between-equivalence found a defect the corpus never could: the evaluator compared the upper bound in the wrong direction, so 10 is between 1 and 20 answered false. The conformance suite had not caught it, because §18.3 tested between only with an absent operand. The suite now has three more rows, and the specification records them in revision r10.

Public API

26 exported symbols.

arithmeticArbitrary const

An arithmetic expression over decimals. Only `+`, `-` and `*` are generated: the law of exactness is stated for them, and `/` is not exact by definition.

BINARY_OPERATORS const

The binary operators a generated expression may use.

booleanArbitrary const

A boolean expression.

decimalArbitrary const

A decimal written as text. The digits come from integers, never from a floating-point number, so the literal is exact by construction: `0.1` is one tenth and…

DependentDocument interface

A document whose fields depend on one another.

dependentDocumentArbitrary const
FIELD_TYPES const

The field types a generated document may declare.

FieldType type

A field type and the matching output type.

identifierArbitrary function

An identifier expression.

IDENTIFIERS const

The names a generated expression may refer to.

IndependentDocument interface

A generated document: independent fields only.

independentDocumentArbitrary const

A document of independent fields, whose declarations may be permuted.

knownTruthArbitrary const

A truth value that is *known* — one the excluded middle applies to.

literalArbitrary function

A literal expression of a given kind.

propertiesFor re-export
Property interface

A property of the language. A property is a statement that must hold for every input the generator can produce — not for the handful of cases a hand-written …

readTruthTables re-export
RunOptions interface

How the property suite is run.

Truth type

The truth tables of Spec-6.12, read out of the specification. The tables are copied into no code. The specification prints them, the property reads them from…

TRUTH_ORDER re-export
TRUTH_VALUES const

Exposed so a test may state the laws over the truth values directly.

truthArbitrary const

The five truth values, in any order.

TruthTable type
TruthTables interface

The two tables of Spec-6.12.

truthToValue function

The runtime value a truth value stands for.

TruthValue type

The five truth values of Spec-6.12.