func TestQueryV1(t *testing.T) { f := newFixture(t) get := newReqV1("GET", `/query?q=a=[1,2,3],a[i]=x`, "") f.server.Handler.ServeHTTP(f.recorder, get) if f.recorder.Code != 200 { t.Errorf("Expected success but got %v", f.recorder) return } var expected adhocQueryResultSetV1 err := util.UnmarshalJSON([]byte(`[{"a":[1,2,3],"i":0,"x":1},{"a":[1,2,3],"i":1,"x":2},{"a":[1,2,3],"i":2,"x":3}]`), &expected) if err != nil { panic(err) } var result adhocQueryResultSetV1 err = util.UnmarshalJSON(f.recorder.Body.Bytes(), &result) if err != nil { t.Errorf("Unexpected error while unmarshalling result: %v", err) return } if !reflect.DeepEqual(result, expected) { t.Errorf("Expected %v but got: %v", expected, result) } }
func TestOneShotJSON(t *testing.T) { ctx := context.Background() store := newTestStore() var buffer bytes.Buffer repl := newRepl(store, &buffer) repl.outputFormat = "json" repl.OneShot(ctx, "data.a[i] = x") var expected interface{} input := ` [ { "i": 0, "x": { "b": { "c": [ true, 2, false ] } } }, { "i": 1, "x": { "b": { "c": [ false, true, 1 ] } } } ] ` if err := util.UnmarshalJSON([]byte(input), &expected); err != nil { panic(err) } var result interface{} if err := util.UnmarshalJSON(buffer.Bytes(), &result); err != nil { t.Errorf("Unexpected output format: %v", err) return } if !reflect.DeepEqual(expected, result) { t.Errorf("Expected %v but got: %v", expected, result) } }
func TestMergeDocs(t *testing.T) { tests := []struct { a string b string c interface{} }{ {`{"x": 1, "y": 2}`, `{"z": 3}`, `{"x": 1, "y": 2, "z": 3}`}, {`{"x": {"y": 2}}`, `{"z": 3, "x": {"q": 4}}`, `{"x": {"y": 2, "q": 4}, "z": 3}`}, {`{"x": 1}`, `{"x": 1}`, fmt.Errorf("x: merge error: json.Number cannot merge into json.Number")}, {`{"x": {"y": [{"z": 2}]}}`, `{"x": {"y": [{"z": 3}]}}`, fmt.Errorf("x: y: merge error: []interface {} cannot merge into []interface {}")}, } for _, tc := range tests { a := map[string]interface{}{} if err := util.UnmarshalJSON([]byte(tc.a), &a); err != nil { panic(err) } b := map[string]interface{}{} if err := util.UnmarshalJSON([]byte(tc.b), &b); err != nil { panic(err) } switch c := tc.c.(type) { case error: _, err := mergeDocs(a, b) if !reflect.DeepEqual(err.Error(), c.Error()) { t.Errorf("Expected error to be exactly %v but got: %v", c, err) } case string: expected := map[string]interface{}{} if err := util.UnmarshalJSON([]byte(c), &expected); err != nil { panic(err) } result, err := mergeDocs(a, b) if err != nil { t.Errorf("Unexpected error on merge(%v, %v): %v", a, b, err) continue } if !reflect.DeepEqual(result, expected) { t.Errorf("Expected merge(%v, %v) to be %v but got: %v", a, b, expected, result) } } } }
func TestInterfaceToValue(t *testing.T) { input := ` { "x": [ 1, true, false, null, "hello", ["goodbye", 1], {"y": 3.1} ] } ` var x interface{} if err := util.UnmarshalJSON([]byte(input), &x); err != nil { panic(err) } expected := MustParseTerm(input).Value v, err := InterfaceToValue(x) if err != nil { t.Errorf("Unexpected error converting interface{} to ast.Value: %v", err) return } if !v.Equal(expected) { t.Errorf("Expected ast.Value to equal:\n%v\nBut got:\n%v", expected, v) } }
// UnmarshalJSON parses the byte array and stores the result in expr. func (expr *Expr) UnmarshalJSON(bs []byte) error { v := map[string]interface{}{} if err := util.UnmarshalJSON(bs, &v); err != nil { return err } return unmarshalExpr(expr, v) }
func parseJSON(s string) interface{} { var x interface{} if err := util.UnmarshalJSON([]byte(s), &x); err != nil { panic(err) } return x }
func TestIndicesAdd(t *testing.T) { indices := newIndices() data := loadSmallTestData() store := NewDataStoreFromJSONObject(data) ref := ast.MustParseRef("data.d[x][y]") // TODO(tsandall): indices.Build(context.Background(), store, invalidTXN, ref) index := indices.Get(ref) // new value to add var val1 interface{} err := util.UnmarshalJSON([]byte(`{"x":[1,true]}`), &val1) if err != nil { panic(err) } bindings1 := loadExpectedBindings(`[{"x": "e", "y": 2}]`)[0] index.Add(val1, bindings1) assertBindingsEqual(t, "new value", index, val1, `[{"x": "e", "y": 2}]`) // existing value val2 := "baz" bindings2 := loadExpectedBindings(`[{"x": "e", "y": 3}]`)[0] index.Add(val2, bindings2) assertBindingsEqual(t, "existing value", index, val2, `[{"x": "e", "y": 1}, {"x": "e", "y": 3}]`) index.Add(val2, bindings2) assertBindingsEqual(t, "same value (no change)", index, val2, `[{"x": "e", "y": 1}, {"x": "e", "y": 3}]`) }
func TestModuleJSONRoundTrip(t *testing.T) { mod := MustParseModule(` package a.b.c import data.x.y as z import data.u.i p = [1,2,{"foo":3.14}] :- r[x] = 1, not q[x] r[y] = v :- i[1] = y, v = i[2] q[x] :- a=[true,false,null,{"x":[1,2,3]}], a[i] = x t = true :- xs = [{"x": a[i].a} | a[i].n = "bob", b[x]] s = {1,2,3} :- true s = set() :- false empty_obj :- {} empty_arr :- [] empty_set :- set() `) bs, err := json.Marshal(mod) if err != nil { t.Fatalf("Unexpected error: %v", err) } roundtrip := &Module{} err = util.UnmarshalJSON(bs, roundtrip) if err != nil { t.Fatalf("Unexpected error: %v", err) } if !roundtrip.Equal(mod) { t.Fatalf("Expected roundtripped module to be equal to original:\nExpected:\n\n%v\n\nGot:\n\n%v\n", mod, roundtrip) } }
func TestEvalBodyCompileError(t *testing.T) { ctx := context.Background() store := newTestStore() var buffer bytes.Buffer repl := newRepl(store, &buffer) repl.outputFormat = "json" err := repl.OneShot(ctx, "x = 1, y > x") if _, ok := err.(ast.Errors); !ok { t.Fatalf("Expected error message in output but got`: %v", buffer.String()) } buffer.Reset() repl.OneShot(ctx, "x = 1, y = 2, y > x") var result2 []interface{} err = util.UnmarshalJSON(buffer.Bytes(), &result2) if err != nil { t.Errorf("Expected valid JSON output but got: %v", buffer.String()) return } expected2 := []interface{}{ map[string]interface{}{ "x": json.Number("1"), "y": json.Number("2"), }, } if !reflect.DeepEqual(expected2, result2) { t.Errorf(`Expected [{"x": 1, "y": 2}] but got: %v"`, result2) return } }
func (te *traceEventV1) UnmarshalJSON(bs []byte) error { keys := map[string]json.RawMessage{} if err := util.UnmarshalJSON(bs, &keys); err != nil { return err } if err := util.UnmarshalJSON(keys["Type"], &te.Type); err != nil { return err } if err := util.UnmarshalJSON(keys["Op"], &te.Op); err != nil { return err } if err := util.UnmarshalJSON(keys["QueryID"], &te.QueryID); err != nil { return err } if err := util.UnmarshalJSON(keys["ParentID"], &te.ParentID); err != nil { return err } switch te.Type { case nodeTypeBodyV1: var body ast.Body if err := util.UnmarshalJSON(keys["Node"], &body); err != nil { return err } te.Node = body case nodeTypeExprV1: var expr ast.Expr if err := util.UnmarshalJSON(keys["Node"], &expr); err != nil { return err } te.Node = &expr case nodeTypeRuleV1: var rule ast.Rule if err := util.UnmarshalJSON(keys["Node"], &rule); err != nil { return err } te.Node = &rule } if err := util.UnmarshalJSON(keys["Locals"], &te.Locals); err != nil { return err } return nil }
func loadExpectedResult(input string) interface{} { if len(input) == 0 { return nil } var data interface{} if err := util.UnmarshalJSON([]byte(input), &data); err != nil { panic(err) } return data }
func runTemplate(tmpl *template.Template, input interface{}) interface{} { var buf bytes.Buffer if err := tmpl.Execute(&buf, input); err != nil { panic(err) } var v interface{} if err := util.UnmarshalJSON(buf.Bytes(), &v); err != nil { panic(err) } return v }
func (f *fixture) executeRequest(req *http.Request, code int, resp string) error { f.reset() f.server.Handler.ServeHTTP(f.recorder, req) if f.recorder.Code != code { return fmt.Errorf("Expected code %v from %v %v but got: %v", req.Method, code, req.URL, f.recorder) } if resp != "" { var result interface{} if err := util.UnmarshalJSON([]byte(f.recorder.Body.String()), &result); err != nil { return fmt.Errorf("Expected JSON response from %v %v but got: %v", req.Method, req.URL, f.recorder) } var expected interface{} if err := util.UnmarshalJSON([]byte(resp), &expected); err != nil { panic(err) } if !reflect.DeepEqual(result, expected) { return fmt.Errorf("Expected JSON response from %v %v to equal %v but got: %v", req.Method, req.URL, expected, result) } } return nil }
// UnmarshalJSON parses the byte array and stores the result in term. // Specialized unmarshalling is required to handle Value. func (term *Term) UnmarshalJSON(bs []byte) error { v := map[string]interface{}{} if err := util.UnmarshalJSON(bs, &v); err != nil { return err } val, err := unmarshalValue(v) if err != nil { return err } term.Value = val return nil }
func TestDumpPath(t *testing.T) { ctx := context.Background() input := `{"a": [1,2,3,4]}` var data map[string]interface{} err := util.UnmarshalJSON([]byte(input), &data) if err != nil { panic(err) } store := storage.New(storage.InMemoryWithJSONConfig(data)) var buffer bytes.Buffer repl := newRepl(store, &buffer) dir, err := ioutil.TempDir("", "dump-path-test") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) file := filepath.Join(dir, "tmpfile") repl.OneShot(ctx, fmt.Sprintf("dump %s", file)) if buffer.String() != "" { t.Errorf("Expected no output but got: %v", buffer.String()) } bs, err := ioutil.ReadFile(file) if err != nil { t.Fatalf("Expected file read to succeed but got: %v", err) } var result map[string]interface{} if err := util.UnmarshalJSON(bs, &result); err != nil { t.Fatalf("Expected json unmarhsal to suceed but got: %v", err) } if !reflect.DeepEqual(data, result) { t.Fatalf("Expected dumped json to equal %v but got: %v", data, result) } }
func TestExprBadJSON(t *testing.T) { assert := func(js string, exp error) { expr := Expr{} err := util.UnmarshalJSON([]byte(js), &expr) if !reflect.DeepEqual(exp, err) { t.Errorf("For %v Expected %v but got: %v", js, exp, err) } } js := ` { "Negated": 100, "Terms": { "Value": "foo", "Type": "string" }, "Index": 0 } ` exp := fmt.Errorf("ast: unable to unmarshal Negated field with type: json.Number (expected true or false)") assert(js, exp) js = ` { "Terms": [ "foo" ], "Index": 0 } ` exp = fmt.Errorf("ast: unable to unmarshal term") assert(js, exp) js = ` { "Terms": "bad value", "Index": 0 } ` exp = fmt.Errorf(`ast: unable to unmarshal Terms field with type: string (expected {"Value": ..., "Type": ...} or [{"Value": ..., "Type": ...}, ...])`) assert(js, exp) js = ` { "Terms": {"Value": "foo", "Type": "string"} }` exp = fmt.Errorf("ast: unable to unmarshal Index field with type: <nil> (expected integer)") assert(js, exp) }
func TestDump(t *testing.T) { ctx := context.Background() input := `{"a": [1,2,3,4]}` var data map[string]interface{} err := util.UnmarshalJSON([]byte(input), &data) if err != nil { panic(err) } store := storage.New(storage.InMemoryWithJSONConfig(data)) var buffer bytes.Buffer repl := newRepl(store, &buffer) repl.OneShot(ctx, "dump") expectOutput(t, buffer.String(), "{\"a\":[1,2,3,4]}\n") }
func loadSmallTestData() map[string]interface{} { var data map[string]interface{} err := util.UnmarshalJSON([]byte(`{ "a": [1,2,3,4], "b": { "v1": "hello", "v2": "goodbye" }, "c": [{ "x": [true, false, "foo"], "y": [null, 3.14159], "z": {"p": true, "q": false} }], "d": { "e": ["bar", "baz"] }, "g": { "a": [1, 0, 0, 0], "b": [0, 2, 0, 0], "c": [0, 0, 0, 4] }, "h": [ [1,2,3], [2,3,4] ], "l": [ { "a": "bob", "b": -1, "c": [1,2,3,4] }, { "a": "alice", "b": 1, "c": [2,3,4,5], "d": null } ] }`), &data) if err != nil { panic(err) } return data }
func TestTermBadJSON(t *testing.T) { input := `{ "Value": [[ {"Value": [{"Value": "a", "Type": "var"}, {"Value": "x", "Type": "string"}], "Type": "ref"}, {"Value": [{"Value": "x", "Type": "var"}], "Type": "array"} ], [ {"Value": 100, "Type": "array"}, {"Value": "foo", "Type": "string"} ]], "Type": "object" }` term := Term{} err := util.UnmarshalJSON([]byte(input), &term) expected := fmt.Errorf("ast: unable to unmarshal term") if !reflect.DeepEqual(expected, err) { t.Errorf("Expected %v but got: %v", expected, err) } }
func loadExpectedBindings(input string) []*ast.ValueMap { var data []map[string]interface{} if err := util.UnmarshalJSON([]byte(input), &data); err != nil { panic(err) } var expected []*ast.ValueMap for _, bindings := range data { buf := ast.NewValueMap() for k, v := range bindings { switch v := v.(type) { case string: buf.Put(ast.Var(k), ast.String(v)) case json.Number: buf.Put(ast.Var(k), ast.Number(v)) default: panic("unreachable") } } expected = append(expected, buf) } return expected }
func executeQuery(data string, compiler *ast.Compiler, tracer topdown.Tracer) { topdown.ResetQueryIDs() d := map[string]interface{}{} if len(data) > 0 { if err := util.UnmarshalJSON([]byte(data), &d); err != nil { panic(err) } } ctx := context.Background() store := storage.New(storage.InMemoryWithJSONConfig(d)) txn := storage.NewTransactionOrDie(ctx, store) defer store.Close(ctx, txn) params := topdown.NewQueryParams(ctx, compiler, store, txn, nil, ast.MustParseRef("data.test.p")) params.Tracer = tracer _, err := topdown.Query(params) if err != nil { panic(err) } }
func newTestStore() *storage.Storage { input := ` { "a": [ { "b": { "c": [true,2,false] } }, { "b": { "c": [false,true,1] } } ] } ` var data map[string]interface{} err := util.UnmarshalJSON([]byte(input), &data) if err != nil { panic(err) } return storage.New(storage.InMemoryWithJSONConfig(data)) }
func TestEvalSingleTermMultiValue(t *testing.T) { ctx := context.Background() store := newTestStore() var buffer bytes.Buffer repl := newRepl(store, &buffer) repl.outputFormat = "json" input := ` [ { "data.a[i].b.c[_]": true, "i": 0 }, { "data.a[i].b.c[_]": 2, "i": 0 }, { "data.a[i].b.c[_]": false, "i": 0 }, { "data.a[i].b.c[_]": false, "i": 1 }, { "data.a[i].b.c[_]": true, "i": 1 }, { "data.a[i].b.c[_]": 1, "i": 1 } ]` var expected interface{} if err := util.UnmarshalJSON([]byte(input), &expected); err != nil { panic(err) } repl.OneShot(ctx, "data.a[i].b.c[_]") var result interface{} if err := util.UnmarshalJSON(buffer.Bytes(), &result); err != nil { t.Errorf("Expected valid JSON document: %v: %v", err, buffer.String()) return } if !reflect.DeepEqual(expected, result) { t.Errorf("Expected %v but got: %v", expected, result) return } buffer.Reset() repl.OneShot(ctx, "data.deadbeef[x]") s := buffer.String() if s != "undefined\n" { t.Errorf("Expected undefined from reference but got: %v", s) return } buffer.Reset() repl.OneShot(ctx, "p[x] :- a = [1,2,3,4], a[_] = x") buffer.Reset() repl.OneShot(ctx, "p[x]") input = ` [ { "x": 1 }, { "x": 2 }, { "x": 3 }, { "x": 4 } ] ` if err := util.UnmarshalJSON([]byte(input), &expected); err != nil { panic(err) } if err := util.UnmarshalJSON(buffer.Bytes(), &result); err != nil { t.Errorf("Expected valid JSON document: %v: %v", err, buffer.String()) return } if !reflect.DeepEqual(expected, result) { t.Errorf("Exepcted %v but got: %v", expected, result) } }