Skip to content

Commit 5abf13f

Browse files
committed
Refactor and more tests.
1 parent cea0c48 commit 5abf13f

File tree

5 files changed

+486
-687
lines changed

5 files changed

+486
-687
lines changed

firebase-firestore/src/androidTest/java/com/google/firebase/firestore/PipelineTest.java

Lines changed: 162 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@
1919
import static com.google.firebase.firestore.pipeline.Function.and;
2020
import static com.google.firebase.firestore.pipeline.Function.arrayContains;
2121
import static com.google.firebase.firestore.pipeline.Function.arrayContainsAny;
22+
import static com.google.firebase.firestore.pipeline.Function.cosineDistance;
2223
import static com.google.firebase.firestore.pipeline.Function.endsWith;
2324
import static com.google.firebase.firestore.pipeline.Function.eq;
25+
import static com.google.firebase.firestore.pipeline.Function.euclideanDistance;
2426
import static com.google.firebase.firestore.pipeline.Function.gt;
27+
import static com.google.firebase.firestore.pipeline.Function.logicalMax;
28+
import static com.google.firebase.firestore.pipeline.Function.logicalMin;
2529
import static com.google.firebase.firestore.pipeline.Function.lt;
2630
import static com.google.firebase.firestore.pipeline.Function.lte;
2731
import static com.google.firebase.firestore.pipeline.Function.neq;
@@ -41,9 +45,12 @@
4145
import com.google.common.truth.Correspondence;
4246
import com.google.firebase.firestore.pipeline.Accumulator;
4347
import com.google.firebase.firestore.pipeline.AggregateStage;
48+
import com.google.firebase.firestore.pipeline.Constant;
4449
import com.google.firebase.firestore.pipeline.Field;
4550
import com.google.firebase.firestore.pipeline.Function;
4651
import com.google.firebase.firestore.testutil.IntegrationTestUtil;
52+
import java.util.Collections;
53+
import java.util.LinkedHashMap;
4754
import java.util.Map;
4855
import java.util.Objects;
4956
import org.junit.After;
@@ -87,11 +94,11 @@ public void tearDown() {
8794
IntegrationTestUtil.tearDown();
8895
}
8996

