FNodeTests.m 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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 "FSnapshotUtilities.h"
  19. #import "FEmptyNode.h"
  20. #import "FChildrenNode.h"
  21. #import "FLeafNode.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 = [FSnapshotUtilities nodeFrom:@{ @"one": @1, @"two": @2, @".priority": @"prio"}];
  84. id<FNode> nodeTwo = [[FEmptyNode emptyNode] updateImmediateChild:@"one" withNewChild:[FSnapshotUtilities nodeFrom:@1]];
  85. nodeTwo = [nodeTwo updateImmediateChild:@"two" withNewChild:[FSnapshotUtilities nodeFrom:@2]];
  86. nodeTwo = [nodeTwo updatePriority:[FSnapshotUtilities nodeFrom:@"prio"]];
  87. XCTAssertEqualObjects(nodeOne, nodeTwo);
  88. XCTAssertEqual(nodeOne.hash, nodeTwo.hash);
  89. XCTAssertFalse([[nodeOne updatePriority:[FEmptyNode emptyNode]] isEqual:nodeOne]);
  90. XCTAssertFalse([[nodeOne updateImmediateChild:@"one" withNewChild:[FEmptyNode emptyNode]] isEqual:nodeOne]);
  91. XCTAssertFalse([[nodeOne updateImmediateChild:@"one" withNewChild:[FSnapshotUtilities nodeFrom:@2]] isEqual:nodeOne]);
  92. }
  93. - (void)testLeadingZerosWorkCorrectly {
  94. NSDictionary *data = @{ @"1": @1, @"01": @2, @"001": @3, @"0001": @4 };
  95. id<FNode> node = [FSnapshotUtilities nodeFrom:data];
  96. XCTAssertEqualObjects([node getImmediateChild:@"1"].val, @1);
  97. XCTAssertEqualObjects([node getImmediateChild:@"01"].val, @2);
  98. XCTAssertEqualObjects([node getImmediateChild:@"001"].val, @3);
  99. XCTAssertEqualObjects([node getImmediateChild:@"0001"].val, @4);
  100. }
  101. - (void)testLeadindZerosArePreservedInValue {
  102. NSDictionary *data = @{ @"1": @1, @"01": @2, @"001": @3, @"0001": @4 };
  103. XCTAssertEqualObjects([FSnapshotUtilities nodeFrom:data].val, data);
  104. }
  105. - (void)testEmptyNodeEqualsEmptyChildrenNode {
  106. XCTAssertEqualObjects([FEmptyNode emptyNode], [[FChildrenNode alloc] init]);
  107. XCTAssertEqualObjects([[FChildrenNode alloc] init], [FEmptyNode emptyNode]);
  108. XCTAssertEqual([[FChildrenNode alloc] init].hash, [FEmptyNode emptyNode].hash);
  109. }
  110. - (void)testUpdatingEmptyChildrenDoesntOverwriteLeafNode {
  111. FLeafNode *node = [[FLeafNode alloc] initWithValue:@"value"];
  112. XCTAssertEqualObjects(node, [node updateChild:[FPath pathWithString:@".priority"] withNewChild:[FEmptyNode emptyNode]]);
  113. XCTAssertEqualObjects(node, [node updateChild:[FPath pathWithString:@"child"] withNewChild:[FEmptyNode emptyNode]]);
  114. XCTAssertEqualObjects(node, [node updateChild:[FPath pathWithString:@"child/.priority"] withNewChild:[FEmptyNode emptyNode]]);
  115. XCTAssertEqualObjects(node, [node updateImmediateChild:@"child" withNewChild:[FEmptyNode emptyNode]]);
  116. XCTAssertEqualObjects(node, [node updateImmediateChild:@".priority" withNewChild:[FEmptyNode emptyNode]]);
  117. }
  118. - (void)testUpdatingPrioritiesOnEmptyNodesIsANoOp {
  119. id<FNode> priority = [FSnapshotUtilities nodeFrom:@"prio"];
  120. XCTAssertTrue([[[[FEmptyNode emptyNode] updatePriority:priority] getPriority] isEmpty]);
  121. XCTAssertTrue([[[[FEmptyNode emptyNode] updateChild:[FPath pathWithString:@".priority"] withNewChild:priority] getPriority] isEmpty]);
  122. XCTAssertTrue([[[[FEmptyNode emptyNode] updateImmediateChild:@".priority" withNewChild:priority] getPriority] isEmpty]);
  123. id<FNode> valueNode = [FSnapshotUtilities nodeFrom:@"value"];
  124. FPath *childPath = [FPath pathWithString:@"child"];
  125. id<FNode> reemptiedChildren = [[[FEmptyNode emptyNode] updateChild:childPath withNewChild:valueNode] updateChild:childPath withNewChild:[FEmptyNode emptyNode]];
  126. XCTAssertTrue([[[reemptiedChildren updatePriority:priority] getPriority] isEmpty]);
  127. XCTAssertTrue([[[reemptiedChildren updateChild:[FPath pathWithString:@".priority"] withNewChild:priority] getPriority] isEmpty]);
  128. XCTAssertTrue([[[reemptiedChildren updateImmediateChild:@".priority" withNewChild:priority] getPriority] isEmpty]);
  129. }
  130. - (void)testDeletingLastChildFromChildrenNodeRemovesPriority {
  131. id<FNode> priority = [FSnapshotUtilities nodeFrom:@"prio"];
  132. id<FNode> valueNode = [FSnapshotUtilities nodeFrom:@"value"];
  133. FPath *childPath = [FPath pathWithString:@"child"];
  134. id<FNode> withPriority = [[[FEmptyNode emptyNode] updateChild:childPath withNewChild:valueNode] updatePriority:priority];
  135. XCTAssertEqualObjects(priority, [withPriority getPriority]);
  136. id<FNode> deletedChild = [withPriority updateChild:childPath withNewChild:[FEmptyNode emptyNode]];
  137. XCTAssertTrue([[deletedChild getPriority] isEmpty]);
  138. }
  139. - (void)testFromNodeReturnsEmptyNodesWithoutPriority {
  140. id<FNode> empty1 = [FSnapshotUtilities nodeFrom:@{ @".priority": @"prio" }];
  141. XCTAssertTrue([[empty1 getPriority] isEmpty]);
  142. id<FNode> empty2 = [FSnapshotUtilities nodeFrom:@{ @"dummy": [NSNull null], @".priority": @"prio" }];
  143. XCTAssertTrue([[empty2 getPriority] isEmpty]);
  144. }
  145. @end