Skip to content

Commit 14ea068

Browse files
authored
Make FSTTimestamp into a public Firestore class (#698)
- FSTTimestamp is now FIRTimestamp, under Firestore/Source/{Public,API}. This is a temporary solution; eventually, FIRTimestamp is supposed to live somewhere under Firebase; - move most internal Timestamp methods to the public header (the only exception is ISOString).
1 parent de00de2 commit 14ea068

33 files changed

+356
-242
lines changed

Firestore/Example/Firestore.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
5492E057202154AB00B64F25 /* FIRSnapshotMetadataTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04D202154AA00B64F25 /* FIRSnapshotMetadataTests.mm */; };
5555
5492E058202154AB00B64F25 /* FSTAPIHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04E202154AA00B64F25 /* FSTAPIHelpers.mm */; };
5656
5492E059202154AB00B64F25 /* FIRQuerySnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04F202154AA00B64F25 /* FIRQuerySnapshotTests.mm */; };
57-
5492E062202154B900B64F25 /* FSTTimestampTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E05B202154B800B64F25 /* FSTTimestampTests.mm */; };
5857
5492E063202154B900B64F25 /* FSTViewSnapshotTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E05C202154B800B64F25 /* FSTViewSnapshotTest.mm */; };
5958
5492E064202154B900B64F25 /* FSTQueryListenerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E05D202154B900B64F25 /* FSTQueryListenerTests.mm */; };
6059
5492E065202154B900B64F25 /* FSTViewTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E05E202154B900B64F25 /* FSTViewTests.mm */; };
@@ -153,6 +152,7 @@
153152
ABF6506C201131F8005F2C74 /* timestamp_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABF6506B201131F8005F2C74 /* timestamp_test.cc */; };
154153
AFE6114F0D4DAECBA7B7C089 /* Pods_Firestore_IntegrationTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2FA635DF5D116A67A7441CD /* Pods_Firestore_IntegrationTests.framework */; };
155154
B6152AD7202A53CB000E5744 /* document_key_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6152AD5202A5385000E5744 /* document_key_test.cc */; };
155+
B65D34A9203C995B0076A5E1 /* FIRTimestampTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B65D34A7203C99090076A5E1 /* FIRTimestampTest.m */; };
156156
B686F2AF2023DDEE0028D6BE /* field_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2AD2023DDB20028D6BE /* field_path_test.cc */; };
157157
B686F2B22025000D0028D6BE /* resource_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2B02024FFD70028D6BE /* resource_path_test.cc */; };
158158
C4E749275AD0FBDF9F4716A8 /* Pods_SwiftBuildTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32AD40BF6B0E849B07FFD05E /* Pods_SwiftBuildTest.framework */; };
@@ -243,7 +243,6 @@
243243
5492E04E202154AA00B64F25 /* FSTAPIHelpers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FSTAPIHelpers.mm; sourceTree = "<group>"; };
244244
5492E04F202154AA00B64F25 /* FIRQuerySnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FIRQuerySnapshotTests.mm; sourceTree = "<group>"; };
245245
5492E05A202154B800B64F25 /* FSTSyncEngine+Testing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FSTSyncEngine+Testing.h"; sourceTree = "<group>"; };
246-
5492E05B202154B800B64F25 /* FSTTimestampTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FSTTimestampTests.mm; sourceTree = "<group>"; };
247246
5492E05C202154B800B64F25 /* FSTViewSnapshotTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FSTViewSnapshotTest.mm; sourceTree = "<group>"; };
248247
5492E05D202154B900B64F25 /* FSTQueryListenerTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FSTQueryListenerTests.mm; sourceTree = "<group>"; };
249248
5492E05E202154B900B64F25 /* FSTViewTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FSTViewTests.mm; sourceTree = "<group>"; };
@@ -359,6 +358,7 @@
359358
ABF6506B201131F8005F2C74 /* timestamp_test.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = timestamp_test.cc; sourceTree = "<group>"; };
360359
B2FA635DF5D116A67A7441CD /* Pods_Firestore_IntegrationTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_IntegrationTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
361360
B6152AD5202A5385000E5744 /* document_key_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = document_key_test.cc; sourceTree = "<group>"; };
361+
B65D34A7203C99090076A5E1 /* FIRTimestampTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIRTimestampTest.m; sourceTree = "<group>"; };
362362
B686F2AD2023DDB20028D6BE /* field_path_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = field_path_test.cc; sourceTree = "<group>"; };
363363
B686F2B02024FFD70028D6BE /* resource_path_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_path_test.cc; sourceTree = "<group>"; };
364364
CE00BABB5A3AAB44A4C209E2 /* Pods-Firestore_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Tests/Pods-Firestore_Tests.debug.xcconfig"; sourceTree = "<group>"; };
@@ -697,6 +697,7 @@
697697
DE51B1831F0D48AC0013853F /* API */ = {
698698
isa = PBXGroup;
699699
children = (
700+
B65D34A7203C99090076A5E1 /* FIRTimestampTest.m */,
700701
5492E045202154AA00B64F25 /* FIRCollectionReferenceTests.mm */,
701702
5492E049202154AA00B64F25 /* FIRDocumentReferenceTests.mm */,
702703
5492E04B202154AA00B64F25 /* FIRDocumentSnapshotTests.mm */,
@@ -771,7 +772,6 @@
771772
5492E05D202154B900B64F25 /* FSTQueryListenerTests.mm */,
772773
5492E061202154B900B64F25 /* FSTQueryTests.mm */,
773774
5492E05A202154B800B64F25 /* FSTSyncEngine+Testing.h */,
774-
5492E05B202154B800B64F25 /* FSTTimestampTests.mm */,
775775
5492E05C202154B800B64F25 /* FSTViewSnapshotTest.mm */,
776776
5492E05E202154B900B64F25 /* FSTViewTests.mm */,
777777
);
@@ -1276,6 +1276,7 @@
12761276
5492E09E2021552D00B64F25 /* FSTEagerGarbageCollectorTests.mm in Sources */,
12771277
5492E0C62021557E00B64F25 /* FSTWatchChange+Testing.mm in Sources */,
12781278
5492E064202154B900B64F25 /* FSTQueryListenerTests.mm in Sources */,
1279+
B65D34A9203C995B0076A5E1 /* FIRTimestampTest.m in Sources */,
12791280
5492E03320213FFC00B64F25 /* FSTSyncEngineTestDriver.mm in Sources */,
12801281
AB380CFE201A2F4500D97691 /* string_util_test.cc in Sources */,
12811282
5492E0A42021552D00B64F25 /* FSTMemoryQueryCacheTests.mm in Sources */,
@@ -1353,7 +1354,6 @@
13531354
AB380D02201BC69F00D97691 /* bits_test.cc in Sources */,
13541355
548DB929200D59F600E00ABC /* comparison_test.cc in Sources */,
13551356
5492E03D2021401F00B64F25 /* FSTAssertTests.mm in Sources */,
1356-
5492E062202154B900B64F25 /* FSTTimestampTests.mm in Sources */,
13571357
AB38D93020236E21000A432D /* database_info_test.cc in Sources */,
13581358
5492E052202154AB00B64F25 /* FIRGeoPointTests.mm in Sources */,
13591359
5492E0C72021557E00B64F25 /* FSTSerializerBetaTests.mm in Sources */,
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright 2017 Google
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+
#import <XCTest/XCTest.h>
18+
19+
#import "Firestore/Source/API/FIRTimestamp+Internal.h"
20+
21+
NS_ASSUME_NONNULL_BEGIN
22+
23+
@interface FIRTimestampTest : XCTestCase
24+
@end
25+
26+
NSDate *TestDate(int year, int month, int day, int hour, int minute, int second) {
27+
NSDateComponents *comps = [[NSDateComponents alloc] init];
28+
comps.year = year;
29+
comps.month = month;
30+
comps.day = day;
31+
comps.hour = hour;
32+
comps.minute = minute;
33+
comps.second = second;
34+
// Force time zone to UTC to avoid these values changing due to daylight saving.
35+
comps.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
36+
37+
return [[NSCalendar currentCalendar] dateFromComponents:comps];
38+
}
39+
40+
@implementation FIRTimestampTest
41+
42+
- (void)testFromDate {
43+
// Use an NSDate such that its fractional seconds have an exact representation to avoid losing
44+
// precision.
45+
NSDate *input = [NSDate dateWithTimeIntervalSinceReferenceDate:1.5];
46+
47+
FIRTimestamp *actual = [FIRTimestamp timestampWithDate:input];
48+
static const int64_t kSecondsFromEpochToReferenceDate = 978307200;
49+
XCTAssertEqual(kSecondsFromEpochToReferenceDate + 1, actual.seconds);
50+
XCTAssertEqual(500000000, actual.nanoseconds);
51+
52+
FIRTimestamp *expected =
53+
[[FIRTimestamp alloc] initWithSeconds:(kSecondsFromEpochToReferenceDate + 1)
54+
nanoseconds:500000000];
55+
XCTAssertEqualObjects(expected, actual);
56+
}
57+
58+
- (void)testSO8601String {
59+
NSDate *date = TestDate(1912, 4, 14, 23, 40, 0);
60+
FIRTimestamp *timestamp =
61+
[[FIRTimestamp alloc] initWithSeconds:(int64_t)date.timeIntervalSince1970
62+
nanoseconds:543000000];
63+
XCTAssertEqualObjects(timestamp.ISO8601String, @"1912-04-14T23:40:00.543000000Z");
64+
}
65+
66+
- (void)testISO8601String_withLowMilliseconds {
67+
NSDate *date = TestDate(1912, 4, 14, 23, 40, 0);
68+
FIRTimestamp *timestamp =
69+
[[FIRTimestamp alloc] initWithSeconds:(int64_t)date.timeIntervalSince1970
70+
nanoseconds:7000000];
71+
XCTAssertEqualObjects(timestamp.ISO8601String, @"1912-04-14T23:40:00.007000000Z");
72+
}
73+
74+
- (void)testISO8601String_withLowNanos {
75+
FIRTimestamp *timestamp = [[FIRTimestamp alloc] initWithSeconds:0 nanoseconds:1];
76+
XCTAssertEqualObjects(timestamp.ISO8601String, @"1970-01-01T00:00:00.000000001Z");
77+
}
78+
79+
- (void)testISO8601String_withNegativeSeconds {
80+
FIRTimestamp *timestamp = [[FIRTimestamp alloc] initWithSeconds:-1 nanoseconds:999999999];
81+
XCTAssertEqualObjects(timestamp.ISO8601String, @"1969-12-31T23:59:59.999999999Z");
82+
}
83+
84+
- (void)testCompare {
85+
NSArray<FIRTimestamp *> *timestamps = @[
86+
[[FIRTimestamp alloc] initWithSeconds:12344 nanoseconds:999999999],
87+
[[FIRTimestamp alloc] initWithSeconds:12345 nanoseconds:0],
88+
[[FIRTimestamp alloc] initWithSeconds:12345 nanoseconds:000000001],
89+
[[FIRTimestamp alloc] initWithSeconds:12345 nanoseconds:99999999],
90+
[[FIRTimestamp alloc] initWithSeconds:12345 nanoseconds:100000000],
91+
[[FIRTimestamp alloc] initWithSeconds:12345 nanoseconds:100000001],
92+
[[FIRTimestamp alloc] initWithSeconds:12346 nanoseconds:0],
93+
];
94+
for (int i = 0; i < timestamps.count - 1; ++i) {
95+
XCTAssertEqual(NSOrderedAscending, [timestamps[i] compare:timestamps[i + 1]]);
96+
XCTAssertEqual(NSOrderedDescending, [timestamps[i + 1] compare:timestamps[i]]);
97+
}
98+
}
99+
100+
@end
101+
102+
NS_ASSUME_NONNULL_END

Firestore/Example/Tests/Core/FSTTimestampTests.mm

Lines changed: 0 additions & 88 deletions
This file was deleted.

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17+
#import <FirebaseFirestore/FIRTimestamp.h>
1718
#import <FirebaseFirestore/FirebaseFirestore.h>
1819

1920
#import <XCTest/XCTest.h>
@@ -220,4 +221,28 @@ - (void)testFieldsWithSpecialCharsCanBeUsedInOrderBy {
220221
[self awaitExpectations];
221222
}
222223

224+
- (NSDictionary<NSString *, id> *)testDataWithTimestamp:(FIRTimestamp *)timestamp {
225+
return @{
226+
@"timestamp" : [timestamp approximateDateValue],
227+
@"metadata" : @{@"nestedTimestamp" : [timestamp approximateDateValue]}
228+
};
229+
}
230+
231+
// This test should break once the default for how timestamps are returned changes.
232+
- (void)testThatDataContainsNativeDateType {
233+
NSDate *date = [NSDate date];
234+
FIRTimestamp *timestamp = [FIRTimestamp timestampWithDate:date];
235+
FIRDocumentReference *doc = [self documentRef];
236+
[self writeDocumentRef:doc data:[self testDataWithTimestamp:timestamp]];
237+
238+
FIRDocumentSnapshot *result = [self readDocumentForRef:doc];
239+
NSDate *resultDate = result.data[@"timestamp"];
240+
XCTAssertEqualWithAccuracy([resultDate timeIntervalSince1970], [date timeIntervalSince1970],
241+
0.000001);
242+
XCTAssertEqualObjects(result.data[@"timestamp"], resultDate);
243+
NSDate *resultNestedDate = result[@"metadata.nestedTimestamp"];
244+
XCTAssertEqualWithAccuracy([resultNestedDate timeIntervalSince1970], [date timeIntervalSince1970],
245+
0.000001);
246+
}
247+
223248
@end

Firestore/Example/Tests/Integration/FSTDatastoreTests.mm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#import <FirebaseFirestore/FirebaseFirestore.h>
1818

19+
#import <FirebaseFirestore/FIRTimestamp.h>
1920
#import <GRPCClient/GRPCCall+ChannelCredentials.h>
2021
#import <GRPCClient/GRPCCall+Tests.h>
2122
#import <XCTest/XCTest.h>
@@ -26,7 +27,6 @@
2627
#import "Firestore/Source/Core/FSTFirestoreClient.h"
2728
#import "Firestore/Source/Core/FSTQuery.h"
2829
#import "Firestore/Source/Core/FSTSnapshotVersion.h"
29-
#import "Firestore/Source/Core/FSTTimestamp.h"
3030
#import "Firestore/Source/Local/FSTQueryData.h"
3131
#import "Firestore/Source/Model/FSTDocumentKey.h"
3232
#import "Firestore/Source/Model/FSTFieldValue.h"
@@ -214,7 +214,7 @@ - (void)testStreamingWrite {
214214

215215
FSTSetMutation *mutation = [self setMutation];
216216
FSTMutationBatch *batch = [[FSTMutationBatch alloc] initWithBatchID:23
217-
localWriteTime:[FSTTimestamp timestamp]
217+
localWriteTime:[FIRTimestamp timestamp]
218218
mutations:@[ mutation ]];
219219
[_testWorkerQueue dispatchAsync:^{
220220
[_remoteStore commitBatch:batch];

Firestore/Example/Tests/Local/FSTLocalSerializerTests.mm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#import "Firestore/Source/Local/FSTLocalSerializer.h"
1818

19+
#import <FirebaseFirestore/FIRTimestamp.h>
1920
#import <XCTest/XCTest.h>
2021

2122
#import "Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.h"
@@ -29,7 +30,6 @@
2930
#import "Firestore/Protos/objc/google/type/Latlng.pbobjc.h"
3031
#import "Firestore/Source/Core/FSTQuery.h"
3132
#import "Firestore/Source/Core/FSTSnapshotVersion.h"
32-
#import "Firestore/Source/Core/FSTTimestamp.h"
3333
#import "Firestore/Source/Local/FSTQueryData.h"
3434
#import "Firestore/Source/Model/FSTDocument.h"
3535
#import "Firestore/Source/Model/FSTDocumentKey.h"
@@ -83,7 +83,7 @@ - (void)testEncodesMutationBatch {
8383
@"num" : @1 })
8484
precondition:[FSTPrecondition preconditionWithExists:YES]];
8585
FSTMutation *del = FSTTestDeleteMutation(@"baz/quux");
86-
FSTTimestamp *writeTime = [FSTTimestamp timestamp];
86+
FIRTimestamp *writeTime = [FIRTimestamp timestamp];
8787
FSTMutationBatch *model = [[FSTMutationBatch alloc] initWithBatchID:42
8888
localWriteTime:writeTime
8989
mutations:@[ set, patch, del ]];
@@ -109,7 +109,7 @@ - (void)testEncodesMutationBatch {
109109

110110
GPBTimestamp *writeTimeProto = [GPBTimestamp message];
111111
writeTimeProto.seconds = writeTime.seconds;
112-
writeTimeProto.nanos = writeTime.nanos;
112+
writeTimeProto.nanos = writeTime.nanoseconds;
113113

114114
FSTPBWriteBatch *batchProto = [FSTPBWriteBatch message];
115115
batchProto.batchId = 42;

Firestore/Example/Tests/Local/FSTLocalStoreTests.mm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616

1717
#import "Firestore/Source/Local/FSTLocalStore.h"
1818

19+
#import <FirebaseFirestore/FIRTimestamp.h>
1920
#import <XCTest/XCTest.h>
2021

2122
#import "Firestore/Source/Core/FSTQuery.h"
22-
#import "Firestore/Source/Core/FSTTimestamp.h"
2323
#import "Firestore/Source/Local/FSTEagerGarbageCollector.h"
2424
#import "Firestore/Source/Local/FSTLocalWriteResult.h"
2525
#import "Firestore/Source/Local/FSTNoOpGarbageCollector.h"
@@ -127,7 +127,7 @@ - (void)writeMutations:(NSArray<FSTMutation *> *)mutations {
127127
FSTLocalWriteResult *result = [self.localStore locallyWriteMutations:mutations];
128128
XCTAssertNotNil(result);
129129
[self.batches addObject:[[FSTMutationBatch alloc] initWithBatchID:result.batchID
130-
localWriteTime:[FSTTimestamp timestamp]
130+
localWriteTime:[FIRTimestamp timestamp]
131131
mutations:mutations]];
132132
self.lastChanges = result.changes;
133133
}
@@ -228,7 +228,7 @@ - (void)testMutationBatchKeys {
228228
FSTMutation *set1 = FSTTestSetMutation(@"foo/bar", @{@"foo" : @"bar"});
229229
FSTMutation *set2 = FSTTestSetMutation(@"bar/baz", @{@"bar" : @"baz"});
230230
FSTMutationBatch *batch = [[FSTMutationBatch alloc] initWithBatchID:1
231-
localWriteTime:[FSTTimestamp timestamp]
231+
localWriteTime:[FIRTimestamp timestamp]
232232
mutations:@[ set1, set2 ]];
233233
FSTDocumentKeySet *keys = [batch keys];
234234
XCTAssertEqual(keys.count, 2);

0 commit comments

Comments
 (0)