90-
private Map<String, Map<String, Object>> bookDocs =
91-
ImmutableMap.ofEntries(
97+
private final Map<String, Map<String, Object>> bookDocs =
98+
mapOfEntries(
9299
entry(
93100
"book1",
94-
ImmutableMap.ofEntries(
101+
mapOfEntries(
95102
entry("title", "The Hitchhiker's Guide to the Galaxy"),
96103
entry("author", "Douglas Adams"),
97104
entry("genre", "Science Fiction"),
@@ -101,7 +108,7 @@ public void tearDown() {
101108
entry("awards", ImmutableMap.of("hugo", true, "nebula", false)))),
102109
entry(
103110
"book2",
104-
ImmutableMap.ofEntries(
111+
mapOfEntries(
105112
entry("title", "Pride and Prejudice"),
106113
entry("author", "Jane Austen"),
107114
entry("genre", "Romance"),
@@ -111,7 +118,7 @@ public void tearDown() {
111118
entry("awards", ImmutableMap.of("none", true)))),
112119
entry(
113120
"book3",
114-
ImmutableMap.ofEntries(
121+
mapOfEntries(
115122
entry("title", "One Hundred Years of Solitude"),
116123
entry("author", "Gabriel García Márquez"),
117124
entry("genre", "Magical Realism"),
@@ -121,7 +128,7 @@ public void tearDown() {
121128
entry("awards", ImmutableMap.of("nobel", true, "nebula", false)))),
122129
entry(
123130
"book4",
124-
ImmutableMap.ofEntries(
131+
mapOfEntries(
125132
entry("title", "The Lord of the Rings"),
126133
entry("author", "J.R.R. Tolkien"),
127134
entry("genre", "Fantasy"),
@@ -131,7 +138,7 @@ public void tearDown() {
131138
entry("awards", ImmutableMap.of("hugo", false, "nebula", false)))),
132139
entry(
133140
"book5",
134-
ImmutableMap.ofEntries(
141+
mapOfEntries(
135142
entry("title", "The Handmaid's Tale"),
136143
entry("author", "Margaret Atwood"),
137144
entry("genre", "Dystopian"),
@@ -142,7 +149,7 @@ public void tearDown() {
142149
"awards", ImmutableMap.of("arthur c. clarke", true, "booker prize", false)))),
143150
entry(
144151
"book6",
145-
ImmutableMap.ofEntries(
152+
mapOfEntries(
146153
entry("title", "Crime and Punishment"),
147154
entry("author", "Fyodor Dostoevsky"),
148155
entry("genre", "Psychological Thriller"),
@@ -152,7 +159,7 @@ public void tearDown() {
152159
entry("awards", ImmutableMap.of("none", true)))),
153160
entry(
154161
"book7",
155-
ImmutableMap.ofEntries(
162+
mapOfEntries(
156163
entry("title", "To Kill a Mockingbird"),
157164
entry("author", "Harper Lee"),
158165
entry("genre", "Southern Gothic"),
@@ -162,7 +169,7 @@ public void tearDown() {
162169
entry("awards", ImmutableMap.of("pulitzer", true)))),
163170
entry(
164171
"book8",
165-
ImmutableMap.ofEntries(
172+
mapOfEntries(
166173
entry("title", "1984"),
167174
entry("author", "George Orwell"),
168175
entry("genre", "Dystopian"),
@@ -172,7 +179,7 @@ public void tearDown() {
172179
entry("awards", ImmutableMap.of("prometheus", true)))),
173180
entry(
174181
"book9",
175-
ImmutableMap.ofEntries(
182+
mapOfEntries(
176183
entry("title", "The Great Gatsby"),
177184
entry("author", "F. Scott Fitzgerald"),
178185
entry("genre", "Modernist"),
@@ -182,7 +189,7 @@ public void tearDown() {
182189
entry("awards", ImmutableMap.of("none", true)))),
183190
entry(
184191
"book10",
185-
ImmutableMap.ofEntries(
192+
mapOfEntries(
186193
entry("title", "Dune"),
187194
entry("author", "Frank Herbert"),
188195
entry("genre", "Science Fiction"),
@@ -239,8 +246,7 @@ public void aggregateResultsMany() {
239246
assertThat(waitFor(execute).getResults())
240247
.comparingElementsUsing(DATA_CORRESPONDENCE)
241248
.containsExactly(
242-
ImmutableMap.ofEntries(
243-
entry("count", 10), entry("avgRating", 4.4), entry("maxRating", 4.6)));
249+
mapOfEntries(entry("count", 10), entry("avgRating", 4.4), entry("maxRating", 4.6)));
244250
}
245251

246252
@Test
@@ -259,9 +265,9 @@ public void groupAndAccumulateResults() {
259265
assertThat(waitFor(execute).getResults())
260266
.comparingElementsUsing(DATA_CORRESPONDENCE)
261267
.containsExactly(
262-
ImmutableMap.ofEntries(entry("avgRating", 4.7), entry("genre", "Fantasy")),
263-
ImmutableMap.ofEntries(entry("avgRating", 4.5), entry("genre", "Romance")),
264-
ImmutableMap.ofEntries(entry("avgRating", 4.4), entry("genre", "Science Fiction")));
268+
mapOfEntries(entry("avgRating", 4.7), entry("genre", "Fantasy")),
269+
mapOfEntries(entry("avgRating", 4.5), entry("genre", "Romance")),
270+
mapOfEntries(entry("avgRating", 4.4), entry("genre", "Science Fiction")));
265271
}
266272

267273
@Test
@@ -279,8 +285,7 @@ public void minAndMaxAccumulations() {
279285
assertThat(waitFor(execute).getResults())
280286
.comparingElementsUsing(DATA_CORRESPONDENCE)
281287
.containsExactly(
282-
ImmutableMap.ofEntries(
283-
entry("count", 10), entry("maxRating", 4.7), entry("minPublished", 1813)));
288+
mapOfEntries(entry("count", 10), entry("maxRating", 4.7), entry("minPublished", 1813)));
284289
}
285290

286291
@Test
@@ -295,26 +300,23 @@ public void canSelectFields() {
295300
assertThat(waitFor(execute).getResults())
296301
.comparingElementsUsing(DATA_CORRESPONDENCE)
297302
.containsExactly(
298-
ImmutableMap.ofEntries(
303+
mapOfEntries(
299304
entry("title", "The Hitchhiker's Guide to the Galaxy"),
300305
entry("author", "Douglas Adams")),
301-
ImmutableMap.ofEntries(
306+
mapOfEntries(
302307
entry("title", "The Great Gatsby"), entry("author", "F. Scott Fitzgerald")),
303-
ImmutableMap.ofEntries(entry("title", "Dune"), entry("author", "Frank Herbert")),
304-
ImmutableMap.ofEntries(
308+
mapOfEntries(entry("title", "Dune"), entry("author", "Frank Herbert")),
309+
mapOfEntries(
305310
entry("title", "Crime and Punishment"), entry("author", "Fyodor Dostoevsky")),
306-
ImmutableMap.ofEntries(
311+
mapOfEntries(
307312
entry("title", "One Hundred Years of Solitude"),
308313
entry("author", "Gabriel García Márquez")),
309-
ImmutableMap.ofEntries(entry("title", "1984"), entry("author", "George Orwell")),
310-
ImmutableMap.ofEntries(
311-
entry("title", "To Kill a Mockingbird"), entry("author", "Harper Lee")),
312-
ImmutableMap.ofEntries(
314+
mapOfEntries(entry("title", "1984"), entry("author", "George Orwell")),
315+
mapOfEntries(entry("title", "To Kill a Mockingbird"), entry("author", "Harper Lee")),
316+
mapOfEntries(
313317
entry("title", "The Lord of the Rings"), entry("author", "J.R.R. Tolkien")),
314-
ImmutableMap.ofEntries(
315-
entry("title", "Pride and Prejudice"), entry("author", "Jane Austen")),
316-
ImmutableMap.ofEntries(
317-
entry("title", "The Handmaid's Tale"), entry("author", "Margaret Atwood")))
318+
mapOfEntries(entry("title", "Pride and Prejudice"), entry("author", "Jane Austen")),
319+
mapOfEntries(entry("title", "The Handmaid's Tale"), entry("author", "Margaret Atwood")))
318320
.inOrder();
319321
}
320322

@@ -362,10 +364,9 @@ public void offsetAndLimits() {
362364
assertThat(waitFor(execute).getResults())
363365
.comparingElementsUsing(DATA_CORRESPONDENCE)
364366
.containsExactly(
365-
ImmutableMap.ofEntries(entry("title", "1984"), entry("author", "George Orwell")),
366-
ImmutableMap.ofEntries(
367-
entry("title", "To Kill a Mockingbird"), entry("author", "Harper Lee")),
368-
ImmutableMap.ofEntries(
367+
mapOfEntries(entry("title", "1984"), entry("author", "George Orwell")),
368+
mapOfEntries(entry("title", "To Kill a Mockingbird"), entry("author", "Harper Lee")),
369+
mapOfEntries(
369370
entry("title", "The Lord of the Rings"), entry("author", "J.R.R. Tolkien")));
370371
}
371372

@@ -598,7 +599,7 @@ public void testArithmeticOperations() {
598599
assertThat(waitFor(execute).getResults())
599600
.comparingElementsUsing(DATA_CORRESPONDENCE)
600601
.containsExactly(
601-
ImmutableMap.ofEntries(
602+
mapOfEntries(
602603
entry("ratingPlusOne", 5.2),
603604
entry("yearsSince1900", 79),
604605
entry("ratingTimesTen", 42),
@@ -652,20 +653,66 @@ public void testChecks() {
652653
randomCol
653654
.pipeline()
654655
.where(not(Field.of("rating").isNan()))
655-
.select(Field.of("rating").eq(null).as("ratingIsNull"))
656-
.select("title")
657-
.sort(Field.of("title").ascending())
656+
.select(
657+
Field.of("rating").isNull().as("ratingIsNull"),
658+
Field.of("rating").eq(Constant.nullValue()).as("ratingEqNull"),
659+
not(Field.of("rating").isNan()).as("ratingIsNotNan"))
660+
.limit(1)
658661
.execute();
659662
assertThat(waitFor(execute).getResults())
660663
.comparingElementsUsing(DATA_CORRESPONDENCE)
661664
.containsExactly(
662-
ImmutableMap.of("title", "Crime and Punishment"),
663-
ImmutableMap.of("title", "Dune"),
664-
ImmutableMap.of("title", "Pride and Prejudice"));
665+
mapOfEntries(
666+
entry("ratingIsNull", false),
667+
entry("ratingEqNull", null),
668+
entry("ratingIsNotNan", true)));
669+
}
670+
671+
@Test
672+
@Ignore("Not supported yet")
673+
public void testLogicalMax() {
674+
Task<PipelineSnapshot> execute =
675+
randomCol
676+
.pipeline()
677+
.where(Field.of("author").eq("Douglas Adams"))
678+
.select(
679+
Field.of("rating").logicalMax(4.5).as("max_rating"),
680+
logicalMax(Field.of("published"), 1900).as("max_published"))
681+
.execute();
682+
assertThat(waitFor(execute).getResults())
683+
.comparingElementsUsing(DATA_CORRESPONDENCE)
684+
.containsExactly(ImmutableMap.of("max_rating", 4.5, "max_published", 1979));
685+
}
686+
687+
@Test
688+
@Ignore("Not supported yet")
689+
public void testLogicalMin() {
690+
Task<PipelineSnapshot> execute =
691+
randomCol
692+
.pipeline()
693+
.select(
694+
Field.of("rating").logicalMin(4.5).as("min_rating"),
695+
logicalMin(Field.of("published"), 1900).as("min_published"))
696+
.execute();
697+
assertThat(waitFor(execute).getResults())
698+
.comparingElementsUsing(DATA_CORRESPONDENCE)
699+
.containsExactly(ImmutableMap.of("min_rating", 4.2, "min_published", 1900));
665700
}
666701

667702
@Test
668-
public void testMapGet() {}
703+
public void testMapGet() {
704+
Task<PipelineSnapshot> execute =
705+
randomCol
706+
.pipeline()
707+
.select(Field.of("awards").mapGet("hugo").as("hugoAward"), Field.of("title"))
708+
.where(eq("hugoAward", true))
709+
.execute();
710+
assertThat(waitFor(execute).getResults())
711+
.comparingElementsUsing(DATA_CORRESPONDENCE)
712+
.containsExactly(
713+
ImmutableMap.of("hugoAward", true, "title", "The Hitchhiker's Guide to the Galaxy"),
714+
ImmutableMap.of("hugoAward", true, "title", "Dune"));
715+
}
669716

670717
@Test
671718
public void testParent() {}
@@ -674,11 +721,81 @@ public void testParent() {}
674721
public void testCollectionId() {}
675722

676723
@Test
677-
public void testDistanceFunctions() {}
724+
public void testDistanceFunctions() {
725+
double[] sourceVector = {0.1, 0.1};
726+
double[] targetVector = {0.5, 0.8};
727+
Task<PipelineSnapshot> execute =
728+
randomCol
729+
.pipeline()
730+
.select(
731+
cosineDistance(Constant.vector(sourceVector), targetVector).as("cosineDistance"),
732+
Function.dotProduct(Constant.vector(sourceVector), targetVector)
733+
.as("dotProductDistance"),
734+
euclideanDistance(Constant.vector(sourceVector), targetVector)
735+
.as("euclideanDistance"))
736+
.limit(1)
737+
.execute();
738+
assertThat(waitFor(execute).getResults())
739+
.comparingElementsUsing(DATA_CORRESPONDENCE)
740+
.containsExactly(
741+
ImmutableMap.of(
742+
"cosineDistance", 0.02560880430538015,
743+
"dotProductDistance", 0.13,
744+
"euclideanDistance", 0.806225774829855));
745+
}
678746

679747
@Test
680748
public void testNestedFields() {}
681749

682750
@Test
683751
public void testMapGetWithFieldNameIncludingNotation() {}
752+
753+
static <T> Map.Entry<String, T> entry(String key, T value) {
754+
return new Map.Entry<String, T>() {
755+
private String k = key;
756+
private T v = value;
757+
758+
@Override
759+
public String getKey() {
760+
return k;
761+
}
762+
763+
@Override
764+
public T getValue() {
765+
return v;
766+
}
767+
768+
@Override
769+
public T setValue(T value) {
770+
T old = v;
771+
v = value;
772+
return old;
773+
}
774+
775+
@Override
776+
public boolean equals(Object o) {
777+
if (!(o instanceof Map.Entry)) {
778+
return false;
779+
}
780+
781+
Map.Entry<?, ?> that = (Map.Entry<?, ?>) o;
782+
return com.google.common.base.Objects.equal(k, that.getKey())
783+
&& com.google.common.base.Objects.equal(v, that.getValue());
784+
}
785+
786+
@Override
787+
public int hashCode() {
788+
return com.google.common.base.Objects.hashCode(k, v);
789+
}
790+
};
791+
}
792+
793+
@SafeVarargs
794+
static <T> Map<String, T> mapOfEntries(Map.Entry<String, T>... entries) {
795+
Map<String, T> res = new LinkedHashMap<>();
796+
for (Map.Entry<String, T> entry : entries) {
797+
res.put(entry.getKey(), entry.getValue());
798+
}
799+
return Collections.unmodifiableMap(res);
800+
}
684801
}

firebase-firestore/src/main/java/com/google/firebase/firestore/Pipeline.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ internal constructor(
225225
private val version: SnapshotVersion,
226226
) {
227227

228-
fun getData(): Map<String, Any> {
228+
fun getData(): Map<String, Any?> {
229229
return userDataWriter().convertObject(fields)
230230
}
231231

0 commit comments

Comments
 (0)