Skip to content

Commit 50f9df9

Browse files
authored
Accept FIRTimestamp where NSDate is currently accepted as a parameter (#823)
1 parent 67b068e commit 50f9df9

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

Firestore/Example/Tests/Integration/API/FIRCursorTests.mm

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,4 +192,82 @@ - (void)testCanBeUsedInDescendingQueries {
192192
XCTAssertEqualObjects(FIRQuerySnapshotGetData(snapshot), (@[ @{ @"v" : @"d", @"sort" : @3.0 } ]));
193193
}
194194

195+
FIRTimestamp *TimestampWithMicros(int64_t seconds, int32_t micros) {
196+
// Firestore only supports microsecond resolution, so use a microsecond as a minimum value for
197+
// nanoseconds.
198+
return [FIRTimestamp timestampWithSeconds:seconds nanoseconds:micros * 1000];
199+
}
200+
201+
- (void)testTimestampsCanBePassedToQueriesAsLimits {
202+
FIRCollectionReference *testCollection = [self collectionRefWithDocuments:@{
203+
@"a" : @{@"timestamp" : TimestampWithMicros(100, 2)},
204+
@"b" : @{@"timestamp" : TimestampWithMicros(100, 5)},
205+
@"c" : @{@"timestamp" : TimestampWithMicros(100, 3)},
206+
@"d" : @{@"timestamp" : TimestampWithMicros(100, 1)},
207+
// Number of microseconds deliberately repeated.
208+
@"e" : @{@"timestamp" : TimestampWithMicros(100, 5)},
209+
@"f" : @{@"timestamp" : TimestampWithMicros(100, 4)},
210+
}];
211+
FIRQuery *query = [testCollection queryOrderedByField:@"timestamp"];
212+
FIRQuerySnapshot *querySnapshot =
213+
[self readDocumentSetForRef:[[query queryStartingAfterValues:@[ TimestampWithMicros(100, 2) ]]
214+
queryEndingAtValues:@[ TimestampWithMicros(100, 5) ]]];
215+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(querySnapshot), (@[ @"c", @"f", @"b", @"e" ]));
216+
}
217+
218+
- (void)testTimestampsCanBePassedToQueriesInWhereClause {
219+
FIRTimestamp *currentTimestamp = [FIRTimestamp timestamp];
220+
int64_t seconds = currentTimestamp.seconds;
221+
int32_t micros = currentTimestamp.nanoseconds / 1000;
222+
FIRCollectionReference *testCollection = [self collectionRefWithDocuments:@{
223+
@"a" : @{
224+
@"timestamp" : TimestampWithMicros(seconds, micros + 2),
225+
},
226+
@"b" : @{
227+
@"timestamp" : TimestampWithMicros(seconds, micros - 1),
228+
},
229+
@"c" : @{
230+
@"timestamp" : TimestampWithMicros(seconds, micros + 3),
231+
},
232+
@"d" : @{
233+
@"timestamp" : TimestampWithMicros(seconds, micros),
234+
},
235+
@"e" : @{
236+
@"timestamp" : TimestampWithMicros(seconds, micros + 1),
237+
}
238+
}];
239+
240+
FIRQuerySnapshot *querySnapshot = [self
241+
readDocumentSetForRef:[[testCollection queryWhereField:@"timestamp"
242+
isGreaterThanOrEqualTo:TimestampWithMicros(seconds, micros)]
243+
queryWhereField:@"timestamp"
244+
isLessThan:TimestampWithMicros(seconds, micros + 3)]];
245+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(querySnapshot), (@[ @"d", @"e", @"a" ]));
246+
}
247+
248+
- (void)testTimestampsAreTruncatedToMicroseconds {
249+
FIRTimestamp *nanos = [FIRTimestamp timestampWithSeconds:0 nanoseconds:123456789];
250+
FIRTimestamp *micros = [FIRTimestamp timestampWithSeconds:0 nanoseconds:123456000];
251+
FIRTimestamp *millis = [FIRTimestamp timestampWithSeconds:0 nanoseconds:123000000];
252+
FIRCollectionReference *testCollection = [self collectionRefWithDocuments:@{
253+
@"a" : @{@"timestamp" : nanos},
254+
}];
255+
256+
FIRQuerySnapshot *querySnapshot =
257+
[self readDocumentSetForRef:[testCollection queryWhereField:@"timestamp" isEqualTo:nanos]];
258+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(querySnapshot), (@[ @"a" ]));
259+
260+
// Because Timestamp should have been truncated to microseconds, the microsecond timestamp
261+
// should be considered equal to the nanosecond one.
262+
querySnapshot =
263+
[self readDocumentSetForRef:[testCollection queryWhereField:@"timestamp" isEqualTo:micros]];
264+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(querySnapshot), (@[ @"a" ]));
265+
266+
// The truncation is just to the microseconds, however, so the millisecond timestamp should be
267+
// treated as different and thus the query should return no results.
268+
querySnapshot =
269+
[self readDocumentSetForRef:[testCollection queryWhereField:@"timestamp" isEqualTo:millis]];
270+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(querySnapshot), (@[]));
271+
}
272+
195273
@end

Firestore/Source/API/FSTUserDataConverter.mm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,13 @@ - (nullable FSTFieldValue *)parseScalarValue:(nullable id)input context:(FSTPars
539539
} else if ([input isKindOfClass:[NSDate class]]) {
540540
return [FSTTimestampValue timestampValue:[FIRTimestamp timestampWithDate:input]];
541541

542+
} else if ([input isKindOfClass:[FIRTimestamp class]]) {
543+
FIRTimestamp *originalTimestamp = (FIRTimestamp *)input;
544+
FIRTimestamp *truncatedTimestamp =
545+
[FIRTimestamp timestampWithSeconds:originalTimestamp.seconds
546+
nanoseconds:originalTimestamp.nanoseconds / 1000 * 1000];
547+
return [FSTTimestampValue timestampValue:truncatedTimestamp];
548+
542549
} else if ([input isKindOfClass:[FIRGeoPoint class]]) {
543550
return [FSTGeoPointValue geoPointValue:input];
544551

0 commit comments

Comments
 (0)