Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33
+12
-3
@@ -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
@@ -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
@@ -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"},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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`},
|
||||||
|
|||||||
Reference in New Issue
Block a user