| 517 | } |
| 518 | |
| 519 | func TestParseClausePositive(t *testing.T) { |
| 520 | tests := []struct { |
| 521 | name string |
| 522 | str string |
| 523 | want ast.Clause |
| 524 | }{ |
| 525 | { |
| 526 | name: "bodiless clause 1", |
| 527 | str: "foo(/bar.baz.Bak).", |
| 528 | want: ast.NewClause(ast.NewAtom("foo", name("/bar.baz.Bak")), nil), |
| 529 | }, |
| 530 | { |
| 531 | name: "bodiless clause 2; invalid but should parse ok.", |
| 532 | str: "foo(X).", |
| 533 | want: ast.NewClause(ast.NewAtom("foo", ast.Variable{"X"}), nil), |
| 534 | }, |
| 535 | { |
| 536 | name: "weird recursive clause", |
| 537 | str: "foo(/bar-1logjam) :- foo(/bar-1logjam).", |
| 538 | want: ast.NewClause( |
| 539 | ast.NewAtom("foo", name("/bar-1logjam")), |
| 540 | []ast.Term{ |
| 541 | ast.NewAtom("foo", name("/bar-1logjam")), |
| 542 | }, |
| 543 | ), |
| 544 | }, |
| 545 | { |
| 546 | name: "weird clause with body", |
| 547 | str: "foo(Xyz) :- Xyz = /foo, /foo != Xyz.", |
| 548 | want: ast.NewClause(ast.NewAtom("foo", ast.Variable{"Xyz"}), []ast.Term{ |
| 549 | ast.Eq{ast.Variable{"Xyz"}, name("/foo")}, |
| 550 | ast.Ineq{name("/foo"), ast.Variable{"Xyz"}}, |
| 551 | }), |
| 552 | }, |
| 553 | } |
| 554 | for _, test := range tests { |
| 555 | t.Run(test.name, func(t *testing.T) { |
| 556 | got, err := Clause(test.str) |
| 557 | if err != nil { |
| 558 | t.Fatalf("Clause(%v) failed with %v", test.str, err) |
| 559 | } |
| 560 | if !got.Head.Equals(test.want.Head) { |
| 561 | t.Fatalf("Clause(%v) = %v want %v", test.str, got, test.want) |
| 562 | } |
| 563 | if diff := cmp.Diff(test.want.Premises, got.Premises, cmp.Comparer(equals)); diff != "" { |
| 564 | t.Errorf("Clause(%v) = %v want %v diff %v", test.str, got, test.want.Premises, diff) |
| 565 | } |
| 566 | }) |
| 567 | } |
| 568 | } |
| 569 | |
| 570 | func TestParseClauseNegative(t *testing.T) { |
| 571 | tests := []struct { |