Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33

Open
lilleman wants to merge 966 commits from worktree-todo-relative-dates-exact-counts into main
6 changed files with 41 additions and 6 deletions
Showing only changes of commit ba2ae41ffe - Show all commits
+12 -3
View File
@@ -309,6 +309,15 @@ func TestCalcRefusesABadOperand(t *testing.T) {
} }
} }
func TestATypedColumnRefusesACalcOverNoDigits(t *testing.T) {
_, err := New(WithoutShippedData(), WithDataPath(writeData(t, map[string]string{
"row": `{"format":"","x":{"format":"{calc(d + 1)}","d":"{digits(0)}","datatype":"integer"}}`,
})))
if err == nil || !strings.Contains(err.Error(), "{digits(0)} prints nothing, which is no number") {
t.Fatalf("New = %v, want a calc over {digits(0)} refused in a typed column", err)
}
}
func TestATypedColumnProvesACalcOverAName(t *testing.T) { func TestATypedColumnProvesACalcOverAName(t *testing.T) {
dir := writeData(t, map[string]string{ dir := writeData(t, map[string]string{
"n": `"{int(1,9)}"`, "n": `"{int(1,9)}"`,
@@ -334,8 +343,8 @@ func TestATypedColumnProvesACalcOverAName(t *testing.T) {
} }
} }
func TestARepeatOfZeroIsNoConstant(t *testing.T) { func TestARepeatOfZeroIsNeverANumber(t *testing.T) {
if got := mustRender(t, engine(1), `{"format":"{calc(x / y)}","x":"1","y":{"format":"0","repeat":0}}`); got != "NaN" { if _, err := resolved(t, `{"format":"{calc(x / y)}","x":"1","y":{"format":"0","repeat":0}}`); err == nil || !strings.Contains(err.Error(), `operand "y" is never a number: it renders ""`) {
t.Errorf("a divisor rendering nothing = %q, want NaN", got) t.Errorf("a calc over a repeat of 0 = %v, want the operand refused as never a number", err)
} }
} }
+1 -1
View File
@@ -26,7 +26,7 @@ func TestDatatypeSitsOnlyInAColumn(t *testing.T) {
} }
for src, want := range map[string]string{ for src, want := range map[string]string{
`{"format":"","n":{"format":"1","datatype":"int"}}`: `datatype takes "string", "integer", "number" or "boolean", got "int"`, `{"format":"","n":{"format":"1","datatype":"int"}}`: `datatype takes "string", "integer", "number" or "boolean", got "int"`,
`{"format":"","n":{"format":"1","datatype":1}}`: "datatype must be a string", `{"format":"","n":{"format":"1","datatype":1}}`: "datatype must be a string, not a number",
} { } {
if _, err := resolved(t, src); err == nil || !strings.Contains(err.Error(), want) { if _, err := resolved(t, src); err == nil || !strings.Contains(err.Error(), want) {
t.Errorf("compile(%s) = %v, want an error containing %q", src, err, want) t.Errorf("compile(%s) = %v, want an error containing %q", src, err, want)
+3 -2
View File
@@ -29,14 +29,15 @@ func TestPackageImports(t *testing.T) {
} }
checked := 0 checked := 0
allowed := map[string][]string{ allowed := map[string][]string{
".": {"internal/builtinfunc", "internal/datafiles", "internal/datatype", "internal/drawstate", "internal/grammar", "internal/invariant", "internal/proven", "internal/rows"}, ".": {"internal/builtinfunc", "internal/datafiles", "internal/datatype", "internal/drawstate", "internal/grammar", "internal/invariant", "internal/jsonvalue", "internal/proven", "internal/rows"},
"cmd/fejkdata": {"."}, "cmd/fejkdata": {"."},
"internal/builtinfunc": {"internal/datatype", "internal/drawstate", "internal/grammar", "internal/invariant", "internal/proven"}, "internal/builtinfunc": {"internal/datatype", "internal/drawstate", "internal/grammar", "internal/invariant", "internal/proven"},
"internal/datafiles": {"internal/grammar"}, "internal/datafiles": {"internal/grammar", "internal/jsonvalue"},
"internal/datatype": nil, "internal/datatype": nil,
"internal/drawstate": nil, "internal/drawstate": nil,
"internal/grammar": nil, "internal/grammar": nil,
"internal/invariant": nil, "internal/invariant": nil,
"internal/jsonvalue": nil,
"internal/proven": {"internal/datatype", "internal/grammar", "internal/invariant"}, "internal/proven": {"internal/datatype", "internal/grammar", "internal/invariant"},
"internal/rows": {"internal/drawstate", "internal/grammar", "internal/invariant"}, "internal/rows": {"internal/drawstate", "internal/grammar", "internal/invariant"},
} }
+11
View File
@@ -1,6 +1,7 @@
package fejkdata package fejkdata
import ( import (
"fmt"
"strings" "strings"
"testing" "testing"
) )
@@ -182,6 +183,16 @@ func TestAChoiceItemKeepsTheNamesItBinds(t *testing.T) {
} }
} }
func TestTheRootScopeIsTheCategory(t *testing.T) {
root := compiled(t, `{"format":"{x as n}{n}{y}","x":"a","y":{"format":"{z as m}{m}","z":"b","repeat":2}}`).(*template)
if k := fmt.Sprint(root.nameScope.kind()); k != "category" {
t.Errorf("root scope kind = %q, want category", k)
}
if k := fmt.Sprint(root.fields["y"].(*template).nameScope.kind()); k != "repeat" {
t.Errorf("repeat scope kind = %q, want repeat", k)
}
}
func TestNameErrors(t *testing.T) { func TestNameErrors(t *testing.T) {
cases := []struct { cases := []struct {
name string name string
+11
View File
@@ -2,9 +2,20 @@ package fejkdata
import ( import (
"regexp" "regexp"
"strings"
"testing" "testing"
) )
func TestAnOptionOfTheWrongKindIsNamedByItsJSONKind(t *testing.T) {
if _, err := resolved(t, `{"format":"x","repeat":2,"separator":5}`); err == nil || !strings.Contains(err.Error(), "separator must be a string, not a number") {
t.Errorf("separator 5 = %v, want the kind named", err)
}
_, err := New(WithoutShippedData(), WithDataPath(writeFiles(t, map[string]string{"t.json": `{"format":"{a}","rows":"t.tsv","key":5}`, "t.tsv": "a\nx\n"})))
if err == nil || !strings.Contains(err.Error(), "key must be a string, not a number") {
t.Errorf("key 5 = %v, want the kind named", err)
}
}
func TestWeightSkewsDistribution(t *testing.T) { func TestWeightSkewsDistribution(t *testing.T) {
f := engine(9) f := engine(9)
heavy := 0 heavy := 0
+3
View File
@@ -309,6 +309,9 @@ func TestFakeStructErrors(t *testing.T) {
{&struct { {&struct {
A int `fake:"person.first"` A int `fake:"person.first"`
}{}, `"Ada" is not an integer`}, }{}, `"Ada" is not an integer`},
{&struct {
A int `fake:"{\"format\":\"{calc(d + 1)}\",\"d\":\"{digits(0)}\"}"`
}{}, "{digits(0)} prints nothing, which is no number"},
{&struct { {&struct {
A int8 `fake:"{int(0,300)}"` A int8 `fake:"{int(0,300)}"`
}{}, `"{int(0,300)}" is not proven within int8; narrow it to that range, or make the field int64`}, }{}, `"{int(0,300)}" is not proven within int8; narrow it to that range, or make the field int64`},