@rse/specbook 1.2.4 → 1.2.6
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 +21 -3
- package/dst/specbook-cmd-lint.js +25 -1
- package/dst/specbook-config.js +18 -17
- package/dst/specbook-coverage.d.ts +17 -0
- package/dst/specbook-coverage.js +106 -0
- package/dst/specbook-diagram.js +163 -21
- package/dst/specbook-export-ast.js +11 -1
- package/dst/specbook-export-html.css +236 -5
- package/dst/specbook-export-html.js +312 -7
- package/dst/specbook-export-pdf.js +30 -6
- package/dst/specbook-format-schema.d.ts +12 -0
- package/dst/specbook-format-schema.js +13 -1
- package/dst/specbook-format.md +110 -10
- package/dst/specbook-format.yaml +354 -173
- package/dst/specbook-parse-semantic.js +6 -42
- package/dst/specbook-parse.d.ts +1 -1
- package/dst/specbook-parse.js +1 -1
- package/package.json +5 -5
package/dst/specbook-format.md
CHANGED
|
@@ -74,6 +74,7 @@ type SchemaObject = {
|
|
|
74
74
|
refs?: string
|
|
75
75
|
optional?: boolean
|
|
76
76
|
referenced?: string[]
|
|
77
|
+
coverage?: string[]
|
|
77
78
|
automaton?: SchemaAutomaton
|
|
78
79
|
diagram?: SchemaDiagram
|
|
79
80
|
format?: SchemaFormat
|
|
@@ -100,6 +101,7 @@ type SchemaDiagramCenterEdges = {
|
|
|
100
101
|
outbound?: string
|
|
101
102
|
both?: string
|
|
102
103
|
labeled?: string
|
|
104
|
+
via?: string
|
|
103
105
|
}
|
|
104
106
|
type SchemaDiagram = {
|
|
105
107
|
type?: "graph" | "hub" | "grid"
|
|
@@ -123,6 +125,7 @@ type SchemaDiagram = {
|
|
|
123
125
|
type SchemaFormat = {
|
|
124
126
|
type?: "auto" | "complex" | "concise"
|
|
125
127
|
maxTableColumns?: number
|
|
128
|
+
maxCellHeight?: number
|
|
126
129
|
withUnusedProps?: boolean
|
|
127
130
|
}
|
|
128
131
|
type SchemaProperty = {
|
|
@@ -234,6 +237,13 @@ type SchemaGradiaConfig = Partial<{
|
|
|
234
237
|
at least once, where a lapse is reported as a warning only,
|
|
235
238
|
BECAUSE a term nobody uses or a requirement no use case exercises is dead weight
|
|
236
239
|
|
|
240
|
+
- `SchemaObject.coverage?: string[]`:
|
|
241
|
+
wildcard references (e.g. `[[SCENARIO:*]]` for the use case scenarios)
|
|
242
|
+
matching the objects whose reference coverage every object of this kind
|
|
243
|
+
reports: the share of them referenced -- themselves or through their
|
|
244
|
+
descendants -- from the object or its descendants (see below),
|
|
245
|
+
BECAUSE a test artifact has to state how much of the specification it verifies
|
|
246
|
+
|
|
237
247
|
- `SchemaObject.automaton?: SchemaAutomaton`:
|
|
238
248
|
finite state machine the child objects of every object of this kind form,
|
|
239
249
|
BECAUSE a lifecycle is only trustworthy when its dead-ends and
|
|
@@ -318,9 +328,11 @@ type SchemaGradiaConfig = Partial<{
|
|
|
318
328
|
objects whose `inbound` value maps onto a node-to-center edge, whose
|
|
319
329
|
`outbound` value onto a center-to-node edge, and whose `both` value
|
|
320
330
|
onto both edges (the second placement rendered as a "ghost" node),
|
|
321
|
-
each optionally named by the value of the `labeled` property
|
|
322
|
-
|
|
323
|
-
|
|
331
|
+
each optionally named by the value of the `labeled` property and/or
|
|
332
|
+
by the mediating object referenced by the `via` property (as `via
|
|
333
|
+
<name>`), BECAUSE the nodes carry no `[[xxx]]` reference to a
|
|
334
|
+
synthetic center, so their relation to it lives in a direction
|
|
335
|
+
property instead
|
|
324
336
|
|
|
325
337
|
- `SchemaDiagram.links?: "props" | "all"`:
|
|
326
338
|
edge source: property values (`props`) or also texts (`all`),
|
|
@@ -350,7 +362,7 @@ type SchemaGradiaConfig = Partial<{
|
|
|
350
362
|
|
|
351
363
|
- `SchemaDiagram.deep?: boolean`:
|
|
352
364
|
whether the references of the descendants of a node count as its own,
|
|
353
|
-
|
|
365
|
+
counted as the arity (default: `false`),
|
|
354
366
|
BECAUSE the relations between coarse objects live in their fine parts
|
|
355
367
|
|
|
356
368
|
- `SchemaDiagram.onlyConnected?: boolean`:
|
|
@@ -365,6 +377,40 @@ type SchemaGradiaConfig = Partial<{
|
|
|
365
377
|
whether every node is labeled with its kind (default: `false`),
|
|
366
378
|
BECAUSE names alone are ambiguous across multiple object kinds
|
|
367
379
|
|
|
380
|
+
- `SchemaDiagram.ordered?: boolean`:
|
|
381
|
+
whether the nodes are placed in document order instead of by the
|
|
382
|
+
layered layout, the top-level ones stacked top-down and the members
|
|
383
|
+
of a container lined up left-to-right (default: `false`),
|
|
384
|
+
BECAUSE in a coarse-to-fine specification the references then all
|
|
385
|
+
point backward, i.e. upward
|
|
386
|
+
|
|
387
|
+
- `SchemaDiagram.nest?: SchemaDiagramNest`:
|
|
388
|
+
nesting of the nodes into container nodes,
|
|
389
|
+
BECAUSE a containment drawn as a box beats one drawn as an edge
|
|
390
|
+
|
|
391
|
+
- `SchemaDiagramNest.properties?: string[]`:
|
|
392
|
+
properties whose single referenced object is the container of a node,
|
|
393
|
+
BECAUSE a `PART-OF` or `TIER` reference is a containment, not a relation
|
|
394
|
+
|
|
395
|
+
- `SchemaDiagramNest.parent?: boolean`:
|
|
396
|
+
whether the parent object is the container of a node (default: `false`),
|
|
397
|
+
BECAUSE the nesting of the objects is a containment, too
|
|
398
|
+
|
|
399
|
+
- `SchemaDiagramNest.kind?: boolean`:
|
|
400
|
+
whether a synthetic container per object kind holds the nodes
|
|
401
|
+
(default: `false`),
|
|
402
|
+
BECAUSE a kind is a grouping no object models
|
|
403
|
+
|
|
404
|
+
- `SchemaDiagramNest.layout?: "graph" | "hub" | "grid"`:
|
|
405
|
+
shape the members of every container are laid out with
|
|
406
|
+
(default: the diagram type),
|
|
407
|
+
BECAUSE the inside of a container may tell a different story than the whole
|
|
408
|
+
|
|
409
|
+
- `SchemaDiagramNest.crossing?: "nodes" | "target" | "both"`:
|
|
410
|
+
ends of a boundary-crossing edge lifted onto the containers
|
|
411
|
+
(default: `nodes`, i.e. none),
|
|
412
|
+
BECAUSE a bundle of references into a container reads as one edge onto it
|
|
413
|
+
|
|
368
414
|
- `SchemaDiagram.properties?: string[]`:
|
|
369
415
|
property names attached to the nodes as key/value annotations,
|
|
370
416
|
BECAUSE the node name alone rarely makes the nodes comparable
|
|
@@ -385,6 +431,10 @@ type SchemaGradiaConfig = Partial<{
|
|
|
385
431
|
maximum column count of the table of the kind (default: `4`),
|
|
386
432
|
BECAUSE the fixed print/PDF page width bounds the table width
|
|
387
433
|
|
|
434
|
+
- `SchemaFormat.maxCellHeight?: number`:
|
|
435
|
+
percent a table cell may tower over its row before it folds (default: `40`),
|
|
436
|
+
BECAUSE a cell of rich prose otherwise dwarfs the whole table
|
|
437
|
+
|
|
388
438
|
- `SchemaFormat.withUnusedProps?: boolean`:
|
|
389
439
|
whether unused properties still render (default: `false`),
|
|
390
440
|
BECAUSE empty entries are noise, unless the gap is the message
|
|
@@ -474,9 +524,10 @@ type SchemaGradiaConfig = Partial<{
|
|
|
474
524
|
|
|
475
525
|
The edges are derived from the `[[xxx]]` references of the node objects
|
|
476
526
|
-- from their property values only, or, with `links: all`, from their
|
|
477
|
-
descriptions as well.
|
|
478
|
-
|
|
479
|
-
|
|
527
|
+
descriptions as well. Every referenced object is lifted to its nearest
|
|
528
|
+
ancestor-or-self within the node set, so a reference onto the scenario
|
|
529
|
+
of a use case yields an edge onto the use case. With `deep: true` the
|
|
530
|
+
references of all descendants of a node object count as its own and the
|
|
480
531
|
number of references behind an edge becomes its arity, so a diagram of
|
|
481
532
|
coarse objects (like the artifacts of a whole specification) shows the
|
|
482
533
|
relations living in their fine-grained parts. With `labeled: true` an
|
|
@@ -527,6 +578,52 @@ nodes as key/value annotations (with every `[[xxx]]` reference stripped
|
|
|
527
578
|
to its target object name), and `config` passes arbitrary Gradia
|
|
528
579
|
rendering options (e.g. `grid-columns-max: 5`) through to the diagram.
|
|
529
580
|
|
|
581
|
+
`ordered` replaces the layered layout of a `graph` by the document
|
|
582
|
+
order of the objects: the top-level nodes stack top-down in that order
|
|
583
|
+
(a synthetic container at the position of its first member), while the
|
|
584
|
+
members of a container line up left-to-right in it, wrapped by the
|
|
585
|
+
Gradia option `graph-columns-max`, so the references of a coarse-to-fine
|
|
586
|
+
specification all point backward, i.e. upward or leftward.
|
|
587
|
+
|
|
588
|
+
`nest` nests the nodes into *container* nodes, drawn as boxes around
|
|
589
|
+
their members with the edges crossing the box borders: the first of its
|
|
590
|
+
`properties` carrying exactly one resolvable reference names the
|
|
591
|
+
container of a node (a container outside the node set is added to it,
|
|
592
|
+
labeled and linked like a node, and nested on its own in turn, so a
|
|
593
|
+
`NODE` sits in its `TIER` and the tier in the tier it is `PART-OF`),
|
|
594
|
+
else with `parent: true` the parent object is the container when part
|
|
595
|
+
of the node set, else with `kind: true` a synthetic container per object
|
|
596
|
+
kind is. An edge between a container and one of its own members is
|
|
597
|
+
dropped, as the nesting already shows it, `layout` selects the shape
|
|
598
|
+
the members of every container are laid out with (default: the diagram
|
|
599
|
+
type), a `hub` carries no containers, as every container would need a
|
|
600
|
+
primary node of its own, and a node nested into itself or into a cycle
|
|
601
|
+
is reported. With `crossing: target` an edge crossing a container
|
|
602
|
+
boundary ends at the outermost container of its target not enclosing
|
|
603
|
+
its source, too, and with `crossing: both` it also starts at the
|
|
604
|
+
corresponding container of its source, where the edges coinciding
|
|
605
|
+
afterwards merge into one with their arities summed, so the edges
|
|
606
|
+
inside a container stay node-to-node while the bundles of references
|
|
607
|
+
into a container become single edges onto it.
|
|
608
|
+
|
|
609
|
+
### Coverage
|
|
610
|
+
|
|
611
|
+
An object kind can carry a `coverage` field, a list of `[[xxx]]`
|
|
612
|
+
reference patterns, which makes every object of that kind report how
|
|
613
|
+
much of the objects matching each pattern it references: the *coverage*
|
|
614
|
+
is the share of the matching objects (those below the reporting object
|
|
615
|
+
itself excluded) which are referenced from the reporting object or one
|
|
616
|
+
of its descendants, where a matching object also counts as referenced
|
|
617
|
+
through one of its descendants, so a use case is covered as soon as one
|
|
618
|
+
of its scenarios is. While the `referenced` field demands the coverage
|
|
619
|
+
of an object kind and warns about every lapse, the `coverage` field
|
|
620
|
+
merely measures it: the HTML/PDF export renders a coverage table below
|
|
621
|
+
the description of the reporting object (one row per pattern, labeled
|
|
622
|
+
by the kinds of the matching objects, with the covered and total counts
|
|
623
|
+
and the ratio as a bar), the AST exports attach the counts as the
|
|
624
|
+
`coverage` field of the object, and the verbose output of `lint` and
|
|
625
|
+
`export` names the unreferenced objects.
|
|
626
|
+
|
|
530
627
|
### Format
|
|
531
628
|
|
|
532
629
|
An object kind can furthermore carry a `format` field, which controls
|
|
@@ -542,7 +639,10 @@ Inside a `concise` table, unconfigured child kinds implicitly stay
|
|
|
542
639
|
an explicitly configured `type` is always honored, even a `complex`
|
|
543
640
|
rendering pressed into a cell. `maxTableColumns` (default: `4`) bounds
|
|
544
641
|
the columns of the compact table of the kind (a wider group chunks
|
|
545
|
-
its properties into embedded per-object tables),
|
|
642
|
+
its properties into embedded per-object tables), `maxCellHeight`
|
|
643
|
+
(default: `40`) is the percentage a table cell of the kind may exceed
|
|
644
|
+
the height of every other non-empty cell of its row before the HTML
|
|
645
|
+
export folds its remaining text away, and `withUnusedProps`
|
|
546
646
|
(default: `false`) unconditionally renders the defined but unused
|
|
547
647
|
properties of that kind, as property table lines or table columns. In
|
|
548
648
|
the HTML/PDF export, a property absent from an object shows an "empty
|
|
@@ -837,7 +937,7 @@ In all formats, the `<name/>` may carry trailing decorations, in any
|
|
|
837
937
|
order:
|
|
838
938
|
|
|
839
939
|
- `{{<id/>}}`: the explicit Wiki-style anchor, setting the object id
|
|
840
|
-
(e.g. `## ENTITY: Attendee
|
|
940
|
+
(e.g. `## ENTITY: Attendee {{attendee}}`).
|
|
841
941
|
|
|
842
942
|
- `(<token/>)`: a parenthesized token with three possible roles: on
|
|
843
943
|
level 1 it becomes the artifact id (e.g. `# DATA: Data Model (DM)`);
|
|
@@ -896,7 +996,7 @@ exports. A reference is a `.`-separated path of segments, where each
|
|
|
896
996
|
segment matches a single object as:
|
|
897
997
|
|
|
898
998
|
- `<id/>`: the object id or explicit anchor (e.g. `[[attendee]]`)
|
|
899
|
-
- `<name/>`: the object name (e.g. `[[Attendee
|
|
999
|
+
- `<name/>`: the object name (e.g. `[[Attendee]]`)
|
|
900
1000
|
- `<kind/>:<name-or-id/>`: kind-qualified (e.g. `[[ENTITY:Event]]`)
|
|
901
1001
|
- `<kind/>:*` or `*`: wildcards (for match sets, see below)
|
|
902
1002
|
|