Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33
@@ -863,11 +863,11 @@ the Development section below, and who ships a register the four above then draw
|
||||
`secrets.GITHUB_TOKEN` resolve on either host, so only the names moved.
|
||||
- **The vocabulary sits below `doc.go`'s package clause, not in the package doc.**
|
||||
Goal 1 is what a developer choosing a library reads first, and the package doc is
|
||||
that page: a glossary of unexported units would fill two thirds of it with names
|
||||
no consumer can call, and Go doc comments have no code markup, so each one would
|
||||
that page: the glossary would fill two thirds of it with the render path's units,
|
||||
mostly unexported, and Go doc comments have no code markup, so every name would
|
||||
render its backticks literally. Below the clause it reaches goal 2's reader — who
|
||||
opens the file — and nothing else. Valid while the glossary names units a consumer
|
||||
cannot reach; one that came to name the exported API would belong above the clause.
|
||||
opens the file — and nothing else. Valid while the glossary's subject is the render
|
||||
path; one written to teach the exported API belongs above the clause.
|
||||
- **Options and fields share one namespace.** `format`, `weight`, `repeat`,
|
||||
`separator`, `datatype` and `drawGroup` are reserved; every other key is a field. Nesting fields under a
|
||||
key, or prefixing options, would tax every template to guard against a
|
||||
|
||||
@@ -16,31 +16,23 @@ package fejkdata
|
||||
|
||||
// Vocabulary
|
||||
//
|
||||
// The words the rest of the package uses, and the unit that owns each:
|
||||
//
|
||||
// - draw — one pick from a choice, or one row taken from a table, and the value
|
||||
// the pick produced: `pick` and `drawn` settle a choice, `table.draw` a row, and
|
||||
// `draw` carries what a read produced.
|
||||
// - expansion — one render of one format, by `expand`. A nested template is an
|
||||
// expansion of its own.
|
||||
// - draw — one pick from a choice, or one row taken from a table, and the value a
|
||||
// read produced: `pick`, `drawn`, `table.draw`, `draw`.
|
||||
// - expansion — one render of one format: `expand`.
|
||||
// - render — what owns one `drawSet`, and so what one reference draw spans:
|
||||
// `Generator.Fake`, `FakeRecord`, `FakeStruct`, `Template.Fake` and
|
||||
// `RecordTemplate.Fake` each start one, as does `expandAnew` per iteration of a
|
||||
// `template.repeat` — an iteration is an expansion and a render of its own.
|
||||
// - hold — keeping one draw of a name, so every route to it reads that value.
|
||||
// `template.held` lists what an expansion holds, `draws` keeps them and
|
||||
// `readField` reads through it; a reference path is held for the whole render.
|
||||
// - draw group — `template.drawGroup`, which gives the reference paths under it
|
||||
// draws of their own inside the render. `drawSet` holds the unnamed group's and
|
||||
// each named one's, and `drawScope` says which one a template renders in.
|
||||
// - pin — fixing which row of a table the render uses. `draws.pin` pins it and the
|
||||
// rows of its ancestors, and `draws.rowOf` draws one where none is pinned.
|
||||
// `Generator.Fake`, `FakeRecord`, `Template.Fake` and `RecordTemplate.Fake`
|
||||
// start one each, `FakeStruct` one per record, and `expandAnew` one per
|
||||
// iteration of a `template.repeat`.
|
||||
// - hold — keeping one draw of a name, so every route to it reads that value:
|
||||
// `template.held`, `draws`, `readField`.
|
||||
// - draw group — reference draws held apart inside one render:
|
||||
// `template.drawGroup` as the data spells it, `template.drawGroupKey` as a
|
||||
// render reads it, `drawSet`, `drawScope`.
|
||||
// - pin — fixing which row of a table the render uses: `draws.pin`, `draws.rowOf`.
|
||||
// - family — a table and every table reaching it through a chain of
|
||||
// `table.parentT`, named by the root that chain ends at: `table.family`.
|
||||
// - whole — a read that lands on a `row`, so the row renders through its table's
|
||||
// format: `tableRead.whole` says a read did, `table.whole` is the node.
|
||||
// - fence — a load-time check refusing data that two routes to one draw would
|
||||
// disagree in, which is why a render cannot fail: `heldCheck` over an
|
||||
// expansion's held names, `drawCheck` over a render's reference paths, and
|
||||
// `checkFamilies` over the rows they pin. `New` runs them over the data set,
|
||||
// `NewTemplate` and `FakeStruct` over what those compile.
|
||||
// - fence — a load-time check, so rendering a compiled tree cannot fail: `New`
|
||||
// runs them over the data set, `NewTemplate` and `FakeStruct` over what those
|
||||
// compile. The draw fences are `heldCheck`, `drawCheck` and `checkFamilies`.
|
||||
|
||||
+11
-13
@@ -10,12 +10,10 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Every backtick in the Vocabulary is a symbol, so an unrecognised spelling fails
|
||||
// rather than going unchecked.
|
||||
var backticked = regexp.MustCompile("`([^`]+)`")
|
||||
// Every backtick in the Vocabulary is a symbol.
|
||||
var backticked = regexp.MustCompile("`([^`\n]+)`")
|
||||
|
||||
// TestVocabularyNamesDeclaredSymbols proves the Vocabulary names symbols this
|
||||
// package declares, so a renamed unit renames its entry with it.
|
||||
// TestVocabularyNamesDeclaredSymbols holds a renamed unit to its Vocabulary entry.
|
||||
func TestVocabularyNamesDeclaredSymbols(t *testing.T) {
|
||||
files := sourceFiles(t)
|
||||
declared := declaredSymbols(files)
|
||||
@@ -50,23 +48,23 @@ func sourceFiles(t *testing.T) []*ast.File {
|
||||
|
||||
func vocabulary(t *testing.T, files []*ast.File) string {
|
||||
t.Helper()
|
||||
var found strings.Builder
|
||||
var sections strings.Builder
|
||||
for _, f := range files {
|
||||
for _, c := range f.Comments {
|
||||
if section, is := strings.CutPrefix(c.Text(), "Vocabulary\n\n"); is {
|
||||
found.WriteString(section)
|
||||
section, found := strings.CutPrefix(c.Text(), "Vocabulary\n\n")
|
||||
if found && c.Pos() > f.Package {
|
||||
sections.WriteString(section)
|
||||
}
|
||||
}
|
||||
}
|
||||
if found.Len() == 0 {
|
||||
t.Fatal("no comment opens with a Vocabulary heading, so fence, hold, pin and the rest are defined nowhere a reader of the code meets them")
|
||||
if sections.Len() == 0 {
|
||||
t.Fatal("no comment below a package clause opens with a Vocabulary heading, so the words the package is written in are defined nowhere a reader of the code meets them")
|
||||
}
|
||||
return found.String()
|
||||
return sections.String()
|
||||
}
|
||||
|
||||
// declaredSymbols is every name the package declares at the top level, a method and
|
||||
// a struct field keyed under its type: draws.pin, tableRead.whole. A name declared
|
||||
// inside a function body is not one a Vocabulary entry may name.
|
||||
// a struct field keyed under its type: draws.pin, tableRead.whole.
|
||||
func declaredSymbols(files []*ast.File) map[string]bool {
|
||||
names := map[string]bool{}
|
||||
for _, f := range files {
|
||||
|
||||
@@ -43,6 +43,9 @@ This round, in order:
|
||||
- Spell one fresh draw set one way: `newDrawSet` exists, and `render.go` and `draw.go`
|
||||
hand-roll `drawSet{unnamed: draws{s: s}}` at three sites; name the lazy-map variant
|
||||
if the difference is deliberate.
|
||||
- Run the package doc's Go example under test, as `readme_test.go` runs the README's
|
||||
JSON blocks: `doc.go` and the README both print `Järvedsvägen 43\n891 77 Järved`
|
||||
for seed 42, and nothing renders either, so a draw that moves leaves both false.
|
||||
|
||||
### Data
|
||||
|
||||
|
||||
Reference in New Issue
Block a user