github.com/unigraph-dev/dgraph@v1.1.1-0.20200923154953-8b52b426f765/query/query2_test.go (about) 1 /* 2 * Copyright 2018 Dgraph Labs, Inc. and Contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package query 18 19 import ( 20 "context" 21 "testing" 22 "time" 23 24 "github.com/stretchr/testify/require" 25 ) 26 27 func TestToFastJSONFilterUID(t *testing.T) { 28 29 query := ` 30 { 31 me(func: uid(0x01)) { 32 name 33 gender 34 friend @filter(anyofterms(name, "Andrea")) { 35 uid 36 } 37 } 38 } 39 ` 40 41 js := processQueryNoErr(t, query) 42 require.JSONEq(t, 43 `{"data": {"me":[{"name":"Michonne","gender":"female","friend":[{"uid":"0x1f"}]}]}}`, 44 js) 45 } 46 47 func TestToFastJSONFilterOrUID(t *testing.T) { 48 49 query := ` 50 { 51 me(func: uid(0x01)) { 52 name 53 gender 54 friend @filter(anyofterms(name, "Andrea") or anyofterms(name, "Andrea Rhee")) { 55 uid 56 name 57 } 58 } 59 } 60 ` 61 62 js := processQueryNoErr(t, query) 63 require.JSONEq(t, 64 `{"data": {"me":[{"name":"Michonne","gender":"female","friend":[{"uid":"0x18","name":"Glenn Rhee"},{"uid":"0x1f","name":"Andrea"}]}]}}`, 65 js) 66 } 67 68 func TestToFastJSONFilterOrCount(t *testing.T) { 69 70 query := ` 71 { 72 me(func: uid(0x01)) { 73 name 74 gender 75 count(friend @filter(anyofterms(name, "Andrea") or anyofterms(name, "Andrea Rhee"))) 76 friend @filter(anyofterms(name, "Andrea")) { 77 name 78 } 79 } 80 } 81 ` 82 83 js := processQueryNoErr(t, query) 84 require.JSONEq(t, 85 `{"data": {"me":[{"count(friend)":2,"friend": [{"name":"Andrea"}],"gender":"female","name":"Michonne"}]}}`, 86 js) 87 } 88 89 func TestToFastJSONFilterOrFirst(t *testing.T) { 90 91 query := ` 92 { 93 me(func: uid(0x01)) { 94 name 95 gender 96 friend(first:2) @filter(anyofterms(name, "Andrea") or anyofterms(name, "Glenn SomethingElse") or anyofterms(name, "Daryl")) { 97 name 98 } 99 } 100 } 101 ` 102 103 js := processQueryNoErr(t, query) 104 require.JSONEq(t, 105 `{"data": {"me":[{"friend":[{"name":"Glenn Rhee"},{"name":"Daryl Dixon"}],"gender":"female","name":"Michonne"}]}}`, 106 js) 107 } 108 109 func TestToFastJSONFilterOrOffset(t *testing.T) { 110 111 query := ` 112 { 113 me(func: uid(0x01)) { 114 name 115 gender 116 friend(offset:1) @filter(anyofterms(name, "Andrea") or anyofterms(name, "Glenn Rhee") or anyofterms(name, "Daryl Dixon")) { 117 name 118 } 119 } 120 } 121 ` 122 123 js := processQueryNoErr(t, query) 124 require.JSONEq(t, 125 `{"data": {"me":[{"friend":[{"name":"Daryl Dixon"},{"name":"Andrea"}],"gender":"female","name":"Michonne"}]}}`, 126 js) 127 } 128 129 func TestToFastJSONFiltergeName(t *testing.T) { 130 131 query := ` 132 { 133 me(func: uid(0x01)) { 134 friend @filter(ge(name, "Rick")) { 135 name 136 } 137 } 138 } 139 ` 140 141 js := processQueryNoErr(t, query) 142 require.JSONEq(t, 143 `{"data": {"me":[{"friend":[{"name":"Rick Grimes"}]}]}}`, 144 js) 145 } 146 147 func TestToFastJSONFilterLtAlias(t *testing.T) { 148 149 // We shouldn't get Zambo Alice. 150 query := ` 151 { 152 me(func: uid(0x01)) { 153 friend(orderasc: alias) @filter(lt(alias, "Pat")) { 154 alias 155 } 156 } 157 } 158 ` 159 160 js := processQueryNoErr(t, query) 161 require.JSONEq(t, 162 `{"data": {"me":[{"friend":[{"alias":"Allan Matt"},{"alias":"Bob Joe"},{"alias":"John Alice"},{"alias":"John Oliver"}]}]}}`, 163 js) 164 } 165 166 func TestToFastJSONFilterge1(t *testing.T) { 167 168 query := ` 169 { 170 me(func: uid(0x01)) { 171 name 172 gender 173 friend @filter(ge(dob, "1909-05-05")) { 174 name 175 } 176 } 177 } 178 ` 179 180 js := processQueryNoErr(t, query) 181 require.JSONEq(t, 182 `{"data": {"me":[{"friend":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"}],"gender":"female","name":"Michonne"}]}}`, 183 js) 184 } 185 186 func TestToFastJSONFilterge2(t *testing.T) { 187 188 query := ` 189 { 190 me(func: uid(0x01)) { 191 name 192 gender 193 friend @filter(ge(dob_day, "1909-05-05")) { 194 name 195 } 196 } 197 } 198 ` 199 200 js := processQueryNoErr(t, query) 201 require.JSONEq(t, 202 `{"data": {"me":[{"friend":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"}],"gender":"female","name":"Michonne"}]}}`, 203 js) 204 } 205 206 func TestToFastJSONFilterGt(t *testing.T) { 207 208 query := ` 209 { 210 me(func: uid(0x01)) { 211 name 212 gender 213 friend @filter(gt(dob, "1909-05-05")) { 214 name 215 } 216 } 217 } 218 ` 219 220 js := processQueryNoErr(t, query) 221 require.JSONEq(t, 222 `{"data": {"me":[{"friend":[{"name":"Rick Grimes"}],"gender":"female","name":"Michonne"}]}}`, 223 js) 224 } 225 226 func TestToFastJSONFilterle(t *testing.T) { 227 228 query := ` 229 { 230 me(func: uid(0x01)) { 231 name 232 gender 233 friend @filter(le(dob, "1909-01-10")) { 234 name 235 } 236 } 237 } 238 ` 239 240 js := processQueryNoErr(t, query) 241 require.JSONEq(t, 242 `{"data": {"me":[{"friend":[{"name":"Daryl Dixon"},{"name":"Andrea"}],"gender":"female","name":"Michonne"}]}}`, 243 js) 244 } 245 246 func TestToFastJSONFilterLt(t *testing.T) { 247 248 query := ` 249 { 250 me(func: uid(0x01)) { 251 name 252 gender 253 friend @filter(lt(dob, "1909-01-10")) { 254 name 255 } 256 } 257 } 258 ` 259 260 js := processQueryNoErr(t, query) 261 require.JSONEq(t, 262 `{"data": {"me":[{"friend":[{"name":"Andrea"}],"gender":"female","name":"Michonne"}]}}`, 263 js) 264 } 265 266 func TestToFastJSONFilterEqualNoHit(t *testing.T) { 267 268 query := ` 269 { 270 me(func: uid(0x01)) { 271 name 272 gender 273 friend @filter(eq(dob, "1909-03-20")) { 274 name 275 } 276 } 277 } 278 ` 279 280 js := processQueryNoErr(t, query) 281 require.JSONEq(t, 282 `{"data": {"me":[{"gender":"female","name":"Michonne"}]}}`, 283 js) 284 } 285 func TestToFastJSONFilterEqualName(t *testing.T) { 286 287 query := ` 288 { 289 me(func: uid(0x01)) { 290 name 291 gender 292 friend @filter(eq(name, "Daryl Dixon")) { 293 name 294 } 295 } 296 } 297 ` 298 299 js := processQueryNoErr(t, query) 300 require.JSONEq(t, 301 `{"data": {"me":[{"friend":[{"name":"Daryl Dixon"}], "gender":"female","name":"Michonne"}]}}`, 302 js) 303 } 304 305 func TestToFastJSONFilterEqualNameNoHit(t *testing.T) { 306 307 query := ` 308 { 309 me(func: uid(0x01)) { 310 name 311 gender 312 friend @filter(eq(name, "Daryl")) { 313 name 314 } 315 } 316 } 317 ` 318 319 js := processQueryNoErr(t, query) 320 require.JSONEq(t, 321 `{"data": {"me":[{"gender":"female","name":"Michonne"}]}}`, 322 js) 323 } 324 325 func TestToFastJSONFilterEqual(t *testing.T) { 326 327 query := ` 328 { 329 me(func: uid(0x01)) { 330 name 331 gender 332 friend @filter(eq(dob, "1909-01-10")) { 333 name 334 } 335 } 336 } 337 ` 338 339 js := processQueryNoErr(t, query) 340 require.JSONEq(t, 341 `{"data": {"me":[{"friend":[{"name":"Daryl Dixon"}], "gender":"female","name":"Michonne"}]}}`, 342 js) 343 } 344 345 func TestToFastJSONOrderName(t *testing.T) { 346 347 query := ` 348 { 349 me(func: uid(0x01)) { 350 name 351 friend(orderasc: alias) { 352 alias 353 } 354 } 355 } 356 ` 357 358 js := processQueryNoErr(t, query) 359 require.JSONEq(t, 360 `{"data": {"me":[{"friend":[{"alias":"Allan Matt"},{"alias":"Bob Joe"},{"alias":"John Alice"},{"alias":"John Oliver"},{"alias":"Zambo Alice"}],"name":"Michonne"}]}}`, 361 js) 362 } 363 364 func TestToFastJSONOrderNameDesc(t *testing.T) { 365 366 query := ` 367 { 368 me(func: uid(0x01)) { 369 name 370 friend(orderdesc: alias) { 371 alias 372 } 373 } 374 } 375 ` 376 377 js := processQueryNoErr(t, query) 378 require.JSONEq(t, 379 `{"data": {"me":[{"friend":[{"alias":"Zambo Alice"},{"alias":"John Oliver"},{"alias":"John Alice"},{"alias":"Bob Joe"},{"alias":"Allan Matt"}],"name":"Michonne"}]}}`, 380 js) 381 } 382 383 func TestToFastJSONOrderName1(t *testing.T) { 384 385 query := ` 386 { 387 me(func: uid(0x01)) { 388 name 389 friend(orderasc: name ) { 390 name 391 } 392 } 393 } 394 ` 395 396 js := processQueryNoErr(t, query) 397 require.JSONEq(t, 398 `{"data": {"me":[{"friend":[{"name":"Andrea"},{"name":"Daryl Dixon"},{"name":"Glenn Rhee"},{"name":"Rick Grimes"}],"name":"Michonne"}]}}`, 399 js) 400 } 401 402 func TestToFastJSONOrderNameError(t *testing.T) { 403 404 query := ` 405 { 406 me(func: uid(0x01)) { 407 name 408 friend(orderasc: nonexistent) { 409 name 410 } 411 } 412 } 413 ` 414 _, err := processQuery(context.Background(), t, query) 415 require.Error(t, err) 416 } 417 418 func TestToFastJSONFilterleOrder(t *testing.T) { 419 420 query := ` 421 { 422 me(func: uid(0x01)) { 423 name 424 gender 425 friend(orderasc: dob) @filter(le(dob, "1909-03-20")) { 426 name 427 } 428 } 429 } 430 ` 431 432 js := processQueryNoErr(t, query) 433 require.JSONEq(t, 434 `{"data": {"me":[{"friend":[{"name":"Andrea"},{"name":"Daryl Dixon"}],"gender":"female","name":"Michonne"}]}}`, 435 js) 436 } 437 438 func TestToFastJSONFiltergeNoResult(t *testing.T) { 439 440 query := ` 441 { 442 me(func: uid(0x01)) { 443 name 444 gender 445 friend @filter(ge(dob, "1999-03-20")) { 446 name 447 } 448 } 449 } 450 ` 451 452 js := processQueryNoErr(t, query) 453 require.JSONEq(t, 454 `{"data": {"me":[{"gender":"female","name":"Michonne"}]}}`, js) 455 } 456 457 func TestToFastJSONFirstOffsetOutOfBound(t *testing.T) { 458 459 query := ` 460 { 461 me(func: uid(0x01)) { 462 name 463 gender 464 friend(offset:100, first:1) { 465 name 466 } 467 } 468 } 469 ` 470 471 js := processQueryNoErr(t, query) 472 require.JSONEq(t, 473 `{"data": {"me":[{"gender":"female","name":"Michonne"}]}}`, 474 js) 475 } 476 477 // No filter. Just to test first and offset. 478 func TestToFastJSONFirstOffset(t *testing.T) { 479 480 query := ` 481 { 482 me(func: uid(0x01)) { 483 name 484 gender 485 friend(offset:1, first:1) { 486 name 487 } 488 } 489 } 490 ` 491 492 js := processQueryNoErr(t, query) 493 require.JSONEq(t, 494 `{"data": {"me":[{"friend":[{"name":"Glenn Rhee"}],"gender":"female","name":"Michonne"}]}}`, 495 js) 496 } 497 498 func TestToFastJSONFilterOrFirstOffset(t *testing.T) { 499 500 query := ` 501 { 502 me(func: uid(0x01)) { 503 name 504 gender 505 friend(offset:1, first:1) @filter(anyofterms(name, "Andrea") or anyofterms(name, "SomethingElse Rhee") or anyofterms(name, "Daryl Dixon")) { 506 name 507 } 508 } 509 } 510 ` 511 512 js := processQueryNoErr(t, query) 513 require.JSONEq(t, 514 `{"data": {"me":[{"friend":[{"name":"Daryl Dixon"}],"gender":"female","name":"Michonne"}]}}`, 515 js) 516 } 517 518 func TestToFastJSONFilterleFirstOffset(t *testing.T) { 519 520 query := ` 521 { 522 me(func: uid(0x01)) { 523 name 524 gender 525 friend(offset:1, first:1) @filter(le(dob, "1909-03-20")) { 526 name 527 } 528 } 529 } 530 ` 531 532 js := processQueryNoErr(t, query) 533 require.JSONEq(t, 534 `{"data": {"me":[{"friend":[{"name":"Andrea"}],"gender":"female","name":"Michonne"}]}}`, 535 js) 536 } 537 538 func TestToFastJSONFilterOrFirstOffsetCount(t *testing.T) { 539 540 query := ` 541 { 542 me(func: uid(0x01)) { 543 name 544 gender 545 count(friend(offset:1, first:1) @filter(anyofterms(name, "Andrea") or anyofterms(name, "SomethingElse Rhee") or anyofterms(name, "Daryl Dixon"))) 546 } 547 } 548 ` 549 550 js := processQueryNoErr(t, query) 551 require.JSONEq(t, 552 `{"data": {"me":[{"count(friend)":1,"gender":"female","name":"Michonne"}]}}`, 553 js) 554 } 555 556 func TestToFastJSONFilterOrFirstNegative(t *testing.T) { 557 558 // When negative first/count is specified, we ignore offset and returns the last 559 // few number of items. 560 query := ` 561 { 562 me(func: uid(0x01)) { 563 name 564 gender 565 friend(first:-1, offset:0) @filter(anyofterms(name, "Andrea") or anyofterms(name, "Glenn Rhee") or anyofterms(name, "Daryl Dixon")) { 566 name 567 } 568 } 569 } 570 ` 571 572 js := processQueryNoErr(t, query) 573 require.JSONEq(t, 574 `{"data": {"me":[{"friend":[{"name":"Andrea"}],"gender":"female","name":"Michonne"}]}}`, 575 js) 576 } 577 578 func TestToFastJSONFilterNot1(t *testing.T) { 579 580 query := ` 581 { 582 me(func: uid(0x01)) { 583 name 584 gender 585 friend @filter(not anyofterms(name, "Andrea rick")) { 586 name 587 } 588 } 589 } 590 ` 591 592 js := processQueryNoErr(t, query) 593 require.JSONEq(t, 594 `{"data": {"me":[{"gender":"female","name":"Michonne","friend":[{"name":"Glenn Rhee"},{"name":"Daryl Dixon"}]}]}}`, js) 595 } 596 597 func TestToFastJSONFilterNot2(t *testing.T) { 598 599 query := ` 600 { 601 me(func: uid(0x01)) { 602 name 603 gender 604 friend @filter(not anyofterms(name, "Andrea") and anyofterms(name, "Glenn Andrea")) { 605 name 606 } 607 } 608 } 609 ` 610 611 js := processQueryNoErr(t, query) 612 require.JSONEq(t, 613 `{"data": {"me":[{"gender":"female","name":"Michonne","friend":[{"name":"Glenn Rhee"}]}]}}`, js) 614 } 615 616 func TestToFastJSONFilterNot3(t *testing.T) { 617 618 query := ` 619 { 620 me(func: uid(0x01)) { 621 name 622 gender 623 friend @filter(not (anyofterms(name, "Andrea") or anyofterms(name, "Glenn Rick Andrea"))) { 624 name 625 } 626 } 627 } 628 ` 629 630 js := processQueryNoErr(t, query) 631 require.JSONEq(t, 632 `{"data": {"me":[{"gender":"female","name":"Michonne","friend":[{"name":"Daryl Dixon"}]}]}}`, js) 633 } 634 635 func TestToFastJSONFilterNot4(t *testing.T) { 636 637 query := ` 638 { 639 me(func: uid(0x01)) { 640 name 641 gender 642 friend (first:2) @filter(not anyofterms(name, "Andrea") 643 and not anyofterms(name, "glenn") 644 and not anyofterms(name, "rick") 645 ) { 646 name 647 } 648 } 649 } 650 ` 651 652 js := processQueryNoErr(t, query) 653 require.JSONEq(t, 654 `{"data": {"me":[{"gender":"female","name":"Michonne","friend":[{"name":"Daryl Dixon"}]}]}}`, js) 655 } 656 657 // TestToFastJSONFilterNot4 was unstable (fails observed locally and on travis). 658 // Following method repeats the query to make sure that it never fails. 659 // It's commented out, because it's too slow for everyday testing. 660 /* 661 func TestToFastJSONFilterNot4x1000000(t *testing.T) { 662 663 for i := 0; i < 1000000; i++ { 664 query := ` 665 { 666 me(func: uid(0x01)) { 667 name 668 gender 669 friend (first:2) @filter(not anyofterms(name, "Andrea") 670 and not anyofterms(name, "glenn") 671 and not anyofterms(name, "rick") 672 ) { 673 name 674 } 675 } 676 } 677 ` 678 679 js := processQueryNoErr(t, query) 680 require.JSONEq(t, 681 `{"data": {"me":[{"gender":"female","name":"Michonne","friend":[{"name":"Daryl Dixon"}]}]}}`, js, 682 "tzdybal: %d", i) 683 } 684 } 685 */ 686 687 func TestToFastJSONFilterAnd(t *testing.T) { 688 689 query := ` 690 { 691 me(func: uid(0x01)) { 692 name 693 gender 694 friend @filter(anyofterms(name, "Andrea") and anyofterms(name, "SomethingElse Rhee")) { 695 name 696 } 697 } 698 } 699 ` 700 701 js := processQueryNoErr(t, query) 702 require.JSONEq(t, 703 `{"data": {"me":[{"name":"Michonne","gender":"female"}]}}`, js) 704 } 705 706 func TestCountReverseFunc(t *testing.T) { 707 708 query := ` 709 { 710 me(func: ge(count(~friend), 2)) { 711 name 712 count(~friend) 713 } 714 } 715 ` 716 js := processQueryNoErr(t, query) 717 require.JSONEq(t, 718 `{"data": {"me":[{"name":"Glenn Rhee","count(~friend)":2}]}}`, 719 js) 720 } 721 722 func TestCountReverseFilter(t *testing.T) { 723 724 query := ` 725 { 726 me(func: anyofterms(name, "Glenn Michonne Rick")) @filter(ge(count(~friend), 2)) { 727 name 728 count(~friend) 729 } 730 } 731 ` 732 js := processQueryNoErr(t, query) 733 require.JSONEq(t, 734 `{"data": {"me":[{"name":"Glenn Rhee","count(~friend)":2}]}}`, 735 js) 736 } 737 738 func TestCountReverse(t *testing.T) { 739 740 query := ` 741 { 742 me(func: uid(0x18)) { 743 name 744 count(~friend) 745 } 746 } 747 ` 748 js := processQueryNoErr(t, query) 749 require.JSONEq(t, 750 `{"data": {"me":[{"name":"Glenn Rhee","count(~friend)":2}]}}`, 751 js) 752 } 753 754 func TestToFastJSONReverse(t *testing.T) { 755 756 query := ` 757 { 758 me(func: uid(0x18)) { 759 name 760 ~friend { 761 name 762 gender 763 alive 764 } 765 } 766 } 767 ` 768 js := processQueryNoErr(t, query) 769 require.JSONEq(t, 770 `{"data": {"me":[{"name":"Glenn Rhee","~friend":[{"alive":true,"gender":"female","name":"Michonne"},{"alive": false, "name":"Andrea"}]}]}}`, 771 js) 772 } 773 774 func TestToFastJSONReverseFilter(t *testing.T) { 775 776 query := ` 777 { 778 me(func: uid(0x18)) { 779 name 780 ~friend @filter(allofterms(name, "Andrea")) { 781 name 782 gender 783 } 784 } 785 } 786 ` 787 js := processQueryNoErr(t, query) 788 require.JSONEq(t, 789 `{"data": {"me":[{"name":"Glenn Rhee","~friend":[{"name":"Andrea"}]}]}}`, 790 js) 791 } 792 793 // Test sorting / ordering by dob. 794 func TestToFastJSONOrder(t *testing.T) { 795 796 query := ` 797 { 798 me(func: uid(0x01)) { 799 name 800 gender 801 friend(orderasc: dob) { 802 name 803 dob 804 } 805 } 806 } 807 ` 808 809 js := processQueryNoErr(t, query) 810 require.JSONEq(t, 811 `{"data": {"me":[{"name":"Michonne","gender":"female","friend":[{"name":"Andrea","dob":"1901-01-15T00:00:00Z"},{"name":"Daryl Dixon","dob":"1909-01-10T00:00:00Z"},{"name":"Glenn Rhee","dob":"1909-05-05T00:00:00Z"},{"name":"Rick Grimes","dob":"1910-01-02T00:00:00Z"}]}]}}`, 812 js) 813 } 814 815 // Test sorting / ordering by dob. 816 func TestToFastJSONOrderDesc1(t *testing.T) { 817 818 query := ` 819 { 820 me(func: uid(0x01)) { 821 name 822 gender 823 friend(orderdesc: dob) { 824 name 825 dob 826 } 827 } 828 } 829 ` 830 831 js := processQueryNoErr(t, query) 832 require.JSONEq(t, 833 `{"data": {"me":[{"friend":[{"dob":"1910-01-02T00:00:00Z","name":"Rick Grimes"},{"dob":"1909-05-05T00:00:00Z","name":"Glenn Rhee"},{"dob":"1909-01-10T00:00:00Z","name":"Daryl Dixon"},{"dob":"1901-01-15T00:00:00Z","name":"Andrea"}],"gender":"female","name":"Michonne"}]}}`, 834 js) 835 } 836 837 func TestToFastJSONOrderDesc2(t *testing.T) { 838 839 query := ` 840 { 841 me(func: uid(0x01)) { 842 name 843 gender 844 friend(orderdesc: dob_day) { 845 name 846 dob 847 } 848 } 849 } 850 ` 851 852 js := processQueryNoErr(t, query) 853 require.JSONEq(t, 854 `{"data": {"me":[{"friend":[{"dob":"1910-01-02T00:00:00Z","name":"Rick Grimes"},{"dob":"1909-05-05T00:00:00Z","name":"Glenn Rhee"},{"dob":"1909-01-10T00:00:00Z","name":"Daryl Dixon"},{"dob":"1901-01-15T00:00:00Z","name":"Andrea"}],"gender":"female","name":"Michonne"}]}}`, 855 js) 856 } 857 858 // Test sorting / ordering by dob. 859 func TestToFastJSONOrderDesc_pawan(t *testing.T) { 860 861 query := ` 862 { 863 me(func: uid(0x01)) { 864 name 865 gender 866 friend(orderdesc: film.film.initial_release_date) { 867 name 868 film.film.initial_release_date 869 } 870 } 871 } 872 ` 873 874 js := processQueryNoErr(t, query) 875 require.JSONEq(t, 876 `{"data": {"me":[{"friend":[{"film.film.initial_release_date":"1929-01-10T00:00:00Z","name":"Daryl Dixon"},{"film.film.initial_release_date":"1909-05-05T00:00:00Z","name":"Glenn Rhee"},{"film.film.initial_release_date":"1900-01-02T00:00:00Z","name":"Rick Grimes"},{"film.film.initial_release_date":"1801-01-15T00:00:00Z","name":"Andrea"}],"gender":"female","name":"Michonne"}]}}`, 877 js) 878 } 879 880 // Test sorting / ordering by dob. 881 func TestToFastJSONOrderDedup(t *testing.T) { 882 883 query := ` 884 { 885 me(func: uid(0x01)) { 886 friend(orderasc: name) { 887 dob 888 name 889 } 890 gender 891 name 892 } 893 } 894 ` 895 896 js := processQueryNoErr(t, query) 897 require.JSONEq(t, 898 `{"data": {"me":[{"friend":[{"dob":"1901-01-15T00:00:00Z","name":"Andrea"},{"dob":"1909-01-10T00:00:00Z","name":"Daryl Dixon"},{"dob":"1909-05-05T00:00:00Z","name":"Glenn Rhee"},{"dob":"1910-01-02T00:00:00Z","name":"Rick Grimes"}],"gender":"female","name":"Michonne"}]}}`, 899 js) 900 } 901 902 // Test sorting / ordering by dob and count. 903 func TestToFastJSONOrderDescCount(t *testing.T) { 904 905 query := ` 906 { 907 me(func: uid(0x01)) { 908 name 909 gender 910 count(friend @filter(anyofterms(name, "Rick")) (orderasc: dob)) 911 } 912 } 913 ` 914 915 js := processQueryNoErr(t, query) 916 require.JSONEq(t, 917 `{"data": {"me":[{"count(friend)":1,"gender":"female","name":"Michonne"}]}}`, 918 js) 919 } 920 921 // Test sorting / ordering by dob. 922 func TestToFastJSONOrderOffset(t *testing.T) { 923 924 query := ` 925 { 926 me(func: uid(0x01)) { 927 name 928 gender 929 friend(orderasc: dob, offset: 2) { 930 name 931 } 932 } 933 } 934 ` 935 936 js := processQueryNoErr(t, query) 937 require.JSONEq(t, 938 `{"data": {"me":[{"friend":[{"name":"Glenn Rhee"},{"name":"Rick Grimes"}],"gender":"female","name":"Michonne"}]}}`, 939 js) 940 } 941 942 // Test sorting / ordering by dob. 943 func TestToFastJSONOrderOffsetCount(t *testing.T) { 944 945 query := ` 946 { 947 me(func: uid(0x01)) { 948 name 949 gender 950 friend(orderasc: dob, offset: 2, first: 1) { 951 name 952 } 953 } 954 } 955 ` 956 957 js := processQueryNoErr(t, query) 958 require.JSONEq(t, 959 `{"data": {"me":[{"friend":[{"name":"Glenn Rhee"}],"gender":"female","name":"Michonne"}]}}`, 960 js) 961 } 962 963 func TestSchema1(t *testing.T) { 964 965 // Alright. Now we have everything set up. Let's create the query. 966 query := ` 967 { 968 person(func: uid(0x01)) { 969 name 970 age 971 address 972 alive 973 survival_rate 974 friend { 975 name 976 address 977 age 978 } 979 } 980 } 981 ` 982 js := processQueryNoErr(t, query) 983 require.JSONEq(t, 984 `{"data": {"person":[{"address":"31, 32 street, Jupiter","age":38,"alive":true,"friend":[{"address":"21, mark street, Mars","age":15,"name":"Rick Grimes"},{"name":"Glenn Rhee","age":15},{"age":17,"name":"Daryl Dixon"},{"age":19,"name":"Andrea"}],"name":"Michonne","survival_rate":98.990000}]}}`, js) 985 } 986 987 func TestMultiQuery(t *testing.T) { 988 989 query := ` 990 { 991 me(func:anyofterms(name, "Michonne")) { 992 name 993 gender 994 } 995 996 you(func:anyofterms(name, "Andrea")) { 997 name 998 } 999 } 1000 ` 1001 js := processQueryNoErr(t, query) 1002 require.JSONEq(t, `{"data": {"me":[{"gender":"female","name":"Michonne"}],"you":[{"name":"Andrea"},{"name":"Andrea With no friends"}]}}`, js) 1003 } 1004 1005 func TestMultiQueryError1(t *testing.T) { 1006 1007 query := ` 1008 { 1009 me(func:anyofterms(name, "Michonne")) { 1010 name 1011 gender 1012 1013 you(func:anyofterms(name, "Andrea")) { 1014 name 1015 } 1016 } 1017 ` 1018 _, err := processQuery(context.Background(), t, query) 1019 require.Error(t, err) 1020 } 1021 1022 func TestMultiQueryError2(t *testing.T) { 1023 1024 query := ` 1025 { 1026 me(anyofterms(name, "Michonne")) { 1027 name 1028 gender 1029 } 1030 } 1031 1032 you(anyofterms(name, "Andrea")) { 1033 name 1034 } 1035 } 1036 ` 1037 _, err := processQuery(context.Background(), t, query) 1038 require.Error(t, err) 1039 } 1040 1041 func TestGenerator(t *testing.T) { 1042 1043 query := ` 1044 { 1045 me(func:anyofterms(name, "Michonne")) { 1046 name 1047 gender 1048 } 1049 } 1050 ` 1051 js := processQueryNoErr(t, query) 1052 require.JSONEq(t, `{"data": {"me":[{"gender":"female","name":"Michonne"}]}}`, js) 1053 } 1054 1055 func TestGeneratorMultiRootMultiQueryRootval(t *testing.T) { 1056 1057 query := ` 1058 { 1059 friend as var(func:anyofterms(name, "Michonne Rick Glenn")) { 1060 name 1061 } 1062 1063 you(func: uid(friend)) { 1064 name 1065 } 1066 } 1067 ` 1068 js := processQueryNoErr(t, query) 1069 require.JSONEq(t, `{"data": {"you":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"}]}}`, js) 1070 } 1071 1072 func TestGeneratorMultiRootMultiQueryVarFilter(t *testing.T) { 1073 1074 query := ` 1075 { 1076 f as var(func:anyofterms(name, "Michonne Rick Glenn")) { 1077 name 1078 } 1079 1080 you(func:anyofterms(name, "Michonne")) { 1081 friend @filter(uid(f)) { 1082 name 1083 } 1084 } 1085 } 1086 ` 1087 js := processQueryNoErr(t, query) 1088 require.JSONEq(t, `{"data": {"you":[{"friend":[{"name":"Rick Grimes"}, {"name":"Glenn Rhee"}]}]}}`, js) 1089 } 1090 1091 func TestGeneratorMultiRootMultiQueryRootVarFilter(t *testing.T) { 1092 1093 query := ` 1094 { 1095 friend as var(func:anyofterms(name, "Michonne Rick Glenn")) { 1096 } 1097 1098 you(func:anyofterms(name, "Michonne Andrea Glenn")) @filter(uid(friend)) { 1099 name 1100 } 1101 } 1102 ` 1103 js := processQueryNoErr(t, query) 1104 require.JSONEq(t, `{"data": {"you":[{"name":"Michonne"}, {"name":"Glenn Rhee"}]}}`, js) 1105 } 1106 1107 func TestGeneratorMultiRootMultiQuery(t *testing.T) { 1108 1109 query := ` 1110 { 1111 me(func:anyofterms(name, "Michonne Rick Glenn")) { 1112 name 1113 } 1114 1115 you(func: uid(1, 23, 24)) { 1116 name 1117 } 1118 } 1119 ` 1120 js := processQueryNoErr(t, query) 1121 require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"}], "you":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"}]}}`, js) 1122 } 1123 1124 func TestGeneratorMultiRootVarOrderOffset(t *testing.T) { 1125 1126 query := ` 1127 { 1128 L as var(func:anyofterms(name, "Michonne Rick Glenn"), orderasc: dob, offset:2) { 1129 name 1130 } 1131 1132 me(func: uid(L)) { 1133 name 1134 } 1135 } 1136 ` 1137 js := processQueryNoErr(t, query) 1138 require.JSONEq(t, `{"data": {"me":[{"name":"Rick Grimes"}]}}`, js) 1139 } 1140 1141 func TestGeneratorMultiRootVarOrderOffset1(t *testing.T) { 1142 1143 query := ` 1144 { 1145 me(func:anyofterms(name, "Michonne Rick Glenn"), orderasc: dob, offset:2) { 1146 name 1147 } 1148 } 1149 ` 1150 js := processQueryNoErr(t, query) 1151 require.JSONEq(t, `{"data": {"me":[{"name":"Rick Grimes"}]}}`, js) 1152 } 1153 1154 func TestGeneratorMultiRootOrderOffset(t *testing.T) { 1155 1156 query := ` 1157 { 1158 L as var(func:anyofterms(name, "Michonne Rick Glenn")) { 1159 name 1160 } 1161 me(func: uid(L), orderasc: dob, offset:2) { 1162 name 1163 } 1164 } 1165 ` 1166 js := processQueryNoErr(t, query) 1167 require.JSONEq(t, `{"data": {"me":[{"name":"Rick Grimes"}]}}`, js) 1168 } 1169 1170 func TestGeneratorMultiRootOrderdesc(t *testing.T) { 1171 1172 query := ` 1173 { 1174 me(func:anyofterms(name, "Michonne Rick Glenn"), orderdesc: dob) { 1175 name 1176 } 1177 } 1178 ` 1179 js := processQueryNoErr(t, query) 1180 require.JSONEq(t, `{"data": {"me":[{"name":"Rick Grimes"},{"name":"Michonne"},{"name":"Glenn Rhee"}]}}`, js) 1181 } 1182 1183 func TestGeneratorMultiRootOrder(t *testing.T) { 1184 1185 query := ` 1186 { 1187 me(func:anyofterms(name, "Michonne Rick Glenn"), orderasc: dob) { 1188 name 1189 } 1190 } 1191 ` 1192 js := processQueryNoErr(t, query) 1193 require.JSONEq(t, `{"data": {"me":[{"name":"Glenn Rhee"},{"name":"Michonne"},{"name":"Rick Grimes"}]}}`, js) 1194 } 1195 1196 func TestGeneratorMultiRootOffset(t *testing.T) { 1197 1198 query := ` 1199 { 1200 me(func:anyofterms(name, "Michonne Rick Glenn"), offset: 1) { 1201 name 1202 } 1203 } 1204 ` 1205 js := processQueryNoErr(t, query) 1206 require.JSONEq(t, `{"data": {"me":[{"name":"Rick Grimes"},{"name":"Glenn Rhee"}]}}`, js) 1207 } 1208 1209 func TestGeneratorMultiRoot(t *testing.T) { 1210 1211 query := ` 1212 { 1213 me(func:anyofterms(name, "Michonne Rick Glenn")) { 1214 name 1215 } 1216 } 1217 ` 1218 1219 js := processQueryNoErr(t, query) 1220 require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"},{"name":"Rick Grimes"}, 1221 {"name":"Glenn Rhee"}]}}`, js) 1222 } 1223 1224 func TestRootList(t *testing.T) { 1225 query := `{ 1226 me(func: uid(1, 23, 24)) { 1227 name 1228 } 1229 }` 1230 js := processQueryNoErr(t, query) 1231 require.JSONEq(t, 1232 `{"data": {"me":[{"name":"Michonne"},{"name":"Rick Grimes"},{"name":"Glenn Rhee"}]}}`, js) 1233 } 1234 1235 func TestRootList1(t *testing.T) { 1236 1237 query := `{ 1238 me(func: uid(0x01, 23, 24, 110)) { 1239 name 1240 } 1241 }` 1242 js := processQueryNoErr(t, query) 1243 require.JSONEq(t, 1244 `{"data": {"me":[{"name":"Michonne"},{"name":"Rick Grimes"}`+ 1245 `,{"name":"Glenn Rhee"},{"name":"Alice"}]}}`, js) 1246 } 1247 1248 func TestRootList2(t *testing.T) { 1249 1250 query := `{ 1251 me(func: uid(0x01, 23, 110, 24)) { 1252 name 1253 } 1254 }` 1255 js := processQueryNoErr(t, query) 1256 require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"},{"name":"Rick Grimes"}`+ 1257 `,{"name":"Glenn Rhee"},{"name":"Alice"}]}}`, js) 1258 } 1259 1260 func TestGeneratorMultiRootFilter1(t *testing.T) { 1261 1262 query := ` 1263 { 1264 me(func:anyofterms(name, "Daryl Rick Glenn")) @filter(le(dob, "1909-01-10")) { 1265 name 1266 } 1267 } 1268 ` 1269 js := processQueryNoErr(t, query) 1270 require.JSONEq(t, `{"data": {"me":[{"name":"Daryl Dixon"}]}}`, js) 1271 } 1272 1273 func TestGeneratorMultiRootFilter2(t *testing.T) { 1274 1275 query := ` 1276 { 1277 me(func:anyofterms(name, "Michonne Rick Glenn")) @filter(ge(dob, "1909-01-10")) { 1278 name 1279 } 1280 } 1281 ` 1282 js := processQueryNoErr(t, query) 1283 require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"},{"name":"Rick Grimes"}`+ 1284 `,{"name":"Glenn Rhee"}]}}`, js) 1285 } 1286 1287 func TestGeneratorMultiRootFilter3(t *testing.T) { 1288 1289 query := ` 1290 { 1291 me(func:anyofterms(name, "Michonne Rick Glenn")) @filter(anyofterms(name, "Glenn") and ge(dob, "1909-01-10")) { 1292 name 1293 } 1294 } 1295 ` 1296 js := processQueryNoErr(t, query) 1297 require.JSONEq(t, `{"data": {"me":[{"name":"Glenn Rhee"}]}}`, js) 1298 } 1299 1300 func TestGeneratorRootFilterOnCountGt(t *testing.T) { 1301 1302 query := ` 1303 { 1304 me(func:anyofterms(name, "Michonne Rick")) @filter(gt(count(friend), 2)) { 1305 name 1306 } 1307 } 1308 ` 1309 js := processQueryNoErr(t, query) 1310 require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"}]}}`, js) 1311 } 1312 1313 func TestGeneratorRootFilterOnCountle(t *testing.T) { 1314 1315 query := ` 1316 { 1317 me(func:anyofterms(name, "Michonne Rick")) @filter(le(count(friend), 2)) { 1318 name 1319 } 1320 } 1321 ` 1322 1323 js := processQueryNoErr(t, query) 1324 require.JSONEq(t, `{"data": {"me":[{"name":"Rick Grimes"}]}}`, js) 1325 } 1326 1327 func TestGeneratorRootFilterOnCountChildLevel(t *testing.T) { 1328 1329 query := ` 1330 { 1331 me(func: uid(23)) { 1332 name 1333 friend @filter(gt(count(friend), 2)) { 1334 name 1335 } 1336 } 1337 } 1338 ` 1339 js := processQueryNoErr(t, query) 1340 require.JSONEq(t, `{"data": {"me":[{"friend":[{"name":"Michonne"}],"name":"Rick Grimes"}]}}`, js) 1341 } 1342 1343 func TestGeneratorRootFilterOnCountWithAnd(t *testing.T) { 1344 1345 query := ` 1346 { 1347 me(func: uid(23)) { 1348 name 1349 friend @filter(gt(count(friend), 4) and lt(count(friend), 100)) { 1350 name 1351 } 1352 } 1353 } 1354 ` 1355 js := processQueryNoErr(t, query) 1356 require.JSONEq(t, `{"data": {"me":[{"friend":[{"name":"Michonne"}],"name":"Rick Grimes"}]}}`, js) 1357 } 1358 1359 func TestGeneratorRootFilterOnCountError1(t *testing.T) { 1360 1361 // only cmp(count(attr), int) is valid, 'max'/'min'/'sum' not supported 1362 query := ` 1363 { 1364 me(func:anyofterms(name, "Michonne Rick")) @filter(gt(count(friend), "invalid")) { 1365 name 1366 } 1367 } 1368 ` 1369 1370 _, err := processQuery(context.Background(), t, query) 1371 require.NotNil(t, err) 1372 } 1373 1374 func TestGeneratorRootFilterOnCountError2(t *testing.T) { 1375 1376 // missing digits 1377 query := ` 1378 { 1379 me(func:anyofterms(name, "Michonne Rick")) @filter(gt(count(friend))) { 1380 name 1381 } 1382 } 1383 ` 1384 1385 _, err := processQuery(context.Background(), t, query) 1386 require.NotNil(t, err) 1387 } 1388 1389 func TestGeneratorRootFilterOnCountError3(t *testing.T) { 1390 1391 // to much args 1392 query := ` 1393 { 1394 me(func:anyofterms(name, "Michonne Rick")) @filter(gt(count(friend), 2, 4)) { 1395 name 1396 } 1397 } 1398 ` 1399 1400 _, err := processQuery(context.Background(), t, query) 1401 require.Error(t, err) 1402 } 1403 1404 func TestNearGenerator(t *testing.T) { 1405 1406 time.Sleep(10 * time.Millisecond) 1407 query := `{ 1408 me(func:near(loc, [1.1,2.0], 5.001)) @filter(not uid(25)) { 1409 name 1410 gender 1411 } 1412 }` 1413 1414 js := processQueryNoErr(t, query) 1415 require.JSONEq(t, `{"data": {"me":[{"name":"Michonne","gender":"female"},{"name":"Rick Grimes","gender": "male"},{"name":"Glenn Rhee"}]}}`, js) 1416 } 1417 1418 func TestNearGeneratorFilter(t *testing.T) { 1419 1420 query := `{ 1421 me(func:near(loc, [1.1,2.0], 5.001)) @filter(allofterms(name, "Michonne")) { 1422 name 1423 gender 1424 } 1425 }` 1426 1427 js := processQueryNoErr(t, query) 1428 require.JSONEq(t, `{"data": {"me":[{"gender":"female","name":"Michonne"}]}}`, js) 1429 } 1430 1431 func TestNearGeneratorError(t *testing.T) { 1432 1433 query := `{ 1434 me(func:near(loc, [1.1,2.0], -5.0)) { 1435 name 1436 gender 1437 } 1438 }` 1439 1440 _, err := processQuery(context.Background(), t, query) 1441 require.Error(t, err) 1442 } 1443 1444 func TestNearGeneratorErrorMissDist(t *testing.T) { 1445 1446 query := `{ 1447 me(func:near(loc, [1.1,2.0])) { 1448 name 1449 gender 1450 } 1451 }` 1452 1453 _, err := processQuery(context.Background(), t, query) 1454 require.Error(t, err) 1455 } 1456 1457 func TestWithinGeneratorError(t *testing.T) { 1458 1459 query := `{ 1460 me(func:within(loc, [[[0.0,0.0], [2.0,0.0], [1.5, 3.0], [0.0, 2.0], [0.0, 0.0]]], 12.2)) { 1461 name 1462 gender 1463 } 1464 }` 1465 1466 _, err := processQuery(context.Background(), t, query) 1467 require.Error(t, err) 1468 } 1469 1470 func TestWithinGenerator(t *testing.T) { 1471 1472 query := `{ 1473 me(func:within(loc, [[[0.0,0.0], [2.0,0.0], [1.5, 3.0], [0.0, 2.0], [0.0, 0.0]]])) @filter(not uid(25)) { 1474 name 1475 } 1476 }` 1477 1478 js := processQueryNoErr(t, query) 1479 require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"},{"name":"Glenn Rhee"}]}}`, js) 1480 } 1481 1482 func TestContainsGenerator(t *testing.T) { 1483 1484 query := `{ 1485 me(func:contains(loc, [2.0,0.0])) { 1486 name 1487 } 1488 }` 1489 1490 js := processQueryNoErr(t, query) 1491 require.JSONEq(t, `{"data": {"me":[{"name":"Rick Grimes"}]}}`, js) 1492 } 1493 1494 func TestContainsGenerator2(t *testing.T) { 1495 1496 query := `{ 1497 me(func:contains(loc, [[[1.0,1.0], [1.9,1.0], [1.9, 1.9], [1.0, 1.9], [1.0, 1.0]]])) { 1498 name 1499 } 1500 }` 1501 1502 js := processQueryNoErr(t, query) 1503 require.JSONEq(t, `{"data": {"me":[{"name":"Rick Grimes"}]}}`, js) 1504 } 1505 1506 func TestIntersectsGeneratorError(t *testing.T) { 1507 1508 query := `{ 1509 me(func:intersects(loc, [0.0,0.0])) { 1510 name 1511 } 1512 }` 1513 1514 _, err := processQuery(context.Background(), t, query) 1515 require.Error(t, err) 1516 } 1517 1518 func TestIntersectsGenerator(t *testing.T) { 1519 1520 query := `{ 1521 me(func:intersects(loc, [[[0.0,0.0], [2.0,0.0], [1.5, 3.0], [0.0, 2.0], [0.0, 0.0]]])) @filter(not uid(25)) { 1522 name 1523 } 1524 }` 1525 1526 js := processQueryNoErr(t, query) 1527 require.JSONEq(t, `{"data": {"me":[{"name":"Michonne"}, {"name":"Rick Grimes"}, {"name":"Glenn Rhee"}]}}`, js) 1528 } 1529 1530 // this test is failing when executed alone, but pass when executed after other tests 1531 // TODO: find and remove the dependency 1532 func TestNormalizeDirective(t *testing.T) { 1533 query := ` 1534 { 1535 me(func: uid(0x01)) @normalize { 1536 mn: name 1537 gender 1538 friend { 1539 n: name 1540 d: dob 1541 friend { 1542 fn : name 1543 } 1544 } 1545 son { 1546 sn: name 1547 } 1548 } 1549 } 1550 ` 1551 1552 js := processQueryNoErr(t, query) 1553 require.JSONEq(t, 1554 `{"data": {"me":[{"d":"1910-01-02T00:00:00Z","fn":"Michonne","mn":"Michonne","n":"Rick Grimes","sn":"Andre"},{"d":"1910-01-02T00:00:00Z","fn":"Michonne","mn":"Michonne","n":"Rick Grimes","sn":"Helmut"},{"d":"1909-05-05T00:00:00Z","mn":"Michonne","n":"Glenn Rhee","sn":"Andre"},{"d":"1909-05-05T00:00:00Z","mn":"Michonne","n":"Glenn Rhee","sn":"Helmut"},{"d":"1909-01-10T00:00:00Z","mn":"Michonne","n":"Daryl Dixon","sn":"Andre"},{"d":"1909-01-10T00:00:00Z","mn":"Michonne","n":"Daryl Dixon","sn":"Helmut"},{"d":"1901-01-15T00:00:00Z","fn":"Glenn Rhee","mn":"Michonne","n":"Andrea","sn":"Andre"},{"d":"1901-01-15T00:00:00Z","fn":"Glenn Rhee","mn":"Michonne","n":"Andrea","sn":"Helmut"}]}}`, 1555 js) 1556 } 1557 1558 func TestNearPoint(t *testing.T) { 1559 1560 query := `{ 1561 me(func: near(geometry, [-122.082506, 37.4249518], 1)) { 1562 name 1563 } 1564 }` 1565 1566 js := processQueryNoErr(t, query) 1567 expected := `{"data": {"me":[{"name":"Googleplex"},{"name":"SF Bay area"},{"name":"Mountain View"}]}}` 1568 require.JSONEq(t, expected, js) 1569 } 1570 1571 func TestWithinPolygon(t *testing.T) { 1572 1573 query := `{ 1574 me(func: within(geometry, [[[-122.06, 37.37], [-122.1, 37.36], [-122.12, 37.4], [-122.11, 37.43], [-122.04, 37.43], [-122.06, 37.37]]])) { 1575 name 1576 } 1577 }` 1578 js := processQueryNoErr(t, query) 1579 expected := `{"data": {"me":[{"name":"Googleplex"},{"name":"Shoreline Amphitheater"}]}}` 1580 require.JSONEq(t, expected, js) 1581 } 1582 1583 func TestContainsPoint(t *testing.T) { 1584 1585 query := `{ 1586 me(func: contains(geometry, [-122.082506, 37.4249518])) { 1587 name 1588 } 1589 }` 1590 1591 js := processQueryNoErr(t, query) 1592 expected := `{"data": {"me":[{"name":"SF Bay area"},{"name":"Mountain View"}]}}` 1593 require.JSONEq(t, expected, js) 1594 } 1595 1596 func TestNearPoint2(t *testing.T) { 1597 1598 query := `{ 1599 me(func: near(geometry, [-122.082506, 37.4249518], 1000)) { 1600 name 1601 } 1602 }` 1603 1604 js := processQueryNoErr(t, query) 1605 expected := `{"data": {"me":[{"name":"Googleplex"},{"name":"Shoreline Amphitheater"}, {"name": "SF Bay area"}, {"name": "Mountain View"}]}}` 1606 require.JSONEq(t, expected, js) 1607 } 1608 1609 func TestIntersectsPolygon1(t *testing.T) { 1610 1611 query := `{ 1612 me(func: intersects(geometry, [[[-122.06, 37.37], [-122.1, 37.36], [-122.12, 37.4], [-122.11, 37.43], [-122.04, 37.43], [-122.06, 37.37]]])) { 1613 name 1614 } 1615 }` 1616 1617 js := processQueryNoErr(t, query) 1618 expected := `{"data" : {"me":[{"name":"Googleplex"},{"name":"Shoreline Amphitheater"}, 1619 {"name":"SF Bay area"},{"name":"Mountain View"}]}}` 1620 require.JSONEq(t, expected, js) 1621 } 1622 1623 func TestIntersectsPolygon2(t *testing.T) { 1624 1625 query := `{ 1626 me(func: intersects(geometry,[[[-121.6, 37.1], [-122.4, 37.3], [-122.6, 37.8], [-122.5, 38.3], [-121.9, 38], [-121.6, 37.1]]])) { 1627 name 1628 } 1629 }` 1630 1631 js := processQueryNoErr(t, query) 1632 expected := `{"data": {"me":[{"name":"Googleplex"},{"name":"Shoreline Amphitheater"}, 1633 {"name":"San Carlos Airport"},{"name":"SF Bay area"}, 1634 {"name":"Mountain View"},{"name":"San Carlos"}]}}` 1635 require.JSONEq(t, expected, js) 1636 } 1637 1638 func TestNotExistObject(t *testing.T) { 1639 1640 // we haven't set genre(type:uid) for 0x01, should just be ignored 1641 query := ` 1642 { 1643 me(func: uid(0x01)) { 1644 name 1645 gender 1646 alive 1647 genre 1648 } 1649 } 1650 ` 1651 js := processQueryNoErr(t, query) 1652 require.JSONEq(t, 1653 `{"data": {"me":[{"name":"Michonne","gender":"female","alive":true}]}}`, 1654 js) 1655 } 1656 1657 func TestLangDefault(t *testing.T) { 1658 1659 query := ` 1660 { 1661 me(func: uid(0x1001)) { 1662 name 1663 } 1664 } 1665 ` 1666 js := processQueryNoErr(t, query) 1667 require.JSONEq(t, 1668 `{"data": {"me":[{"name":"Badger"}]}}`, 1669 js) 1670 } 1671 1672 func TestLangMultiple_Alias(t *testing.T) { 1673 1674 query := ` 1675 { 1676 me(func: uid(0x1001)) { 1677 a: name@pl 1678 b: name@cn 1679 c: name 1680 } 1681 } 1682 ` 1683 js := processQueryNoErr(t, query) 1684 require.JSONEq(t, 1685 `{"data": {"me":[{"c":"Badger","a":"Borsuk europejski"}]}}`, 1686 js) 1687 } 1688 1689 func TestLangMultiple(t *testing.T) { 1690 1691 query := ` 1692 { 1693 me(func: uid(0x1001)) { 1694 name@pl 1695 name 1696 } 1697 } 1698 ` 1699 js := processQueryNoErr(t, query) 1700 require.JSONEq(t, 1701 `{"data": {"me":[{"name":"Badger","name@pl":"Borsuk europejski"}]}}`, 1702 js) 1703 } 1704 1705 func TestLangSingle(t *testing.T) { 1706 1707 query := ` 1708 { 1709 me(func: uid(0x1001)) { 1710 name@pl 1711 } 1712 } 1713 ` 1714 js := processQueryNoErr(t, query) 1715 require.JSONEq(t, 1716 `{"data": {"me":[{"name@pl":"Borsuk europejski"}]}}`, 1717 js) 1718 } 1719 1720 func TestLangSingleFallback(t *testing.T) { 1721 1722 query := ` 1723 { 1724 me(func: uid(0x1001)) { 1725 name@cn 1726 } 1727 } 1728 ` 1729 js := processQueryNoErr(t, query) 1730 require.JSONEq(t, `{"data": {"me": []}}`, js) 1731 } 1732 1733 func TestLangMany1(t *testing.T) { 1734 1735 query := ` 1736 { 1737 me(func: uid(0x1001)) { 1738 name@ru:en:fr 1739 } 1740 } 1741 ` 1742 js := processQueryNoErr(t, query) 1743 require.JSONEq(t, 1744 `{"data": {"me":[{"name@ru:en:fr":"Барсук"}]}}`, 1745 js) 1746 } 1747 1748 func TestLangMany2(t *testing.T) { 1749 1750 query := ` 1751 { 1752 me(func: uid(0x1001)) { 1753 name@hu:fi:fr 1754 } 1755 } 1756 ` 1757 js := processQueryNoErr(t, query) 1758 require.JSONEq(t, 1759 `{"data": {"me":[{"name@hu:fi:fr":"Blaireau européen"}]}}`, 1760 js) 1761 } 1762 1763 func TestLangMany3(t *testing.T) { 1764 1765 query := ` 1766 { 1767 me(func: uid(0x1001)) { 1768 name@hu:fr:fi 1769 } 1770 } 1771 ` 1772 js := processQueryNoErr(t, query) 1773 require.JSONEq(t, 1774 `{"data": {"me":[{"name@hu:fr:fi":"Blaireau européen"}]}}`, 1775 js) 1776 } 1777 1778 func TestLangManyFallback(t *testing.T) { 1779 1780 query := ` 1781 { 1782 me(func: uid(0x1001)) { 1783 name@hu:fi:cn 1784 } 1785 } 1786 ` 1787 js := processQueryNoErr(t, query) 1788 require.JSONEq(t, `{"data": {"me": []}}`, js) 1789 } 1790 1791 func TestLangNoFallbackNoDefault(t *testing.T) { 1792 1793 query := ` 1794 { 1795 me(func: uid(0x1004)) { 1796 name 1797 } 1798 } 1799 ` 1800 js := processQueryNoErr(t, query) 1801 require.JSONEq(t, `{"data": {"me": []}}`, js) 1802 } 1803 1804 func TestLangSingleNoFallbackNoDefault(t *testing.T) { 1805 1806 query := ` 1807 { 1808 me(func: uid(0x1004)) { 1809 name@cn 1810 } 1811 } 1812 ` 1813 js := processQueryNoErr(t, query) 1814 require.JSONEq(t, `{"data": {"me": []}}`, js) 1815 } 1816 1817 func TestLangMultipleNoFallbackNoDefault(t *testing.T) { 1818 1819 query := ` 1820 { 1821 me(func: uid(0x1004)) { 1822 name@cn:hi 1823 } 1824 } 1825 ` 1826 js := processQueryNoErr(t, query) 1827 require.JSONEq(t, `{"data": {"me": []}}`, js) 1828 } 1829 1830 func TestLangOnlyForcedFallbackNoDefault(t *testing.T) { 1831 1832 query := ` 1833 { 1834 me(func: uid(0x1004)) { 1835 name@. 1836 } 1837 } 1838 ` 1839 js := processQueryNoErr(t, query) 1840 // this test is fragile - '.' may return value in any language (depending on data) 1841 require.JSONEq(t, 1842 `{"data": {"me":[{"name@.":"Artem Tkachenko"}]}}`, 1843 js) 1844 } 1845 1846 func TestLangSingleForcedFallbackNoDefault(t *testing.T) { 1847 1848 query := ` 1849 { 1850 me(func: uid(0x1004)) { 1851 name@cn:. 1852 } 1853 } 1854 ` 1855 js := processQueryNoErr(t, query) 1856 // this test is fragile - '.' may return value in any language (depending on data) 1857 require.JSONEq(t, 1858 `{"data": {"me":[{"name@cn:.":"Artem Tkachenko"}]}}`, 1859 js) 1860 } 1861 1862 func TestLangMultipleForcedFallbackNoDefault(t *testing.T) { 1863 1864 query := ` 1865 { 1866 me(func: uid(0x1004)) { 1867 name@hi:cn:. 1868 } 1869 } 1870 ` 1871 js := processQueryNoErr(t, query) 1872 // this test is fragile - '.' may return value in any language (depending on data) 1873 require.JSONEq(t, 1874 `{"data": {"me":[{"name@hi:cn:.":"Artem Tkachenko"}]}}`, 1875 js) 1876 } 1877 1878 func TestLangFilterMatch1(t *testing.T) { 1879 1880 query := ` 1881 { 1882 me(func:allofterms(name@pl, "Europejski borsuk")) { 1883 name@pl 1884 } 1885 } 1886 ` 1887 js := processQueryNoErr(t, query) 1888 require.JSONEq(t, 1889 `{"data": {"me":[{"name@pl":"Borsuk europejski"}]}}`, 1890 js) 1891 } 1892 1893 func TestLangFilterMismatch1(t *testing.T) { 1894 1895 query := ` 1896 { 1897 me(func:allofterms(name@pl, "European Badger")) { 1898 name@pl 1899 } 1900 } 1901 ` 1902 js := processQueryNoErr(t, query) 1903 require.JSONEq(t, `{"data": {"me": []}}`, js) 1904 } 1905 1906 func TestLangFilterMismatch2(t *testing.T) { 1907 1908 query := ` 1909 { 1910 me(func: uid(0x1, 0x2, 0x3, 0x1001)) @filter(anyofterms(name@pl, "Badger is cool")) { 1911 name@pl 1912 } 1913 } 1914 ` 1915 js := processQueryNoErr(t, query) 1916 require.JSONEq(t, `{"data": {"me": []}}`, js) 1917 } 1918 1919 func TestLangFilterMismatch3(t *testing.T) { 1920 1921 query := ` 1922 { 1923 me(func: uid(0x1, 0x2, 0x3, 0x1001)) @filter(allofterms(name@pl, "European borsuk")) { 1924 name@pl 1925 } 1926 } 1927 ` 1928 js := processQueryNoErr(t, query) 1929 require.JSONEq(t, `{"data": {"me": []}}`, js) 1930 } 1931 1932 func TestLangFilterMismatch5(t *testing.T) { 1933 1934 query := ` 1935 { 1936 me(func:anyofterms(name@en, "european honey")) { 1937 name@en 1938 } 1939 } 1940 ` 1941 js := processQueryNoErr(t, query) 1942 require.JSONEq(t, 1943 `{"data": {"me":[{"name@en":"European badger"},{"name@en":"Honey badger"},{"name@en":"Honey bee"}]}}`, 1944 js) 1945 } 1946 1947 func TestLangFilterMismatch6(t *testing.T) { 1948 1949 query := ` 1950 { 1951 me(func: uid(0x1001, 0x1002, 0x1003)) @filter(lt(name@en, "D")) { 1952 name@en 1953 } 1954 } 1955 ` 1956 js := processQueryNoErr(t, query) 1957 require.JSONEq(t, `{"data": {"me": []}}`, js) 1958 } 1959 1960 func TestEqWithTerm(t *testing.T) { 1961 1962 query := ` 1963 { 1964 me(func:eq(nick_name, "Two Terms")) { 1965 uid 1966 } 1967 } 1968 ` 1969 js := processQueryNoErr(t, query) 1970 require.JSONEq(t, 1971 `{"data": {"me":[{"uid":"0x1392"}]}}`, 1972 js) 1973 } 1974 1975 func TestLangLossyIndex1(t *testing.T) { 1976 1977 query := ` 1978 { 1979 me(func:eq(lossy, "Badger")) { 1980 lossy 1981 lossy@en 1982 } 1983 } 1984 ` 1985 js := processQueryNoErr(t, query) 1986 require.JSONEq(t, 1987 `{"data": {"me":[{"lossy":"Badger","lossy@en":"European badger"}]}}`, 1988 js) 1989 } 1990 1991 func TestLangLossyIndex2(t *testing.T) { 1992 1993 query := ` 1994 { 1995 me(func:eq(lossy@ru, "Барсук")) { 1996 lossy 1997 lossy@en 1998 } 1999 } 2000 ` 2001 js := processQueryNoErr(t, query) 2002 require.JSONEq(t, 2003 `{"data": {"me":[{"lossy":"Badger","lossy@en":"European badger"}]}}`, 2004 js) 2005 } 2006 2007 func TestLangLossyIndex3(t *testing.T) { 2008 2009 query := ` 2010 { 2011 me(func:eq(lossy@fr, "Blaireau")) { 2012 lossy 2013 lossy@en 2014 } 2015 } 2016 ` 2017 js := processQueryNoErr(t, query) 2018 require.JSONEq(t, `{"data": {"me": []}}`, js) 2019 } 2020 2021 func TestLangLossyIndex4(t *testing.T) { 2022 2023 query := ` 2024 { 2025 me(func:eq(value, "mission")) { 2026 value 2027 } 2028 } 2029 ` 2030 _, err := processQuery(context.Background(), t, query) 2031 require.Error(t, err) 2032 } 2033 2034 // Test for bug #1295 2035 func TestLangBug1295(t *testing.T) { 2036 2037 // query for Canadian (French) version of the royal_title, then show English one 2038 // this case is not trivial, because farmhash of "en" is less than farmhash of "fr" 2039 // so we need to iterate over values in all languages to find a match 2040 // for alloftext, this won't work - we use default/English tokenizer for function parameters 2041 // when no language is specified, while index contains tokens generated with French tokenizer 2042 2043 functions := []string{"eq", "allofterms" /*, "alloftext" */} 2044 langs := []string{"", "@."} 2045 2046 for _, l := range langs { 2047 for _, f := range functions { 2048 t.Run(f+l, func(t *testing.T) { 2049 query := ` 2050 { 2051 q(func:` + f + "(royal_title" + l + `, "Sa Majesté Elizabeth Deux, par la grâce de Dieu Reine du Royaume-Uni, du Canada et de ses autres royaumes et territoires, Chef du Commonwealth, Défenseur de la Foi")) { 2052 royal_title@en 2053 } 2054 }` 2055 2056 json := processQueryNoErr(t, query) 2057 if l == "" { 2058 require.JSONEq(t, `{"data": {"q": []}}`, json) 2059 } else { 2060 require.JSONEq(t, 2061 `{"data": {"q":[{"royal_title@en":"Her Majesty Elizabeth the Second, by the Grace of God of the United Kingdom of Great Britain and Northern Ireland and of Her other Realms and Territories Queen, Head of the Commonwealth, Defender of the Faith"}]}}`, 2062 json) 2063 } 2064 }) 2065 } 2066 } 2067 2068 } 2069 2070 func TestLangDotInFunction(t *testing.T) { 2071 2072 query := ` 2073 { 2074 me(func:anyofterms(name@., "europejski honey")) { 2075 name@pl 2076 name@en 2077 } 2078 } 2079 ` 2080 js := processQueryNoErr(t, query) 2081 require.JSONEq(t, 2082 `{"data": {"me":[{"name@pl":"Borsuk europejski","name@en":"European badger"},{"name@en":"Honey badger"},{"name@en":"Honey bee"}]}}`, 2083 js) 2084 }