FNodeTests.m 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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. #import <Foundation/Foundation.h>
  17. #import <XCTest/XCTest.h>
  18. #import "FirebaseDatabase/Sources/Snapshot/FChildrenNode.h"
  19. #import "FirebaseDatabase/Sources/Snapshot/FEmptyNode.h"
  20. #import "FirebaseDatabase/Sources/Snapshot/FLeafNode.h"
  21. #import "FirebaseDatabase/Sources/Snapshot/FSnapshotUtilities.h"
  22. @interface FNodeTests : XCTestCase
  23. @end
  24. @implementation FNodeTests
  25. - (void)testLeafNodeEqualsHashCode {
  26. id<FNode> falseNode = [FSnapshotUtilities nodeFrom:@NO];
  27. id<FNode> trueNode = [FSnapshotUtilities nodeFrom:@YES];
  28. id<FNode> stringOneNode = [FSnapshotUtilities nodeFrom:@"one"];
  29. id<FNode> stringTwoNode = [FSnapshotUtilities nodeFrom:@"two"];
  30. id<FNode> zeroNode = [FSnapshotUtilities nodeFrom:@0];
  31. id<FNode> oneNode = [FSnapshotUtilities nodeFrom:@1];
  32. id<FNode> emptyNode1 = [FSnapshotUtilities nodeFrom:nil];
  33. id<FNode> emptyNode2 = [FSnapshotUtilities nodeFrom:[NSNull null]];
  34. XCTAssertEqualObjects(falseNode, [FSnapshotUtilities nodeFrom:@NO]);
  35. XCTAssertEqual(falseNode.hash, [FSnapshotUtilities nodeFrom:@NO].hash);
  36. XCTAssertEqualObjects(trueNode, [FSnapshotUtilities nodeFrom:@YES]);
  37. XCTAssertEqual(trueNode.hash, [FSnapshotUtilities nodeFrom:@YES].hash);
  38. XCTAssertFalse([falseNode isEqual:trueNode]);
  39. XCTAssertFalse([falseNode isEqual:oneNode]);
  40. XCTAssertFalse([falseNode isEqual:stringOneNode]);
  41. XCTAssertFalse([falseNode isEqual:emptyNode1]);
  42. XCTAssertEqualObjects(stringOneNode, [FSnapshotUtilities nodeFrom:@"one"]);
  43. XCTAssertEqual(stringOneNode.hash, [FSnapshotUtilities nodeFrom:@"one"].hash);
  44. XCTAssertFalse([stringOneNode isEqual:stringTwoNode]);
  45. XCTAssertFalse([stringOneNode isEqual:emptyNode1]);
  46. XCTAssertFalse([stringOneNode isEqual:oneNode]);
  47. XCTAssertFalse([stringOneNode isEqual:trueNode]);
  48. XCTAssertEqualObjects(zeroNode, [FSnapshotUtilities nodeFrom:@0]);
  49. XCTAssertEqual(zeroNode.hash, [FSnapshotUtilities nodeFrom:@0].hash);
  50. XCTAssertFalse([zeroNode isEqual:oneNode]);
  51. XCTAssertFalse([zeroNode isEqual:emptyNode1]);
  52. XCTAssertFalse([zeroNode isEqual:falseNode]);
  53. XCTAssertEqualObjects(emptyNode1, emptyNode2);
  54. XCTAssertEqual(emptyNode1.hash, emptyNode2.hash);
  55. }
  56. - (void)testLeafNodePrioritiesEqualsHashCode {
  57. id<FNode> oneOne = [FSnapshotUtilities nodeFrom:@1 priority:@1];
  58. id<FNode> stringOne = [FSnapshotUtilities nodeFrom:@"value" priority:@1];
  59. id<FNode> oneString = [FSnapshotUtilities nodeFrom:@1 priority:@"value"];
  60. id<FNode> stringString = [FSnapshotUtilities nodeFrom:@"value" priority:@"value"];
  61. XCTAssertEqualObjects(oneOne, [FSnapshotUtilities nodeFrom:@1 priority:@1]);
  62. XCTAssertEqual(oneOne.hash, [FSnapshotUtilities nodeFrom:@1 priority:@1].hash);
  63. XCTAssertFalse([oneOne isEqual:stringOne]);
  64. XCTAssertFalse([oneOne isEqual:oneString]);
  65. XCTAssertFalse([oneOne isEqual:stringString]);
  66. XCTAssertEqualObjects(stringOne, [FSnapshotUtilities nodeFrom:@"value" priority:@1]);
  67. XCTAssertEqual(stringOne.hash, [FSnapshotUtilities nodeFrom:@"value" priority:@1].hash);
  68. XCTAssertFalse([stringOne isEqual:oneOne]);
  69. XCTAssertFalse([stringOne isEqual:oneString]);
  70. XCTAssertFalse([stringOne isEqual:stringString]);
  71. XCTAssertEqualObjects(oneString, [FSnapshotUtilities nodeFrom:@1 priority:@"value"]);
  72. XCTAssertEqual(oneString.hash, [FSnapshotUtilities nodeFrom:@1 priority:@"value"].hash);
  73. XCTAssertFalse([oneString isEqual:stringOne]);
  74. XCTAssertFalse([oneString isEqual:oneOne]);
  75. XCTAssertFalse([oneString isEqual:stringString]);
  76. XCTAssertEqualObjects(stringString, [FSnapshotUtilities nodeFrom:@"value" priority:@"value"]);
  77. XCTAssertEqual(stringString.hash, [FSnapshotUtilities nodeFrom:@"value" priority:@"value"].hash);
  78. XCTAssertFalse([stringString isEqual:stringOne]);
  79. XCTAssertFalse([stringString isEqual:oneString]);
  80. XCTAssertFalse([stringString isEqual:oneOne]);
  81. }
  82. - (void)testChildrenNodeEqualsHashCode {
  83. id<FNode> nodeOne =
  84. [FSnapshotUtilities nodeFrom:@{@"one" : @1, @"two" : @2, @".priority" : @"prio"}];
  85. id<FNode> nodeTwo =
  86. [[FEmptyNode emptyNode] updateImmediateChild:@"one"
  87. withNewChild:[FSnapshotUtilities nodeFrom:@1]];
  88. nodeTwo = [nodeTwo updateImmediateChild:@"two" withNewChild:[FSnapshotUtilities nodeFrom:@2]];
  89. nodeTwo = [nodeTwo updatePriority:[FSnapshotUtilities nodeFrom:@"prio"]];
  90. XCTAssertEqualObjects(nodeOne, nodeTwo);
  91. XCTAssertEqual(nodeOne.hash, nodeTwo.hash);
  92. XCTAssertFalse([[nodeOne updatePriority:[FEmptyNode emptyNode]] isEqual:nodeOne]);
  93. XCTAssertFalse([[nodeOne updateImmediateChild:@"one"
  94. withNewChild:[FEmptyNode emptyNode]] isEqual:nodeOne]);
  95. XCTAssertFalse([[nodeOne updateImmediateChild:@"one"
  96. withNewChild:[FSnapshotUtilities nodeFrom:@2]] isEqual:nodeOne]);
  97. }
  98. - (void)testLeadingZerosWorkCorrectly {
  99. NSDictionary *data = @{@"1" : @1, @"01" : @2, @"001" : @3, @"0001" : @4};
  100. id<FNode> node = [FSnapshotUtilities nodeFrom:data];
  101. XCTAssertEqualObjects([node getImmediateChild:@"1"].val, @1);
  102. XCTAssertEqualObjects([node getImmediateChild:@"01"].val, @2);
  103. XCTAssertEqualObjects([node getImmediateChild:@"001"].val, @3);
  104. XCTAssertEqualObjects([node getImmediateChild:@"0001"].val, @4);
  105. }
  106. - (void)testLeadindZerosArePreservedInValue {
  107. NSDictionary *data = @{@"1" : @1, @"01" : @2, @"001" : @3, @"0001" : @4};
  108. XCTAssertEqualObjects([FSnapshotUtilities nodeFrom:data].val, data);
  109. }
  110. - (void)testEmptyNodeEqualsEmptyChildrenNode {
  111. XCTAssertEqualObjects([FEmptyNode emptyNode], [[FChildrenNode alloc] init]);
  112. XCTAssertEqualObjects([[FChildrenNode alloc] init], [FEmptyNode emptyNode]);
  113. XCTAssertEqual([[FChildrenNode alloc] init].hash, [FEmptyNode emptyNode].hash);
  114. }
  115. - (void)testUpdatingEmptyChildrenDoesntOverwriteLeafNode {
  116. FLeafNode *node = [[FLeafNode alloc] initWithValue:@"value"];
  117. XCTAssertEqualObjects(node, [node updateChild:[FPath pathWithString:@".priority"]
  118. withNewChild:[FEmptyNode emptyNode]]);
  119. XCTAssertEqualObjects(node, [node updateChild:[FPath pathWithString:@"child"]
  120. withNewChild:[FEmptyNode emptyNode]]);
  121. XCTAssertEqualObjects(node, [node updateChild:[FPath pathWithString:@"child/.priority"]
  122. withNewChild:[FEmptyNode emptyNode]]);
  123. XCTAssertEqualObjects(node, [node updateImmediateChild:@"child"
  124. withNewChild:[FEmptyNode emptyNode]]);
  125. XCTAssertEqualObjects(node, [node updateImmediateChild:@".priority"
  126. withNewChild:[FEmptyNode emptyNode]]);
  127. }
  128. - (void)testUpdatingPrioritiesOnEmptyNodesIsANoOp {
  129. id<FNode> priority = [FSnapshotUtilities nodeFrom:@"prio"];
  130. XCTAssertTrue([[[[FEmptyNode emptyNode] updatePriority:priority] getPriority] isEmpty]);
  131. XCTAssertTrue([[[[FEmptyNode emptyNode] updateChild:[FPath pathWithString:@".priority"]
  132. withNewChild:priority] getPriority] isEmpty]);
  133. XCTAssertTrue([[[[FEmptyNode emptyNode] updateImmediateChild:@".priority"
  134. withNewChild:priority] getPriority] isEmpty]);
  135. id<FNode> valueNode = [FSnapshotUtilities nodeFrom:@"value"];
  136. FPath *childPath = [FPath pathWithString:@"child"];
  137. id<FNode> reemptiedChildren = [[[FEmptyNode emptyNode]
  138. updateChild:childPath
  139. withNewChild:valueNode] updateChild:childPath withNewChild:[FEmptyNode emptyNode]];
  140. XCTAssertTrue([[[reemptiedChildren updatePriority:priority] getPriority] isEmpty]);
  141. XCTAssertTrue([[[reemptiedChildren updateChild:[FPath pathWithString:@".priority"]
  142. withNewChild:priority] getPriority] isEmpty]);
  143. XCTAssertTrue([[[reemptiedChildren updateImmediateChild:@".priority"
  144. withNewChild:priority] getPriority] isEmpty]);
  145. }
  146. - (void)testDeletingLastChildFromChildrenNodeRemovesPriority {
  147. id<FNode> priority = [FSnapshotUtilities nodeFrom:@"prio"];
  148. id<FNode> valueNode = [FSnapshotUtilities nodeFrom:@"value"];
  149. FPath *childPath = [FPath pathWithString:@"child"];
  150. id<FNode> withPriority = [[[FEmptyNode emptyNode] updateChild:childPath
  151. withNewChild:valueNode] updatePriority:priority];
  152. XCTAssertEqualObjects(priority, [withPriority getPriority]);
  153. id<FNode> deletedChild = [withPriority updateChild:childPath withNewChild:[FEmptyNode emptyNode]];
  154. XCTAssertTrue([[deletedChild getPriority] isEmpty]);
  155. }
  156. - (void)testFromNodeReturnsEmptyNodesWithoutPriority {
  157. id<FNode> empty1 = [FSnapshotUtilities nodeFrom:@{@".priority" : @"prio"}];
  158. XCTAssertTrue([[empty1 getPriority] isEmpty]);
  159. id<FNode> empty2 =
  160. [FSnapshotUtilities nodeFrom:@{@"dummy" : [NSNull null], @".priority" : @"prio"}];
  161. XCTAssertTrue([[empty2 getPriority] isEmpty]);
  162. }
  163. @end