diff --git a/FatAntelope.Tests/XdtDiffWriterTests.cs b/FatAntelope.Tests/XdtDiffWriterTests.cs index 8242e16..c46e506 100644 --- a/FatAntelope.Tests/XdtDiffWriterTests.cs +++ b/FatAntelope.Tests/XdtDiffWriterTests.cs @@ -12,21 +12,76 @@ namespace FatAntelope.Tests public class XdtWriterTests { [TestMethod] - public void SetAttribute() + public void NoLocatorAndSetAttributes() { - var doc1 = @" + var source = @" - child1 - child2 + child1 + child2 "; - var doc2 = @" + var target = @" - child1 - child2 + child1 + child2 "; - AssertCanTransform(doc1, doc2); + var patch = GetPatch(source, target); + + // Locator = none + AssertNoLocator(patch.SelectSingleNode("/root/child1")); + + // Transform = SetAttributes + AssertTransform(patch.SelectSingleNode("/root/child1"), "SetAttributes(type,name)"); + + AssertCanTransform(source, target); + } + + [TestMethod] + public void MatchAndSetAttribute() + { + var source = @" + + child1 + child2 + "; + + var target = @" + + child1 + child2 + "; + + var patch = GetPatch(source, target); + + // Locator = Match(type) + AssertLocator(patch.SelectSingleNode("/root/child"), "Match(type)"); + + // Transform = SetAttribute(type) + AssertTransform(patch.SelectSingleNode("/root/child"), "SetAttributes(name)"); + + AssertCanTransform(source, target); + } + + private void AssertTransform(XmlNode node, string expected) + { + Assert.IsNotNull(node); + var value = node.SelectSingleNode("@*[local-name() = 'Transform']").Value; + Assert.AreEqual(expected, value); + } + + private void AssertLocator(XmlNode node, string expected) + { + Assert.IsNotNull(node); + var value = node.SelectSingleNode("@*[local-name() = 'Locator']").Value; + Assert.AreEqual(expected, value); + } + + private void AssertNoLocator(XmlNode node) + { + Assert.IsNotNull(node); + var attribute = node.SelectSingleNode("@*[local-name() = 'Locator']"); + Assert.IsNull(attribute); } private void AssertCanTransform(string sourceXml, string targetXml) @@ -52,6 +107,23 @@ private void AssertCanTransform(string sourceXml, string targetXml) Assert.IsTrue(Enumerable.SequenceEqual(transformedTree.Root.Hash, tree2.Root.Hash)); } + private XmlDocument GetPatch(string sourceXml, string targetXml) + { + var doc1 = new XmlDocument(); + doc1.LoadXml(sourceXml); + + // reordered xml but same values + var doc2 = new XmlDocument(); + doc2.LoadXml(targetXml); + + var tree1 = new XTree(doc1); + var tree2 = new XTree(doc2); + XDiff.Diff(tree1, tree2); + + var writer = new XdtDiffWriter(); + return writer.GetDiff(tree2); + } + private XmlDocument Transform(XmlDocument sourceXml, XmlDocument patchXml) { var source = new XmlTransformableDocument(); diff --git a/FatAntelope/Writers/XdtDiffWriter.cs b/FatAntelope/Writers/XdtDiffWriter.cs index c2e623a..bc86412 100644 --- a/FatAntelope/Writers/XdtDiffWriter.cs +++ b/FatAntelope/Writers/XdtDiffWriter.cs @@ -386,6 +386,8 @@ private Trait GetUniqueTrait(XNode element) // Mulitple elements with the same name if (duplicates.Count > 1) { + XNode poorAttribute = null; + // try and find unique attribute foreach (var attribute in element.Attributes) { @@ -408,11 +410,16 @@ private Trait GetUniqueTrait(XNode element) } if (unique) - return new Trait() { Attribute = attribute, Index = index }; + { + if (attribute.Match != MatchType.Match) + poorAttribute = poorAttribute ?? attribute; + else + return new Trait() { Attribute = attribute, Index = index }; + } } // No unique attributes, so use index - return new Trait() { Index = index }; + return new Trait() { Attribute = poorAttribute, Index = index }; } }