func TestEventEqual(t *testing.T) { a := ast.NewValueMap() a.Put(ast.String("foo"), ast.Number("1")) b := ast.NewValueMap() b.Put(ast.String("foo"), ast.Number("2")) tests := []struct { a *Event b *Event equal bool }{ {&Event{}, &Event{}, true}, {&Event{Op: EvalOp}, &Event{Op: EnterOp}, false}, {&Event{QueryID: 1}, &Event{QueryID: 2}, false}, {&Event{ParentID: 1}, &Event{ParentID: 2}, false}, {&Event{Node: ast.MustParseBody("true")}, &Event{Node: ast.MustParseBody("false")}, false}, {&Event{Node: ast.MustParseBody("true")[0]}, &Event{Node: ast.MustParseBody("false")[0]}, false}, {&Event{Node: ast.MustParseRule("p :- true")}, &Event{Node: ast.MustParseRule("p :- false")}, false}, {&Event{Node: "foo"}, &Event{Node: "foo"}, false}, // test some unsupported node type } for _, tc := range tests { if tc.a.Equal(tc.b) != tc.equal { var s string if tc.equal { s = "==" } else { s = "!=" } t.Errorf("Expected %v %v %v", tc.a, s, tc.b) } } }
func runTruthTestCase(t *testing.T, data string, module string, n int, events map[int]*topdown.Event) { answer, _, err := explainQuery(data, module) if err != nil { t.Fatalf("Unexpected explanation error: %v", err) } if len(answer) != n { t.Errorf("Expected %d events but got: %v", n, len(answer)) } for i, event := range events { if i >= len(answer) { t.Errorf("Got %d events, cannot check event #%d", len(answer), i) continue } result := answer[i] bindings := ast.NewValueMap() event.Locals.Iter(func(k, v ast.Value) bool { if b := result.Locals.Get(k); b != nil { bindings.Put(k, b) } return false }) result.Locals = bindings if !result.Equal(event) { t.Errorf("Expected event #%d to be %v but got: %v", i, event, result) } } }
func parseBindings(s string) *ast.ValueMap { t := ast.MustParseTerm(s) obj, ok := t.Value.(ast.Object) if !ok { return nil } r := ast.NewValueMap() for _, pair := range obj { k, v := pair[0], pair[1] r.Put(k.Value, v.Value) } return r }
// Build initializes the references' index by walking the store for the reference and // creating the index that maps values to bindings. func (ind *indices) Build(ctx context.Context, store Store, txn Transaction, ref ast.Ref) error { index := newBindingIndex() ind.registerTriggers(store) err := iterStorage(ctx, store, txn, ref, ast.EmptyRef(), ast.NewValueMap(), func(bindings *ast.ValueMap, val interface{}) { index.Add(val, bindings) }) if err != nil { return err } hashCode := ref.Hash() head := ind.table[hashCode] entry := &indicesNode{ key: ref, val: index, next: head, } ind.table[hashCode] = entry return nil }
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 }