|
23 | 23 | import static com.google.firebase.firestore.testutil.TestUtil.path;
|
24 | 24 | import static com.google.firebase.firestore.testutil.TestUtil.ref;
|
25 | 25 | import static com.google.firebase.firestore.testutil.TestUtil.testEquality;
|
| 26 | +import static com.google.firebase.firestore.testutil.TestUtil.wrap; |
26 | 27 | import static java.util.Arrays.asList;
|
27 | 28 | import static org.junit.Assert.assertEquals;
|
28 | 29 | import static org.junit.Assert.assertFalse;
|
29 | 30 | import static org.junit.Assert.assertTrue;
|
30 | 31 |
|
| 32 | +import com.google.firebase.Timestamp; |
| 33 | +import com.google.firebase.firestore.Blob; |
| 34 | +import com.google.firebase.firestore.GeoPoint; |
31 | 35 | import com.google.firebase.firestore.model.Document;
|
32 | 36 | import com.google.firebase.firestore.model.ResourcePath;
|
33 | 37 | import com.google.firebase.firestore.testutil.ComparatorTester;
|
| 38 | +import java.util.Arrays; |
34 | 39 | import java.util.Collections;
|
35 | 40 | import java.util.List;
|
36 | 41 | import org.junit.Test;
|
@@ -553,4 +558,62 @@ public void testMatchesAllDocuments() {
|
553 | 558 | query = baseQuery.endAt(new Bound(Collections.emptyList(), true));
|
554 | 559 | assertFalse(query.matchesAllDocuments());
|
555 | 560 | }
|
| 561 | + |
| 562 | + @Test |
| 563 | + public void testCanonicalIdsAreStable() { |
| 564 | + // This test aims to ensure that we do not break canonical IDs, as they are used as keys in |
| 565 | + // the TargetCache. |
| 566 | + |
| 567 | + Query baseQuery = Query.atPath(ResourcePath.fromString("collection")); |
| 568 | + |
| 569 | + assertCanonicalId(baseQuery, "collection|f:|ob:__name__asc"); |
| 570 | + assertCanonicalId( |
| 571 | + baseQuery.filter(filter("a", ">", "a")), "collection|f:a>a|ob:aasc__name__asc"); |
| 572 | + assertCanonicalId( |
| 573 | + baseQuery.filter(filter("a", "<=", new GeoPoint(90.0, -90.0))), |
| 574 | + "collection|f:a<=GeoPoint { latitude=90.0, longitude=-90.0 }|ob:aasc__name__asc"); |
| 575 | + assertCanonicalId( |
| 576 | + baseQuery.filter(filter("a", "<=", new Timestamp(60, 3000))), |
| 577 | + "collection|f:a<=Timestamp(seconds=60, nanoseconds=3000)|ob:aasc__name__asc"); |
| 578 | + assertCanonicalId( |
| 579 | + baseQuery.filter(filter("a", ">=", Blob.fromBytes(new byte[] {1, 2, 3}))), |
| 580 | + "collection|f:a>=Blob { bytes=010203 }|ob:aasc__name__asc"); |
| 581 | + assertCanonicalId( |
| 582 | + baseQuery.filter(filter("a", "==", Arrays.asList(1, 2, 3))), |
| 583 | + "collection|f:a==[1, 2, 3]|ob:__name__asc"); |
| 584 | + assertCanonicalId( |
| 585 | + baseQuery.filter(filter("a", "==", Double.NaN)), "collection|f:a==NaN|ob:__name__asc"); |
| 586 | + assertCanonicalId( |
| 587 | + baseQuery.filter(filter("__name__", "==", ref("collection/id"))), |
| 588 | + "collection|f:__name__==collection/id|ob:__name__asc"); |
| 589 | + assertCanonicalId( |
| 590 | + baseQuery.filter(filter("a", "==", map("a", "b", "inner", map("d", "c")))), |
| 591 | + "collection|f:a==ArraySortedMap{(a=>b), (inner=>ArraySortedMap{(d=>c)};)};|ob:__name__asc"); |
| 592 | + assertCanonicalId( |
| 593 | + baseQuery.filter(filter("a", "in", Arrays.asList(1, 2, 3))), |
| 594 | + "collection|f:ain[1, 2, 3]|ob:__name__asc"); |
| 595 | + assertCanonicalId( |
| 596 | + baseQuery.filter(filter("a", "array-contains-any", Arrays.asList(1, 2, 3))), |
| 597 | + "collection|f:aarray_contains_any[1, 2, 3]|ob:__name__asc"); |
| 598 | + assertCanonicalId( |
| 599 | + baseQuery.filter(filter("a", "array-contains", "a")), |
| 600 | + "collection|f:aarray_containsa|ob:__name__asc"); |
| 601 | + assertCanonicalId(baseQuery.orderBy(orderBy("a")), "collection|f:|ob:aasc__name__asc"); |
| 602 | + assertCanonicalId( |
| 603 | + baseQuery |
| 604 | + .orderBy(orderBy("a")) |
| 605 | + .startAt(new Bound(Arrays.asList(wrap("foo"), wrap(Arrays.asList(1, 2, 3))), true)), |
| 606 | + "collection|f:|ob:aasc__name__asc|lb:b:foo[1, 2, 3]"); |
| 607 | + assertCanonicalId( |
| 608 | + baseQuery |
| 609 | + .orderBy(orderBy("a")) |
| 610 | + .endAt(new Bound(Arrays.asList(wrap("foo"), wrap(Arrays.asList(1, 2, 3))), false)), |
| 611 | + "collection|f:|ob:aasc__name__asc|ub:a:foo[1, 2, 3]"); |
| 612 | + assertCanonicalId(baseQuery.limitToFirst(5), "collection|f:|ob:__name__asc|l:5"); |
| 613 | + assertCanonicalId(baseQuery.limitToLast(5), "collection|f:|ob:__name__desc|l:5"); |
| 614 | + } |
| 615 | + |
| 616 | + private void assertCanonicalId(Query query, String expectedCanonicalId) { |
| 617 | + assertEquals(expectedCanonicalId, query.toTarget().getCanonicalId()); |
| 618 | + } |
556 | 619 | }
|
0 commit comments