15. Conformance
Contents of FBL 0.17
| Class | Requirements |
|---|---|
| FBL document | Validates against $defs/Document and passes the checks of section 14.1 without errors. |
| Validator | Implements section 14.1, (FBL 0.9) building every grammar a binding carries, and reports problems with JSON Pointers; checks registrations against $defs/Registration and fixtures against $defs/Fixture and section 15.3. |
| Host — declared | Implements the lossless readings of the families it supports (section 4), rules (section 5), the splice catalogue and new-text rules (section 6), history and drift (section 7), the registration (section 8), several readings (section 9), routing and templates (sections 12, 13), and passes every fixture of the families it supports. It states which families it supports. |
| Host — full | Host — declared for the six families of FBL 0.8, plus folder subjects (section 10) and the plugin contract (section 11). (FBL 0.9) No host is required to support the grammar family; a host that does says so and passes its fixtures byte for byte, every host producing the same splices (section 6.5). (FBL 0.11) Except that a host which reads or writes Structurizr DSL workspaces or .owm maps through their declared bindings (the six C4 tool types and the Wardley map) MUST support the grammar family with every construct of this version, say so, and pass its fixtures byte for byte with the same splices as every other host. |
| Persistence plugin | Meets section 11.4 for its format. |
A host that does not support a binding's family or plugin MUST open its documents read-only, if it can read them at all, and say why; this is DISL's rule for a missing required plugin (DISL §13.1). (FBL 0.17) A host that supports the grammar family at an earlier version than a construct of the family that a binding uses, as a host at 0.9 does a binding that uses a construct of 0.11 or later, MAY open, read and edit that binding's documents, reading the binding as section 2.7 says. It then MUST report each construct it does not read as a warning that names the construct, and MUST NOT write a splice that touches text such a construct governs: the text of the entries and nodes that the rule, slot or property carrying the construct reads, and the place where a write the construct shapes would go. That text stays byte for byte, and an edit the host could plan only by touching it is refused, with the construct named as the reason. A host that cannot honour that, as where it cannot tell which text such a construct governs, MUST treat the binding as one whose family it does not support, and so open its documents read-only as the paragraph above says, which is what (FBL 0.11) FBL 0.11 to 0.16 required of every such host. This leaves unchanged what the class Host — full requires of a host that reads or writes Structurizr DSL workspaces or .owm maps: it MUST support the grammar family with every construct of this version.
A host that cannot watch files reads bodies on open and on request only, and says so. A host that cannot keep the registration (a read-only workspace) keeps positions for the session only, and says so. Nothing else in this document degrades: byte preservation, exact undo and drift refusal are required of every host.
fixtures/<name>/fixture.json, validated by $defs/Fixture, is a conformance test for hosts:
| Property | Description |
|---|---|
binding |
The binding under test, relative to the fixture. |
input |
The input body, a file beside the fixture, compared byte for byte (the repository keeps these files from line-ending conversion). |
template |
(FBL 0.10) {name, origin}: the input is the new document the binding's template gives for a file of that name and the reading of that origin (section 13), its placeholders replaced. The validator writes the template so and compares it with the input byte for byte; read and steps then apply to it as to any input, as the reading of that origin. A template holding {newid:<rule>} cannot be written so, and is not stated this way. |
read |
What reading the input yields: (FBL 0.7) document, the attributes of the document as attributes below, elements (id, type, (FBL 0.7) optionally parent, the id of the element it is contained in or null at the top level, and (FBL 0.5) optionally attributes, the values read for the attributes it names, a JSON string for a text and a JSON number, bool or null otherwise), findings (rule, line), unreadable. |
steps |
In order: an edit (add, set, remove, (FBL 0.3) move, place, (FBL 0.7) setting, or save without change; an add or a move carries a position as section 11.2 gives it, and (FBL 0.5) an add the slot it fills, as section 11.2's add does, which a host needs when one type fills several slots of one parent), an undo or a redo; the splices it must produce, as {operation, start, end, text} with UTF-8 byte offsets into the document before the step; the document after it (expect, or expectFile); (FBL 0.10) expectFiles, the bytes after it of each file beside the input that its splices name in their file, by that name, relative to the input's folder (the body a registration names, or a sidecar), a splice without file being the input's; refused with the reason when the edit must be refused and write nothing. |
(FBL 0.7) elements lists every element the body's entries yield, in reading order, and, when the input is a registration, the elements the tool type's specification makes of its blocks as well (DESL sections 5.5, 7.7.2). An attribute with many is stated as a JSON array of its items in order, and an enumeration's value by its key. A step's edit is one change, or a list of changes that one transaction makes, planned in order as one edit (section 6.4); a set or remove may carry occurrence, the place in reading order of the holder of a duplicated id it concerns (2 for the second). Its splices are listed in the order section 6.5 applies them: by offset, and at one offset in the order the edit made them. A setting on a list block that is absent is planned as the tool type's specification gives it, which may write the whole list (DESL section 5.5).
A host passes a fixture when reading the input gives what read lists (for an element with attributes, each attribute named there has that value and that JSON type; attributes not named are not compared) and every step produces exactly its splices and its document. For a refused step it passes when it refuses the edit and writes nothing: the text of refused is informative, because FBL leaves a refusal's wording to the host except where a binding gives the reason itself (readOnly, section 3.4, and (FBL 0.10) refusals, section 6.4), and then it is that reason. The repository's validator checks every fixture's consistency: each step's splices turn the document before it into its expect, and back by their inverses; an undo returns the document the undone edit started from; a save and a refused edit change nothing. Undo steps list the inverse splices under the operation of the splice each inverts. (FBL 0.10) A file a step's splices name in file is replayed as the input is, from its bytes beside the input, with its undo and redo checked the same way; a fixture whose input is a registration so states the edits of the body it opens.
(FBL 0.7) A setting edit changes an entry of a declared block of the registration, which is then the fixture's input: it names the block and the entry's key, and gives its new value, its new position in a kept block ({index}, {after: key} or {before: key}), a new key as rename, or remove: true; a setting with a position and no value moves the entry. When the input is a registration, the fixture's read is that of the document it opens: the elements of the body it names, and the findings, a registration finding's line being a line of the registration. A fixture for a registration that createOnFirstPlacement creates starts from the text section 8.4 creates. A step whose setting writes a block outside the history is no step of the history, so an undo after it undoes the edit before it.
Together the fixtures exercise every operation of section 6.1. (FBL 0.11) They do so for the grammar family's writes too: replace-value, insert-key, remove-key, insert-entry, remove-entry, rewrite-reference and open-block each appear in a fixture of a grammar binding, and (FBL 0.16) replace-separator, which only this family writes.