Beispiel #1
0
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)
		}
	}

}
Beispiel #2
0
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)
		}
	}
}
Beispiel #3
0
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
}
Beispiel #4
0
// 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
}
Beispiel #5
0
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
}