gron/statements_test.go
2018-01-01 23:57:43 +00:00

205 lines
4.1 KiB
Go

package main
import (
"bytes"
"encoding/json"
"reflect"
"sort"
"testing"
)
func statementsFromStringSlice(strs []string) statements {
ss := make(statements, len(strs))
for i, str := range strs {
ss[i] = statementFromString(str)
}
return ss
}
func TestStatementsSimple(t *testing.T) {
j := []byte(`{
"dotted": "A dotted value",
"a quoted": "value",
"bool1": true,
"bool2": false,
"anull": null,
"anarr": [1, 1.5],
"anob": {
"foo": "bar"
},
"else": 1,
"id": 66912849,
"": 2
}`)
ss, err := statementsFromJSON(bytes.NewReader(j), statement{{"json", typBare}})
if err != nil {
t.Errorf("Want nil error from makeStatementsFromJSON() but got %s", err)
}
wants := statementsFromStringSlice([]string{
`json = {};`,
`json.dotted = "A dotted value";`,
`json["a quoted"] = "value";`,
`json.bool1 = true;`,
`json.bool2 = false;`,
`json.anull = null;`,
`json.anarr = [];`,
`json.anarr[0] = 1;`,
`json.anarr[1] = 1.5;`,
`json.anob = {};`,
`json.anob.foo = "bar";`,
`json["else"] = 1;`,
`json.id = 66912849;`,
`json[""] = 2;`,
})
t.Logf("Have: %#v", ss)
for _, want := range wants {
if !ss.Contains(want) {
t.Errorf("Statement group should contain `%s` but doesn't", want)
}
}
}
func TestStatementsSorting(t *testing.T) {
want := statementsFromStringSlice([]string{
`json.a = true;`,
`json.b = true;`,
`json.c[0] = true;`,
`json.c[2] = true;`,
`json.c[10] = true;`,
`json.c[11] = true;`,
`json.c[21][2] = true;`,
`json.c[21][11] = true;`,
})
have := statementsFromStringSlice([]string{
`json.c[11] = true;`,
`json.c[21][2] = true;`,
`json.c[0] = true;`,
`json.c[2] = true;`,
`json.b = true;`,
`json.c[10] = true;`,
`json.c[21][11] = true;`,
`json.a = true;`,
})
sort.Sort(have)
for i := range want {
if !reflect.DeepEqual(have[i], want[i]) {
t.Errorf("Statements sorted incorrectly; want `%s` at index %d, have `%s`", want[i], i, have[i])
}
}
}
func BenchmarkStatementsLess(b *testing.B) {
ss := statementsFromStringSlice([]string{
`json.c[21][2] = true;`,
`json.c[21][11] = true;`,
})
for i := 0; i < b.N; i++ {
_ = ss.Less(0, 1)
}
}
func BenchmarkFill(b *testing.B) {
j := []byte(`{
"dotted": "A dotted value",
"a quoted": "value",
"bool1": true,
"bool2": false,
"anull": null,
"anarr": [1, 1.5],
"anob": {
"foo": "bar"
},
"else": 1
}`)
var top interface{}
err := json.Unmarshal(j, &top)
if err != nil {
b.Fatalf("Failed to unmarshal test file: %s", err)
}
for i := 0; i < b.N; i++ {
ss := make(statements, 0)
ss.fill(statement{{"json", typBare}}, top)
}
}
func TestUngronStatementsSimple(t *testing.T) {
in := statementsFromStringSlice([]string{
`json.contact = {};`,
`json.contact["e-mail"][0] = "mail@tomnomnom.com";`,
`json.contact["e-mail"][1] = "test@tomnomnom.com";`,
`json.contact["e-mail"][3] = "foo@tomnomnom.com";`,
`json.contact.twitter = "@TomNomNom";`,
})
want := map[string]interface{}{
"json": map[string]interface{}{
"contact": map[string]interface{}{
"e-mail": []interface{}{
0: "mail@tomnomnom.com",
1: "test@tomnomnom.com",
3: "foo@tomnomnom.com",
},
"twitter": "@TomNomNom",
},
},
}
have, err := in.toInterface()
if err != nil {
t.Fatalf("want nil error but have: %s", err)
}
t.Logf("Have: %#v", have)
t.Logf("Want: %#v", want)
eq := reflect.DeepEqual(have, want)
if !eq {
t.Errorf("have and want are not equal")
}
}
func TestUngronStatementsInvalid(t *testing.T) {
cases := []statements{
statementsFromStringSlice([]string{``}),
statementsFromStringSlice([]string{`this isn't a statement at all`}),
statementsFromStringSlice([]string{`json[0] = 1;`, `json.bar = 1;`}),
}
for _, c := range cases {
_, err := c.toInterface()
if err == nil {
t.Errorf("want non-nil error; have nil")
}
}
}
func TestStatement(t *testing.T) {
s := statement{
token{"json", typBare},
token{".", typDot},
token{"foo", typBare},
token{"=", typEquals},
token{"2", typNumber},
token{";", typSemi},
}
have := s.String()
want := "json.foo = 2;"
if have != want {
t.Errorf("have: `%s` want: `%s`", have, want)
}
}