Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33
@@ -48,16 +48,6 @@ func TestParseRefuses(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseAccepts(t *testing.T) {
|
|
||||||
if tb := parse(t, "t", "a\n1\n", Options{}); tb.Len() != 1 {
|
|
||||||
t.Errorf("one row: Len = %d, want 1", tb.Len())
|
|
||||||
}
|
|
||||||
tb := parse(t, "t", "k\nx\ny\n", Options{Key: "k", Name: "k"})
|
|
||||||
if r, err := tb.find("y", nil); err != nil || r != 1 {
|
|
||||||
t.Errorf("the key named as name: find(y) = %d, %v, want row 1", r, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLinkRefusesAParentRowNoChildLinksTo(t *testing.T) {
|
func TestLinkRefusesAParentRowNoChildLinksTo(t *testing.T) {
|
||||||
country := parse(t, "country", "code\nSE\nNO\n", Options{Key: "code"})
|
country := parse(t, "country", "code\nSE\nNO\n", Options{Key: "code"})
|
||||||
city := parse(t, "city", "country\tname\nSE\tLund\nSE\tBorg\n", Options{Parent: "country"})
|
city := parse(t, "city", "country\tname\nSE\tLund\nSE\tBorg\n", Options{Parent: "country"})
|
||||||
|
|||||||
@@ -190,8 +190,6 @@ func TestNameErrors(t *testing.T) {
|
|||||||
`no field "zz"`},
|
`no field "zz"`},
|
||||||
{"read once through a field path that does not resolve", map[string]string{"card": `{"format":"{place as p}{p.zz}","place":{"format":"{x}","x":["a","b"]}}`},
|
{"read once through a field path that does not resolve", map[string]string{"card": `{"format":"{place as p}{p.zz}","place":{"format":"{x}","x":["a","b"]}}`},
|
||||||
`no field "zz"`},
|
`no field "zz"`},
|
||||||
{"read by nothing", map[string]string{"word": `["a","b"]`, "card": `"{/word as w}"`},
|
|
||||||
""},
|
|
||||||
{"one arm read twice in an alternation", map[string]string{"cat": `{"format":"{w|w}","w":["a","b"]}`, "card": `"{/cat as n}{n} {n.w}"`},
|
{"one arm read twice in an alternation", map[string]string{"cat": `{"format":"{w|w}","w":["a","b"]}`, "card": `"{/cat as n}{n} {n.w}"`},
|
||||||
""},
|
""},
|
||||||
{"a field and a path into it in one alternation", map[string]string{"cat": `{"format":"{w|w.x}","w":{"format":"{x}","x":["a","b"]}}`, "card": `"{/cat as n}{n} {n.w}"`},
|
{"a field and a path into it in one alternation", map[string]string{"cat": `{"format":"{w|w.x}","w":{"format":"{x}","x":["a","b"]}}`, "card": `"{/cat as n}{n} {n.w}"`},
|
||||||
@@ -250,28 +248,6 @@ func TestNameErrors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestANameReadOnceLoads(t *testing.T) {
|
|
||||||
for name, files := range map[string]map[string]string{
|
|
||||||
"through a path": {"word": `{"format":"{w}","w":["a","b"]}`, "card": `"{/word as a}{a.w} {/word.w}"`},
|
|
||||||
"whole, bound to a reference path": {"word": `{"format":"{w}","w":["a","b"]}`, "card": `"{/word.w as c}{c} {/word.w}"`},
|
|
||||||
"through a step up": {"region.json": nameTables()["region.json"], "region.tsv": nameTables()["region.tsv"], "municipality.json": nameTables()["municipality.json"], "municipality.tsv": nameTables()["municipality.tsv"], "card": `"{/municipality as m}{m..region.name}"`},
|
|
||||||
"as a calc operand": {"word": `["1","2"]`, "card": `"{/word as w}{calc(w * 2)}"`},
|
|
||||||
"whole": {"word": `["a","b"]`, "card": `{"format":"{/word as w}{x}","x":"{w}"}`},
|
|
||||||
"whole, as a transform's operand": {"word": `["a","b"]`, "card": `"{/word as w}{uppercase(w)}"`},
|
|
||||||
} {
|
|
||||||
withJSON := map[string]string{}
|
|
||||||
for file, body := range files {
|
|
||||||
if !strings.Contains(file, ".") {
|
|
||||||
file += ".json"
|
|
||||||
}
|
|
||||||
withJSON[file] = body
|
|
||||||
}
|
|
||||||
if _, err := New(WithoutShippedData(), WithDataPath(writeFiles(t, withJSON))); err != nil {
|
|
||||||
t.Errorf("%s: New() = %v, want it to load", name, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestANameBindsAReferenceFromItsFolder(t *testing.T) {
|
func TestANameBindsAReferenceFromItsFolder(t *testing.T) {
|
||||||
dir := writeData(t, map[string]string{
|
dir := writeData(t, map[string]string{
|
||||||
"sv/word": `["a","b","c","d","e","f","g","h"]`,
|
"sv/word": `["a","b","c","d","e","f","g","h"]`,
|
||||||
|
|||||||
@@ -5,14 +5,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAChoiceWithNothingToDrawIsRejected(t *testing.T) {
|
|
||||||
for _, src := range []string{`[{"format":"A","weight":0},{"format":"B","weight":0}]`, `[]`} {
|
|
||||||
if _, err := resolved(t, src); err == nil {
|
|
||||||
t.Errorf("compile(%s) = nil error, want a choice with nothing to draw refused", src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWeightSkewsDistribution(t *testing.T) {
|
func TestWeightSkewsDistribution(t *testing.T) {
|
||||||
f := engine(9)
|
f := engine(9)
|
||||||
heavy := 0
|
heavy := 0
|
||||||
|
|||||||
+12
-2
@@ -127,15 +127,25 @@ func TestAFieldBindingIsRefusedWhereNoFieldIs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestANameReadOnceIsWhatItBinds(t *testing.T) {
|
func TestANameReadOnceIsWhatItBinds(t *testing.T) {
|
||||||
|
word := `"word":{"format":"{w}","w":["a","b"]}`
|
||||||
for long, short := range map[string]string{
|
for long, short := range map[string]string{
|
||||||
`{"format":"{place as p}{p.x}","place":{"format":"{x}","x":["a","b"]}}`: `{"format":"{place.x}","place":{"format":"{x}","x":["a","b"]}}`,
|
`{"format":"{place as p}{p.x}","place":{"format":"{x}","x":["a","b"]}}`: `{"format":"{place.x}","place":{"format":"{x}","x":["a","b"]}}`,
|
||||||
`{"format":"{place as p}{p}","place":["x","y"]}`: `{"format":"{place}","place":["x","y"]}`,
|
`{"format":"{place as p}{p}","place":["x","y"]}`: `{"format":"{place}","place":["x","y"]}`,
|
||||||
`{"format":"{place as p}{calc(p * 2)}","place":["1","2"]}`: `{"format":"{calc(place * 2)}","place":["1","2"]}`,
|
`{"format":"{place as p}{calc(p * 2)}","place":["1","2"]}`: `{"format":"{calc(place * 2)}","place":["1","2"]}`,
|
||||||
|
`{"format":"{place as p}{uppercase(p)}","place":["x","y"]}`: `{"format":"{uppercase(place)}","place":["x","y"]}`,
|
||||||
|
`{"format":"{place as p}{x}","x":"{p}","place":["x","y"]}`: `{"format":"{place}","place":["x","y"]}`,
|
||||||
|
`{"format":"{word as a}{a.w} {word.w}",` + word + `}`: `{"format":"{word.w} {word.w}",` + word + `}`,
|
||||||
|
`{"format":"{word.w as c}{c} {word.w}",` + word + `}`: `{"format":"{word.w} {word.w}",` + word + `}`,
|
||||||
|
`{"format":"{n}|{x}","x":{"format":"{a as n}{a}","a":["1","2"]}}`: `{"format":"{x.a}|{x}","x":{"format":"{a}","a":["1","2"]}}`,
|
||||||
} {
|
} {
|
||||||
sameRenders(t, long, short)
|
sameRenders(t, long, short)
|
||||||
}
|
}
|
||||||
if _, err := resolved(t, `{"format":"{n}|{x}","x":{"format":"{a as n}{a}","a":["1","2"]}}`); err != nil {
|
files := with(nameTables(), map[string]string{"long.json": `"{/municipality as m}{m..region.name}"`, "short.json": `"{/municipality..region.name}"`})
|
||||||
t.Errorf("a name bound in a field and read once above it = %v, want it loaded", err)
|
a, b := newGenerator(t, writeFiles(t, files), WithSeed(1)), newGenerator(t, writeFiles(t, files), WithSeed(1))
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
if x, y := fake(t, a, "long"), fake(t, b, "short"); x != y {
|
||||||
|
t.Fatalf("a name read once through a step up rendered %q where its path rendered %q", x, y)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+18
-31
@@ -1,6 +1,7 @@
|
|||||||
package fejkdata
|
package fejkdata
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@@ -31,30 +32,39 @@ func TestOneItemChoiceIsItsItem(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPartThatDoesNothingIsIgnored(t *testing.T) {
|
func TestAPartWithNoEffectRendersAsWithoutIt(t *testing.T) {
|
||||||
for long, short := range map[string]string{
|
for long, short := range map[string]string{
|
||||||
|
`{"format":"Malmö"}`: `"Malmö"`,
|
||||||
|
`{"format":"{digits(3)}"}`: `"{digits(3)}"`,
|
||||||
|
`[{"format":"a","weight":1},"b"]`: `["a","b"]`,
|
||||||
|
`[{"format":"a","weight":0},"b"]`: `"b"`,
|
||||||
`{"format":"a","weight":2}`: `"a"`,
|
`{"format":"a","weight":2}`: `"a"`,
|
||||||
`{"format":"a","weight":0}`: `"a"`,
|
`{"format":"a","weight":0}`: `"a"`,
|
||||||
`{"format":"{x}","x":{"format":"a","weight":2}}`: `{"format":"{x}","x":"a"}`,
|
`{"format":"{x}","x":{"format":"a","weight":2}}`: `{"format":"{x}","x":"a"}`,
|
||||||
`[{"format":"a","weight":2}]`: `"a"`,
|
`[{"format":"a","weight":2}]`: `"a"`,
|
||||||
|
`{"format":"{x}","x":["a","b"],"repeat":1}`: `{"format":"{x}","x":["a","b"]}`,
|
||||||
`{"format":"{x}","x":["a","b"],"separator":","}`: `{"format":"{x}","x":["a","b"]}`,
|
`{"format":"{x}","x":["a","b"],"separator":","}`: `{"format":"{x}","x":["a","b"]}`,
|
||||||
|
`{"format":"{x}","x":["a","b"],"repeat":2,"separator":""}`: `{"format":"{x}","x":["a","b"],"repeat":2}`,
|
||||||
|
`{"format":"","n":{"format":"{x}","x":["1","2"],"datatype":"string"}}`: `{"format":"","n":{"format":"{x}","x":["1","2"]}}`,
|
||||||
`{"format":"{n}","repeat":2,"n":{"format":"1","datatype":"integer"}}`: `{"format":"{n}","repeat":2,"n":"1"}`,
|
`{"format":"{n}","repeat":2,"n":{"format":"1","datatype":"integer"}}`: `{"format":"{n}","repeat":2,"n":"1"}`,
|
||||||
`[{"format":"1","datatype":"integer"},"x"]`: `["1","x"]`,
|
`[{"format":"1","datatype":"integer"},"x"]`: `["1","x"]`,
|
||||||
|
`{"format":"{word as w}x","word":["a","b"]}`: `"x"`,
|
||||||
`null`: `""`,
|
`null`: `""`,
|
||||||
`{"format":"{p}","p":{"format":"{x}","x":[null,"a"]}}`: `{"format":"{p}","p":{"format":"{x}","x":["","a"]}}`,
|
`{"format":"{p}","p":{"format":"{x}","x":[null,"a"]}}`: `{"format":"{p}","p":{"format":"{x}","x":["","a"]}}`,
|
||||||
`[{"format":"a","weight":0},"b"]`: `"b"`,
|
|
||||||
`"{int(5,5)}"`: `"5"`,
|
`"{int(5,5)}"`: `"5"`,
|
||||||
`"{float(1,1,2)}"`: `"1.00"`,
|
`"{float(1,1,2)}"`: `"1.00"`,
|
||||||
`"{date(1990-01-01,1990-01-01,'2006-01-02')}"`: `"1990-01-01"`,
|
`"{date(1990-01-01,1990-01-01,'2006-01-02')}"`: `"1990-01-01"`,
|
||||||
`"{date(1990-01-01,1990-12-31,'x')}"`: `"x"`,
|
`"{date(1990-01-01,1990-12-31,'x')}"`: `"x"`,
|
||||||
`"{time('x')}"`: `"x"`,
|
`"{time('x')}"`: `"x"`,
|
||||||
|
`"{time('2006-01-02')}"`: `"1970-01-01"`,
|
||||||
} {
|
} {
|
||||||
sameRenders(t, long, short)
|
sameRenders(t, long, short)
|
||||||
}
|
}
|
||||||
for _, src := range []string{`"{date(1990-01-01,1990-12-31,'15:04')}"`, `"{time('2006-01-02 15:04')}"`} {
|
if r := compiled(t, `{"format":"","n":{"format":"1","datatype":"string"}}`).(*template); !r.isRecord || *r.fields["n"].(*template).datatype != DataTypeString {
|
||||||
if _, err := resolved(t, src); err != nil {
|
t.Error("a column of datatype string is no string column of a record")
|
||||||
t.Errorf("compile(%s) = %v, want a layout of either kind rendered", src, err)
|
|
||||||
}
|
}
|
||||||
|
if got := mustRender(t, engine(1), `"{date(1990-01-01,1990-12-31,'15:04')}"`); !regexp.MustCompile(`^\d\d:\d\d$`).MatchString(got) {
|
||||||
|
t.Errorf("date with a clock-only layout = %q, want a clock", got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,40 +87,17 @@ func TestAJSONNumberOrBooleanIsItsText(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestARepeatedItemCountsAsWritten(t *testing.T) {
|
func TestARepeatedItemCountsAsWritten(t *testing.T) {
|
||||||
for _, src := range []string{`["a", "a", "b"]`, `[{"format":"{x}","x":"1"},{"format":"{x}","x":"1"}]`, `{"format":"{w}","w":["", "", "x"]}`, `{"format":"","w":[null,null,"a"]}`, `{"format":"{x|x|y}","x":"1","y":"2"}`} {
|
for _, src := range []string{`["a", "a", "b"]`, `{"format":"{x|x|y}","x":"a","y":"b"}`} {
|
||||||
if _, err := resolved(t, src); err != nil {
|
f, n, as := engine(1), compiled(t, src), 0
|
||||||
t.Errorf("compile(%s) = %v, want it loaded", src, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f, n, as := engine(1), compiled(t, `["a", "a", "b"]`), 0
|
|
||||||
for i := 0; i < 600; i++ {
|
for i := 0; i < 600; i++ {
|
||||||
if renderOnce(f.drawState, n) == "a" {
|
if renderOnce(f.drawState, n) == "a" {
|
||||||
as++
|
as++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if as < 340 || as > 460 {
|
if as < 340 || as > 460 {
|
||||||
t.Errorf(`["a","a","b"] drew a %d times in 600, want about 400`, as)
|
t.Errorf("%s drew a %d times in 600, want about 400", src, as)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestADefaultWrittenOutIsTheDefault(t *testing.T) {
|
|
||||||
for long, short := range map[string]string{
|
|
||||||
`{"format":"Malmö"}`: `"Malmö"`,
|
|
||||||
`{"format":"{digits(3)}"}`: `"{digits(3)}"`,
|
|
||||||
`[{"format":"a","weight":1},"b"]`: `["a","b"]`,
|
|
||||||
`{"format":"{x}","x":["a","b"],"repeat":1}`: `{"format":"{x}","x":["a","b"]}`,
|
|
||||||
`{"format":"{x}","x":["a","b"],"repeat":2,"separator":""}`: `{"format":"{x}","x":["a","b"],"repeat":2}`,
|
|
||||||
`{"format":"","n":{"format":"{x}","x":["1","2"],"datatype":"string"}}`: `{"format":"","n":{"format":"{x}","x":["1","2"]}}`,
|
|
||||||
`{"format":"a","weight":1}`: `"a"`,
|
|
||||||
`[{"format":"a","weight":1}]`: `"a"`,
|
|
||||||
`{"format":"{x}","x":{"format":"a","weight":1}}`: `{"format":"{x}","x":"a"}`,
|
|
||||||
`{"format":"{x}","x":["a","b"],"separator":""}`: `{"format":"{x}","x":["a","b"]}`,
|
|
||||||
} {
|
|
||||||
sameRenders(t, long, short)
|
|
||||||
}
|
|
||||||
if r := compiled(t, `{"format":"","n":{"format":"1","datatype":"string"}}`).(*template); !r.isRecord || *r.fields["n"].(*template).datatype != DataTypeString {
|
|
||||||
t.Error("a column of datatype string is no string column of a record")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInlineFolderSigilsAreRejected(t *testing.T) {
|
func TestInlineFolderSigilsAreRejected(t *testing.T) {
|
||||||
|
|||||||
@@ -665,18 +665,6 @@ func TestTableFences(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSameShapedChoiceIsAChoice(t *testing.T) {
|
|
||||||
rows := `[{"format":"{name}","name":"Sweden","alpha2":"SE"},{"format":"{name}","name":"Norway","alpha2":"NO"},{"format":"{name}","name":"Denmark","alpha2":"DK"}]`
|
|
||||||
weighted := `[{"format":"{name}","name":"Sweden","weight":2},{"format":"{name}","name":"Norway"}]`
|
|
||||||
f := newGenerator(t, writeData(t, map[string]string{"country": rows, "weighted": weighted}), WithSeed(1))
|
|
||||||
if v := fake(t, f, "country"); v != "Sweden" && v != "Norway" && v != "Denmark" {
|
|
||||||
t.Fatalf("country = %q, want one of its items", v)
|
|
||||||
}
|
|
||||||
if v := fake(t, f, "weighted"); v != "Sweden" && v != "Norway" {
|
|
||||||
t.Fatalf("weighted = %q, want one of its items", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTableInAStructTag(t *testing.T) {
|
func TestTableInAStructTag(t *testing.T) {
|
||||||
f := newGenerator(t, writeFiles(t, geo()), WithSeed(1))
|
f := newGenerator(t, writeFiles(t, geo()), WithSeed(1))
|
||||||
var v struct {
|
var v struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user