FIRNumericTransformTests.mm 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * Copyright 2019 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. #import <FirebaseFirestore/FirebaseFirestore.h>
  17. #import <XCTest/XCTest.h>
  18. #import "Firestore/Source/API/FIRFieldValue+Internal.h"
  19. #import "Firestore/Example/Tests/Util/FSTEventAccumulator.h"
  20. #import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
  21. double DOUBLE_EPSILON = 0.000001;
  22. @interface FIRNumericTransformTests : FSTIntegrationTestCase
  23. @end
  24. @implementation FIRNumericTransformTests {
  25. // A document reference to read and write to.
  26. FIRDocumentReference *_docRef;
  27. // Accumulator used to capture events during the test.
  28. FSTEventAccumulator<FIRDocumentSnapshot *> *_accumulator;
  29. // Listener registration for a listener maintained during the course of the test.
  30. id<FIRListenerRegistration> _listenerRegistration;
  31. }
  32. - (void)setUp {
  33. [super setUp];
  34. _docRef = [self documentRef];
  35. _accumulator = [FSTEventAccumulator accumulatorForTest:self];
  36. _listenerRegistration =
  37. [_docRef addSnapshotListenerWithIncludeMetadataChanges:YES
  38. listener:_accumulator.valueEventHandler];
  39. // Wait for initial nil snapshot to avoid potential races.
  40. FIRDocumentSnapshot *initialSnapshot = [_accumulator awaitEventWithName:@"initial event"];
  41. XCTAssertFalse(initialSnapshot.exists);
  42. }
  43. - (void)tearDown {
  44. [_listenerRegistration remove];
  45. [super tearDown];
  46. }
  47. #pragma mark - Test Helpers
  48. /** Writes some initial data and consumes the events generated. */
  49. - (void)writeInitialData:(NSDictionary<NSString *, id> *)data {
  50. [self writeDocumentRef:_docRef data:data];
  51. XCTAssertEqualObjects([_accumulator awaitLocalEvent].data, data);
  52. XCTAssertEqualObjects([_accumulator awaitRemoteEvent].data, data);
  53. }
  54. - (void)expectLocalAndRemoteValue:(int64_t)expectedSum {
  55. FIRDocumentSnapshot *snap = [_accumulator awaitLocalEvent];
  56. XCTAssertEqualObjects(@(expectedSum), snap[@"sum"]);
  57. snap = [_accumulator awaitRemoteEvent];
  58. XCTAssertEqualObjects(@(expectedSum), snap[@"sum"]);
  59. }
  60. - (void)expectApproximateLocalAndRemoteValue:(double)expectedSum {
  61. FIRDocumentSnapshot *snap = [_accumulator awaitLocalEvent];
  62. XCTAssertEqualWithAccuracy(expectedSum, [snap[@"sum"] doubleValue], DOUBLE_EPSILON);
  63. snap = [_accumulator awaitRemoteEvent];
  64. XCTAssertEqualWithAccuracy(expectedSum, [snap[@"sum"] doubleValue], DOUBLE_EPSILON);
  65. }
  66. #pragma mark - Test Cases
  67. - (void)testCreateDocumentWithIncrement {
  68. [self writeDocumentRef:_docRef
  69. data:@{@"sum" : [FIRFieldValue fieldValueForIntegerIncrement:1337]}];
  70. [self expectLocalAndRemoteValue:1337];
  71. }
  72. - (void)testMergeOnNonExistingDocumentWithIncrement {
  73. [self mergeDocumentRef:_docRef
  74. data:@{@"sum" : [FIRFieldValue fieldValueForIntegerIncrement:1337]}];
  75. [self expectLocalAndRemoteValue:1337];
  76. }
  77. - (void)testIntegerIncrementWithExistingInteger {
  78. [self writeInitialData:@{@"sum" : @1337}];
  79. [self updateDocumentRef:_docRef data:@{@"sum" : [FIRFieldValue fieldValueForIntegerIncrement:1]}];
  80. [self expectLocalAndRemoteValue:1338];
  81. }
  82. - (void)testDoubleIncrementWithExistingDouble {
  83. [self writeInitialData:@{@"sum" : @13.37}];
  84. [self updateDocumentRef:_docRef
  85. data:@{@"sum" : [FIRFieldValue fieldValueForDoubleIncrement:0.1]}];
  86. [self expectApproximateLocalAndRemoteValue:13.47];
  87. }
  88. - (void)testIntegerIncrementWithExistingDouble {
  89. [self writeInitialData:@{@"sum" : @13.37}];
  90. [self updateDocumentRef:_docRef data:@{@"sum" : [FIRFieldValue fieldValueForIntegerIncrement:1]}];
  91. [self expectApproximateLocalAndRemoteValue:14.37];
  92. }
  93. - (void)testDoubleIncrementWithExistingInteger {
  94. [self writeInitialData:@{@"sum" : @1337}];
  95. [self updateDocumentRef:_docRef
  96. data:@{@"sum" : [FIRFieldValue fieldValueForDoubleIncrement:0.1]}];
  97. [self expectApproximateLocalAndRemoteValue:1337.1];
  98. }
  99. - (void)testIntegerIncrementWithExistingString {
  100. [self writeInitialData:@{@"sum" : @"overwrite"}];
  101. [self updateDocumentRef:_docRef
  102. data:@{@"sum" : [FIRFieldValue fieldValueForIntegerIncrement:1337]}];
  103. [self expectLocalAndRemoteValue:1337];
  104. }
  105. - (void)testDoubleIncrementWithExistingString {
  106. [self writeInitialData:@{@"sum" : @"overwrite"}];
  107. [self updateDocumentRef:_docRef
  108. data:@{@"sum" : [FIRFieldValue fieldValueForDoubleIncrement:13.37]}];
  109. [self expectApproximateLocalAndRemoteValue:13.37];
  110. }
  111. - (void)testIncrementTwiceInABatch {
  112. [self writeInitialData:@{@"sum" : @"overwrite"}];
  113. FIRWriteBatch *batch = _docRef.firestore.batch;
  114. [batch updateData:@{@"sum" : [FIRFieldValue fieldValueForIntegerIncrement:1]}
  115. forDocument:_docRef];
  116. [batch updateData:@{@"sum" : [FIRFieldValue fieldValueForIntegerIncrement:1]}
  117. forDocument:_docRef];
  118. [batch
  119. commitWithCompletion:[self completionForExpectationWithName:@"testIncrementTwiceInABatch"]];
  120. [self awaitExpectations];
  121. [self expectApproximateLocalAndRemoteValue:2];
  122. }
  123. - (void)testIncrementDeleteIncrementInABatch {
  124. [self writeInitialData:@{@"sum" : @"overwrite"}];
  125. FIRWriteBatch *batch = _docRef.firestore.batch;
  126. [batch updateData:@{@"sum" : [FIRFieldValue fieldValueForIntegerIncrement:1]}
  127. forDocument:_docRef];
  128. [batch updateData:@{@"sum" : [FIRFieldValue fieldValueForDelete]} forDocument:_docRef];
  129. [batch updateData:@{@"sum" : [FIRFieldValue fieldValueForIntegerIncrement:3]}
  130. forDocument:_docRef];
  131. [batch commitWithCompletion:
  132. [self completionForExpectationWithName:@"testIncrementDeleteIncrementInABatch"]];
  133. [self awaitExpectations];
  134. [self expectApproximateLocalAndRemoteValue:3];
  135. }
  136. - (void)testServerTimestampAndIncrement {
  137. // This test stacks two pending transforms (a ServerTimestamp and an Increment transform)
  138. // and reproduces the setup that was reported in
  139. // https://github.com/firebase/firebase-android-sdk/issues/491
  140. // In our original code, a NumericIncrementTransform could cause us to decode the
  141. // ServerTimestamp as part of a FSTPatchMutation, which triggered an assertion failure.
  142. [self writeInitialData:@{@"val" : @"overwrite"}];
  143. [self disableNetwork];
  144. [_docRef updateData:@{@"val" : [FIRFieldValue fieldValueForServerTimestamp]}];
  145. [_docRef updateData:@{@"val" : [FIRFieldValue fieldValueForIntegerIncrement:1]}];
  146. FIRDocumentSnapshot *snap = [_accumulator awaitLocalEvent];
  147. XCTAssertNotNil([snap valueForField:@"val"
  148. serverTimestampBehavior:FIRServerTimestampBehaviorEstimate]);
  149. snap = [_accumulator awaitLocalEvent];
  150. XCTAssertEqualObjects(@1, snap[@"val"]);
  151. [self enableNetwork];
  152. snap = [_accumulator awaitRemoteEvent];
  153. XCTAssertEqualObjects(@1, snap[@"val"]);
  154. }
  155. - (void)testMultipleDoubleIncrements {
  156. [self writeInitialData:@{@"sum" : @"0.0"}];
  157. [self disableNetwork];
  158. [_docRef updateData:@{@"sum" : [FIRFieldValue fieldValueForDoubleIncrement:0.1]}];
  159. [_docRef updateData:@{@"sum" : [FIRFieldValue fieldValueForDoubleIncrement:0.01]}];
  160. [_docRef updateData:@{@"sum" : [FIRFieldValue fieldValueForDoubleIncrement:0.001]}];
  161. FIRDocumentSnapshot *snap = [_accumulator awaitLocalEvent];
  162. XCTAssertEqualWithAccuracy(0.1, [snap[@"sum"] doubleValue], DOUBLE_EPSILON);
  163. snap = [_accumulator awaitLocalEvent];
  164. XCTAssertEqualWithAccuracy(0.11, [snap[@"sum"] doubleValue], DOUBLE_EPSILON);
  165. snap = [_accumulator awaitLocalEvent];
  166. XCTAssertEqualWithAccuracy(0.111, [snap[@"sum"] doubleValue], DOUBLE_EPSILON);
  167. [self enableNetwork];
  168. snap = [_accumulator awaitRemoteEvent];
  169. XCTAssertEqualWithAccuracy(0.111, [snap[@"sum"] doubleValue], DOUBLE_EPSILON);
  170. }
  171. @end