Helpers
(t *testing.T, program string)
| 86 | // Helpers |
| 87 | |
| 88 | func runEvaluate(t *testing.T, program string) []factstore.TemporalFact { |
| 89 | unit, err := parse.Unit(strings.NewReader(program)) |
| 90 | if err != nil { |
| 91 | t.Fatalf("Parse failed: %v", err) |
| 92 | } |
| 93 | |
| 94 | programInfo, err := analysis.AnalyzeOneUnit(unit, nil) |
| 95 | if err != nil { |
| 96 | t.Fatalf("Analyze failed: %v", err) |
| 97 | } |
| 98 | |
| 99 | store := factstore.NewTemporalStore() |
| 100 | err = engine.EvalProgram(programInfo, factstore.NewTemporalFactStoreAdapter(store), |
| 101 | engine.WithTemporalStore(store)) |
| 102 | if err != nil { |
| 103 | t.Fatalf("Eval failed: %v", err) |
| 104 | } |
| 105 | |
| 106 | var facts []factstore.TemporalFact |
| 107 | // Collect all facts |
| 108 | // We iterate over all predicates |
| 109 | for pred := range programInfo.Decls { |
| 110 | query := ast.Atom{Predicate: pred} |
| 111 | // Creating a dummy query atom with variables is hard without knowing arity/types easily |
| 112 | // But store.GetAllFacts takes a query atom. |
| 113 | // Let's just assume we can query everything. |
| 114 | // Actually, GetAllFacts isn't exposed on the interface easily like that? |
| 115 | // store.GetAllFacts takes a callback. |
| 116 | // We'll construct a query with variables. |
| 117 | args := make([]ast.BaseTerm, pred.Arity) |
| 118 | for i := 0; i < pred.Arity; i++ { |
| 119 | args[i] = ast.Variable{Symbol: "X"} // Same var ok? No, better unique. |
| 120 | } |
| 121 | query.Args = args |
| 122 | |
| 123 | store.GetAllFacts(query, func(tf factstore.TemporalFact) error { |
| 124 | facts = append(facts, tf) |
| 125 | return nil |
| 126 | }) |
| 127 | } |
| 128 | // Also for match(Name), which is not temporal in sequence test |
| 129 | // Ideally we check EDB/IDB predicates. |
| 130 | return facts |
| 131 | } |
| 132 | |
| 133 | func containsFact(facts []factstore.TemporalFact, prefix string) bool { |
| 134 | for _, f := range facts { |
no test coverage detected