(t *testing.T)
| 190 | } |
| 191 | |
| 192 | func TestCheckRuleNegative(t *testing.T) { |
| 193 | tests := []ast.Clause{ |
| 194 | clause("foo(X)."), |
| 195 | clause("foo(_)."), |
| 196 | clause("foo(_) :- bar(_)."), |
| 197 | clause("foo(X, _) :- foo(2, 1)."), |
| 198 | clause("foo(X) :- bar(Y)."), |
| 199 | clause("foo(X) :- X != Y, bar(Y)."), |
| 200 | clause("foo(X) :- X = Y."), |
| 201 | clause("foo(X) :- X < Y, foo(Y)."), |
| 202 | clause("foo(X) :- X = [Y]."), |
| 203 | clause("foo(X) :- X = fn:list(Y)."), |
| 204 | clause("foo(X) :- X = fn:list:get(1)."), |
| 205 | clause("foo(X) :- X = fn:list(fn:list:get(1))."), |
| 206 | clause("foo(X) :- X = fn:list(_)."), |
| 207 | // Head variable neither defined by body nor transform. |
| 208 | clause("foo(A) :- bar(X) |> let Y = fn:plus(X, X)."), |
| 209 | // Wildcard is like a variable neither defined by body nor transform. |
| 210 | clause("foo(Y) :- bar(X) |> let Y = fn:plus(X, _)."), |
| 211 | // Transform variable not defined by body. |
| 212 | clause("foo(Y) :- bar(X) |> do fn:group_by(A)."), |
| 213 | // Wildcard is like a variable not defined by body. |
| 214 | clause("foo(Y) :- bar(X) |> do fn:group_by(_)."), |
| 215 | // Wildcard references do not make sense in a transform. |
| 216 | clause("foo(Y) :- bar(X) |> let Y = fn:plus(X, X), let Z = fn:ring_the_alarm(_)."), |
| 217 | // A transform may not redefine a variable from body. |
| 218 | clause("foo(X) :- bar(X) |> let X = fn:plus(X, X)."), |
| 219 | // Wrong arity |
| 220 | clause("foo(Y) :- bar(X) |> let Y = fn:list:get(1)."), |
| 221 | // fn:collect() needs at least one argument. |
| 222 | clause("foo(X) :- bar(Y) |> do fn:group_by(), let X = fn:collect()."), |
| 223 | // fn:collect_distinct() needs at least one argument. |
| 224 | clause("foo(X) :- bar(Y) |> do fn:group_by(), let X = fn:collect_distinct()."), |
| 225 | // In a reducer, need to refer to variables from body. |
| 226 | clause("foo(X) :- bar(Y), baz(Z) |> do fn:group_by(Y), let X = fn:collect(X)."), |
| 227 | // nonsensical uses of fn:struct and fn:map |
| 228 | clause("foo(X) :- X = fn:struct(1)."), |
| 229 | clause("foo(X) :- X = fn:struct(1,2,3)."), |
| 230 | clause("foo(X) :- X = fn:map(1)."), |
| 231 | clause("foo(X) :- X = fn:map(1,2,3)."), |
| 232 | clause("foo(A) :- bar(Y), bar(Z) |> do fn:group_by(Y), let A = fn:plus(Z, 1)."), |
| 233 | } |
| 234 | for _, clause := range tests { |
| 235 | analyzer, _ := New(map[ast.PredicateSym]ast.Decl{ |
| 236 | ast.PredicateSym{"bar", 1}: makeSyntheticDecl(t, atom("bar(X)")), |
| 237 | }, nil, ErrorForBoundsMismatch) |
| 238 | if err := analyzer.CheckRule(clause); err == nil { |
| 239 | t.Errorf("Expected error for rule %v", clause) |
| 240 | } |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | func mustDesugar(t *testing.T, decls map[ast.PredicateSym]ast.Decl) map[ast.PredicateSym]*ast.Decl { |
| 245 | t.Helper() |
nothing calls this directly
no test coverage detected