public void TestChildNodeBasicFunctionality() { rootNode = rootNode.AsSubdivision(); Assert.False(rootNode.IsUnit, "Parent should not be a unit."); Assert.True(rootNode.IsSubdivision, "Parent should be a subdivision."); ProductBrand childDimension = ProductDimensions.CreateBrand("google"); ProductPartitionNode childNode = rootNode.AddChild(childDimension); Assert.AreSame(childDimension, childNode.Dimension, "Child node merely wraps the " + "underlying dimension node."); Assert.AreSame(rootNode, childNode.Parent, "child.GetParent should return parentNode."); Assert.That(childNode.ProductPartitionId == 0, "Partition ID is incorrect."); Assert.That(childNode.Children.Count() == 0, "ChildNode should not have any children."); Assert.True(childNode.IsUnit, "New node should be a unit node by default."); Assert.True(childNode.IsBiddableUnit, "New node should be a biddable unit node by default."); Assert.That(rootNode.HasChild(childDimension), "rootNode.HasChild should return true when " + "passed the dimension of the added child"); Assert.False(rootNode.HasChild(ProductDimensions.CreateBrand("xyz")), "rootNode.HasChild " + "should return false when passed a dimension for a nonexistent child"); Assert.False(rootNode.HasChild(null), "rootNode.HasChild should return false when passed " + "a dimension for a nonexistent child"); }
public void TestNavigation() { rootNode = rootNode.AsSubdivision(); ProductBrand brandGoogle = ProductDimensions.CreateBrand("google"); ProductBrand brandOther = ProductDimensions.CreateBrand(null); ProductCanonicalCondition conditionNew = ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.NEW); ProductCanonicalCondition conditionUsed = ProductDimensions.CreateCanonicalCondition(ProductCanonicalConditionCondition.USED); ProductCanonicalCondition conditionOther = ProductDimensions.CreateCanonicalCondition(); // Build up the brand = Google node under the root. ProductPartitionNode brandGoogleNode = rootNode.AddChild(brandGoogle).AsSubdivision(); brandGoogleNode.AddChild(conditionNew); brandGoogleNode.AddChild(conditionUsed); brandGoogleNode.AddChild(conditionOther); Assert.True(brandGoogleNode.HasChild(conditionNew), "HasChild should return true for existing child dimension."); Assert.AreSame(brandGoogleNode, brandGoogleNode.GetChild(conditionNew).Parent, "parent->GetChild->getParent should return parent."); Assert.True(brandGoogleNode.HasChild(conditionUsed), "HasChild should return true for existing child dimension."); Assert.AreSame(brandGoogleNode, brandGoogleNode.GetChild(conditionUsed).Parent, "parent->GetChild->getParent should return parent."); Assert.True(brandGoogleNode.HasChild(conditionOther), "HasChild should return true for existing child dimension."); Assert.AreSame(brandGoogleNode, brandGoogleNode.GetChild(conditionOther).Parent, "parent->GetChild->getParent should return parent."); // Build up the brand = null (other) node under the root. ProductPartitionNode brandOtherNode = rootNode.AddChild(brandOther).AsSubdivision(); brandOtherNode.AddChild(conditionNew); Assert.True(brandOtherNode.HasChild(conditionNew), "HasChild should return true for existing child dimension."); Assert.AreSame(brandOtherNode, brandOtherNode.GetChild(conditionNew).Parent, "parent->GetChild->getParent should return parent."); Assert.False(brandOtherNode.HasChild(conditionUsed), "HasChild should return false for nonexistent child dimension."); Assert.False(brandOtherNode.HasChild(conditionOther), "HasChild should return false for nonexistent child dimension."); brandOtherNode.AddChild(conditionOther); Assert.True(brandOtherNode.HasChild(conditionOther), "HasChild should return true for existing child dimension."); Assert.AreSame(brandOtherNode, brandOtherNode.GetChild(conditionOther).Parent, "parent->GetChild->getParent should return parent."); // Remove one of the children of brand = null. brandOtherNode.RemoveChild(conditionOther); Assert.False(brandOtherNode.HasChild(conditionOther), "HasChild should return false for a removed child dimension."); // Remove the rest of the children of brand = null. brandOtherNode.RemoveAllChildren(); Assert.False(brandOtherNode.HasChild(conditionNew), "HasChild should return false for any removed child dimension."); Assert.False(brandOtherNode.HasChild(conditionUsed), "HasChild should return false for any removed child dimension."); }
/// <summary> /// Adds to the operations list all operations required to mutate /// <paramref name="originalNode"/> to the state* of /// <paramref name="newNode"/>. /// </summary> /// <param name="originalNode">The original node.</param> /// <param name="newNode">The new node.</param> /// <param name="ops">The operations list to add to.</param> /// <param name="idGenerator">The temporary ID generator for ADD operations.</param> /// <returns>The set of child product dimensions that require further /// processing.</returns> private void AddMutateOperations(ProductPartitionNode originalNode, ProductPartitionNode newNode, List<OperationPair> ops, TemporaryIdGenerator idGenerator) { NodeDifference nodeDifference = Diff(originalNode, newNode, dimensionComparator); bool isProcessChildren; switch (nodeDifference) { case NodeDifference.NEW_NODE: ops.AddRange(CreateAddOperations(newNode, idGenerator)); // No need to further process children. The ADD operations above will include operations // for all children of newNode. isProcessChildren = false; break; case NodeDifference.REMOVED_NODE: ops.Add(CreateRemoveOperation(originalNode)); // No need to further process children. The REMOVE operation above will perform a // cascading delete of all children of newNode. isProcessChildren = false; break; case NodeDifference.PARTITION_TYPE_CHANGE: case NodeDifference.EXCLUDED_UNIT_CHANGE: ops.Add(CreateRemoveOperation(originalNode)); ops.AddRange(CreateAddOperations(newNode, idGenerator)); // No need to further process children. The ADD operations above will include operations // for all children of newNode. isProcessChildren = false; break; case NodeDifference.BID_CHANGE: // Ensure that the new node has the proper ID (this may have been lost if the node // was removed and then re-added). newNode.ProductPartitionId = originalNode.ProductPartitionId; ops.Add(CreateSetBidOperation(newNode)); // Process the children of newNode. The SET operation above will only handle changes // made to newNode, not its children. isProcessChildren = true; break; case NodeDifference.NONE: // Ensure that the new node has the proper ID (this may have been lost if the node // was removed and then re-added). newNode.ProductPartitionId = originalNode.ProductPartitionId; // This node does not have changes, but its children may. isProcessChildren = true; break; default: throw new InvalidOperationException("Unrecognized difference: " + nodeDifference); } if (isProcessChildren) { // Try to match the children in new and original trees to identify the // matching dimensions. foreach (ProductPartitionNode newChild in newNode.Children) { if (originalNode.HasChild(newChild.Dimension)) { // this is probably an edit. AddMutateOperations(originalNode.GetChild(newChild.Dimension), newChild, ops, idGenerator); } else { // this is a new node. AddMutateOperations(null, newChild, ops, idGenerator); } } foreach (ProductPartitionNode originalChild in originalNode.Children) { if (newNode.HasChild(originalChild.Dimension)) { // this is probably an edit. We dealt with it before continue; } else { // this is a removed node. AddMutateOperations(originalChild, null, ops, idGenerator); } } } }
public void TestChildNodeBasicFunctionality() { rootNode = rootNode.AsSubdivision(); Assert.False(rootNode.IsUnit, "Parent should not be a unit."); Assert.True(rootNode.IsSubdivision, "Parent should be a subdivision."); ProductBrand childDimension = ProductDimensions.CreateBrand("google"); ProductPartitionNode childNode = rootNode.AddChild(childDimension); Assert.AreSame(childDimension, childNode.Dimension, "Child node merely wraps the " + "underlying dimension node."); Assert.AreSame(rootNode, childNode.Parent, "child.GetParent should return parentNode."); Assert.That(childNode.ProductPartitionId == 0, "Partition ID is incorrect."); Assert.That(childNode.Children.Count() == 0, "ChildNode should not have any children."); Assert.True(childNode.IsUnit, "New node should be a unit node by default."); Assert.True(childNode.IsBiddableUnit, "New node should be a biddable unit node by default."); Assert.That(rootNode.HasChild(childDimension), "rootNode.HasChild should return true when " + "passed the dimension of the added child"); Assert.False(rootNode.HasChild(ProductDimensions.CreateBrand("xyz")), "rootNode.HasChild " + "should return false when passed a dimension for a nonexistent child"); Assert.False(rootNode.HasChild(null), "rootNode.HasChild should return false when passed " + "a dimension for a nonexistent child"); }