I maintain the specification of Podlite, a block-based markup language. Its rules are prose. The table rule, for example, is a few sentences about separators and cells.
Podlite 3.0 is due in mid-November, and in it the rules come with tests. The tests are written in Podlite and sit in the specification text next to the rules they check. With a test, checking a rule becomes more predictable: you run it on a concrete document and get the same answer each time.
A rule of the 3.0 specification with its test opened: the source, then what each selector must and must not find
A test
Each test is a block. It holds one or more assertions about what a parser makes of a document, and it may hold the document itself, in a fixture:
=begin test :id<heading-carries-its-level>
=begin fixture
=head2 Overview
=end fixture
=for assert :caption('a second-level heading is recognised as such')
head2
=end test
An assertion carries a selector, the same kind Podlite uses to pick blocks in an include. By default it holds when the selector finds at least one block. With :absent it holds when the selector finds none, which is how a rule like "every invoice has a number" gets written:
=for assert :absent
Invoice[ :!?number ]
What the tests check
Podlite describes what each part of a document is and leaves the look to the renderer. The tests check the parsed structure, the names and configuration of blocks, and never the rendered output.
The specification also says which one wins: "If a test of this specification differs from the rule it checks, the rule governs." Later some details may move from the rule text into the tests, which would make the rules shorter to read.
Sentences a test cannot check
The tests are a start. They do not cover every rule yet, and they will grow along with the specification. Some sentences will have to change before they can be tested: the table section still says the cells "should be carefully aligned to ensure the table is interpreted as the user intended".
So 3.0 adds a sentence a parser can be checked against. Whitespace between two cells is one separator, whatever its width, and an empty cell is written with a visible | or +. The parser does not follow it yet: a one-line table with a | | z loses its empty middle cell. The bug is filed and will be fixed to match the rule.
Tests for your own documents
You can use the same blocks on your own documents. A knowledge base, for example, can require every invoice to carry a number. Run the tests on one file or on many, for instance after a script or an agent has edited them.
The CLI runs them:
npx podlite test my-notes.podlite
Links
The 3.0 specification, with each test shown beside its rule, is at podlite.org/v3.0/specification
The announcement lists the other changes: Coming in Podlite 3.0.
Comments on the tests go to the podlite-specs Discussions on GitHub.

Top comments (0)