public void BothModifiedExampleFormTextWorksWithConflict() { const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='test' guid='F169EB3D-16F2-4eb0-91AA-FDB91636F8F6'> <sense id='123'> <example> <form lang='chorus'> <text>This is my example sentence.</text> </form> </example> </sense> </entry> </lift>"; var ours = ancestor.Replace(@"This is my example", @"This was your example"); var theirs = ancestor.Replace(@"This is my example", @"It's mine don't touch it."); using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); Assert.AreEqual(1, listener.Conflicts.Count); var warning = listener.Conflicts[0]; Assert.AreEqual(typeof(XmlTextBothEditedTextConflict), warning.GetType(), warning.ToString()); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "//example/form"); } }
public void BothAddedHeaderButWithDifferentContentInEach() { const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='parent' guid='c1ed1fa3-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='a'> <text>form parent</text> </form> </lexical-unit> </entry> </lift>"; var alpha = ancestor.Replace("<entry id", "<header><description>alphastuff</description></header><entry id"); var beta = ancestor.Replace("<entry id", "<header><ranges>betastuff</ranges></header><entry id"); using (var oursTemp = new TempFile(alpha)) using (var theirsTemp = new TempFile(beta)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); Assert.IsTrue(result.Contains("<header>")); Assert.IsTrue(result.Contains("<description>")); Assert.IsTrue(result.Contains("<ranges>")); listener.AssertExpectedChangesCount(2); } }
public void OneAddedOneTranslationOtherEditedFormText() { const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='test' guid='F169EB3D-16F2-4eb0-91AA-FDB91636F8F6'> <sense id='123'> <example> <form lang='chorus'> <text>This is my example sentence.</text> </form> </example> </sense> </entry> </lift>"; var ours = ancestor.Replace(@"This is my example", @"This was your example"); var theirs = ancestor.Replace(@"</example>", @"<form lang='en'><text>hello new entry</text></form></example>"); using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "//example"); AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath("//example/form", 2); } }
public void Conflict_TheirsAppearsInCollisionNote() { const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='lexicalformcollission' guid='c1ed1fa7-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='x'> <text>ours</text> </form> </lexical-unit> </entry> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='lexicalformcollission' guid='c1ed1fa7-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='x'> <text>theirs</text> </form> </lexical-unit> </entry> </lift>"; const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='lexicalformcollission' guid='c1ed1fa7-e382-11de-8a39-0800200c9a66' /> </lift>"; using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new PoorMansMergeStrategy(), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='lexicalformcollission']"); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry");//just one XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry/field[@type='mergeConflict']/trait[@name = 'looserData']"); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry/field[@type='mergeConflict' and @dateCreated]"); } }
public void BothAddedMainItemButWithDifferentContentHasOneConflictReport() { const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='noChangesInEither' guid='c1ed1f9d-e382-11de-8a39-0800200c9a66' /> </lift>"; const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='noChangesInEither' guid='c1ed1f9d-e382-11de-8a39-0800200c9a66' /> <entry id='addedByBoth' guid='c1ed1f9e-e382-11de-8a39-0800200c9a66' > <sense id='somesense'> <gloss lang='a'> <text>editedByUs</text> </gloss> </sense> </entry> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='noChangesInEither' guid='c1ed1f9d-e382-11de-8a39-0800200c9a66' /> <entry id='addedByBoth' guid='c1ed1f9e-e382-11de-8a39-0800200c9a66' > <sense id='somesense'> <gloss lang='a'> <text>editedByThem</text> </gloss> </sense> </entry> </lift>"; // We win merge situation. MergeSituation mergeSit = new NullMergeSituation(); DoMergeWithLiftEntryMergingStrategy(ancestor, ours, theirs, mergeSit, new[] { "lift/entry[@id='addedByBoth']/sense/gloss/text[text()='editedByUs']" }, new[] { "lift/entry[@id='addedByBoth']/sense/gloss/text[text()='editedByThem']" }, 1, new List<Type> { typeof(XmlTextBothAddedTextConflict) }, 4, new List<Type> { typeof(XmlAttributeBothAddedReport), typeof(XmlAttributeBothAddedReport), typeof(XmlAttributeBothAddedReport), typeof(XmlAttributeBothAddedReport) }); // They win merge situation. mergeSit = new NullMergeSituationTheyWin(); DoMergeWithLiftEntryMergingStrategy(ancestor, ours, theirs, mergeSit, new[] { "lift/entry[@id='addedByBoth']/sense/gloss/text[text()='editedByThem']" }, new[] { "lift/entry[@id='addedByBoth']/sense/gloss/text[text()='editedByUs']" }, 1, new List<Type> { typeof(XmlTextBothAddedTextConflict) }, 4, new List<Type> { typeof(XmlAttributeBothAddedReport), typeof(XmlAttributeBothAddedReport), typeof(XmlAttributeBothAddedReport), typeof(XmlAttributeBothAddedReport) }); }
public void RangeSectionMergedCorrectly() { using (var oursTemp = new TempFile(_ours)) using (var theirsTemp = new TempFile(_theirs)) using (var ancestorTemp = new TempFile(_ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='usOnly']"); AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(@"lift/header/ranges/range", 4); } }
public void OneEditedExampleWhileOtherAddedTranslation_MergesButRaiseWarning() { const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='test' guid='F169EB3D-16F2-4eb0-91AA-FDB91636F8F6'> <sense id='123'> <example> <form lang='chorus'> <text>This is my example sentence.</text> </form> </example> </sense> </entry> </lift>"; var ours = ancestor.Replace("This is my", "This is our"); var theirs = ancestor.Replace("</example>","<translation><form lang='en'><text>hello</text></form></translation></example>"); using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); Assert.AreEqual(1, listener.Conflicts.Count); var warning = listener.Warnings[0]; Assert.AreEqual(typeof(BothEditedDifferentPartsOfDependentPiecesOfDataWarning), warning.GetType(), warning.ToString()); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "//example"); } }
private void TestBodyMerge(string ancestorBody, string ourBody, string theirBody, Action<string> testsOnResultingFile, Action<ListenerForUnitTests> testsOnEventListener ) { string ancestor = @"<?xml version='1.0' encoding='utf-8'?><html><body>"+ancestorBody+"</body></html>"; string theirs = @"<?xml version='1.0' encoding='utf-8'?><html><body>" + theirBody + "</body></html>"; string ours = @"<?xml version='1.0' encoding='utf-8'?><html><body>" + ourBody + "</body></html>"; using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; new Bloom_ChorusPlugin.BloomHtmlFileTypeHandler().Do3WayMerge(mergeOrder); testsOnResultingFile(mergeOrder.pathToOurs); testsOnEventListener(listener); } }
private MergeResult DoMerge(string commonAncestor, string ourContent, string theirContent) { var result = new MergeResult(); using (var ours = new TempFile(ourContent)) using (var theirs = new TempFile(theirContent)) using (var ancestor = new TempFile(commonAncestor)) { var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(ours.Path, ancestor.Path, theirs.Path, situation); result.listener = new ListenerForUnitTests(); mergeOrder.EventListener = result.listener; new BloomHtmlFileTypeHandler().Do3WayMerge(mergeOrder); result.resultString = File.ReadAllText(ours.Path); } return result; }
public void NewEntryFromUs_HasNoChangeReports() { const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='commonOldie' guid='c1ecf897-e382-11de-8a39-0800200c9a66' /> </lift>"; const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='ourNew' guid='c1ecf898-e382-11de-8a39-0800200c9a66' /> <entry id='commonOldie' guid='c1ecf897-e382-11de-8a39-0800200c9a66' /> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='commonOldie' guid='c1ecf897-e382-11de-8a39-0800200c9a66' /> </lift>"; using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new DropTheirsMergeStrategy(), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='ourNew']"); listener.AssertExpectedConflictCount(0); listener.AssertExpectedChangesCount(0); } }
public void NewStyle_DoomedByUsEditedByThem_HasOneConflict() { // New Style means the deleted entry was really removed from the file, not just marked as deleted. const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='noChangesInEither' guid='c1ed1f9b-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='a'> <text>form a</text> </form> </lexical-unit> </entry> <entry id='doomedByUsEditedByThem' guid='c1ed1f9c-e382-11de-8a39-0800200c9a66' > <sense> <gloss lang='a'> <text>original</text> </gloss> </sense> </entry> </lift>"; const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='noChangesInEither' guid='c1ed1f9b-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='a'> <text>form a</text> </form> </lexical-unit> </entry> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='noChangesInEither' guid='c1ed1f9b-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='a'> <text>form a</text> </form> </lexical-unit> </entry> <entry id='doomedByUsEditedByThem' guid='c1ed1f9c-e382-11de-8a39-0800200c9a66' > <sense> <gloss lang='a'> <text>newByThem</text> </gloss> </sense> </entry> </lift>"; var listener = new ListenerForUnitTests(); using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new DropTheirsMergeStrategy(), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); Assert.IsTrue(result.ToLower().Contains("utf-8")); } listener.AssertExpectedChangesCount(0); listener.AssertExpectedConflictCount(1); listener.AssertFirstConflictType<RemovedVsEditedElementConflict>(); }
public void OneAddedOneTranslationWhileOtherAddedAnother_Merged() { const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='test' guid='F169EB3D-16F2-4eb0-91AA-FDB91636F8F6'> <sense id='123'> <example> <form lang='chorus'> <text>This is my example sentence.</text> </form> </example> </sense> </entry> </lift>"; var ours = ancestor.Replace("</example>", "<translation><form lang='tp'><text>Dispela em i sentens bilong mi.</text></form></translation></example>"); var theirs = ancestor.Replace("</example>", "<translation><form lang='en'><text>hello</text></form></translation></example>"); using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "//example"); } }
public void UnchangedEntryInBoth_NotDuplicated() { const string all = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='sameInBoth' guid='c1ed1f92-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='a'> <text>form a</text> </form> </lexical-unit> </entry> </lift>"; using (var oursTemp = new TempFile(all)) using (var theirsTemp = new TempFile(all)) using (var ancestorTemp = new TempFile(all)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new DropTheirsMergeStrategy(), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='sameInBoth']"); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry/lexical-unit"); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry/lexical-unit/form/text"); } }
public void Merge_AncestorAndOursSame_ResultHasTheirsAlso() { const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry dateCreated='2011-03-09T17:08:44Z' dateModified='2012-05-18T08:31:54Z' id='00853b73-fda2-4b12-8a89-6957cc7e7e79' guid='00853b73-fda2-4b12-8a89-6957cc7e7e79'> <lexical-unit> <form lang='ldb-fonipa-x-emic'> <text>asatɛn</text> </form> </lexical-unit> </entry> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='00853b73-fda2-4b12-8a89-6957cc7e7e79' dateCreated='2011-03-09T05:08:44Z' dateModified='2012-05-14T02:38:00Z' guid='00853b73-fda2-4b12-8a89-6957cc7e7e79'> <lexical-unit> <form lang='ldb-fonipa-x-emic'> <text>asatɛn</text> </form> <form lang='ldb-Zxxx-x-audio'> <text>asatɛn-63472603074018.wav</text> </form> </lexical-unit> </entry> </lift>"; const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry dateCreated='2011-03-09T17:08:44Z' dateModified='2011-04-08T16:53:45Z' id='00853b73-fda2-4b12-8a89-6957cc7e7e79' guid='00853b73-fda2-4b12-8a89-6957cc7e7e79'> <lexical-unit> <form lang='ldb-fonipa-x-emic'> <text>asatɛn</text> </form> </lexical-unit> </entry> </lift>"; using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); //this doesn't seem particular relevant, but senses are, in fact, ordered, so there is some ambiguity here var result = File.ReadAllText(mergeOrder.pathToOurs); //Assert.AreEqual(typeof(AmbiguousInsertConflict), listener.Conflicts[0].GetType()); // Check that the audio made it into the merge. XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry/lexical-unit/form[@lang='ldb-fonipa-x-emic']"); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry/lexical-unit/form[@lang='ldb-Zxxx-x-audio']"); } }
public void Merge_MultiTextInFormInEntry_ResultHasWarningReport() { const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='00853b73-fda2-4b12-8a89-6957cc7e7e79' guid='00853b73-fda2-4b12-8a89-6957cc7e7e79'> <lexical-unit> <form lang='en'> <text>common form</text> <text>our extra text</text> </form> </lexical-unit> </entry> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='00853b73-fda2-4b12-8a89-6957cc7e7e79' guid='00853b73-fda2-4b12-8a89-6957cc7e7e79'> <lexical-unit> <form lang='en'> <text>common form</text> <text>their extra text</text> </form> </lexical-unit> </entry> </lift>"; const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='00853b73-fda2-4b12-8a89-6957cc7e7e79' guid='00853b73-fda2-4b12-8a89-6957cc7e7e79'> <lexical-unit> <form lang='en'> <text>common form</text> </form> </lexical-unit> </entry> </lift>"; using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); // Check that there is only one entry in the merged file. XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry/lexical-unit/form/text"); XmlTestHelper.AssertXPathIsNull(result, "lift/entry/lexical-unit/form/text[text()='extra text']"); Assert.AreEqual(2, listener.Warnings.Count); Assert.AreEqual(typeof(MergeWarning), listener.Warnings[0].GetType()); Assert.AreEqual(typeof(MergeWarning), listener.Warnings[1].GetType()); } }
public void Empty_Ancestor_Adds_Children_From_Both() { const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='usOnly' guid='c1ed1f95-e382-11de-8a39-0800200c9a66' /> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='themOnly' guid='c1ed1f96-e382-11de-8a39-0800200c9a66' /> </lift>"; const string ancestor = @"<lift version='0.12'></lift>"; using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new PoorMansMergeStrategy(), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); // REVIEW JohnT(RandyR): Should new entries from 'loser' register an addition change? XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift[entry/@id='usOnly']"); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift[entry/@id='themOnly']"); listener.AssertExpectedChangesCount(0); listener.AssertExpectedConflictCount(0); } }
public void EntryRemovedByUs_Removed() { using (var oursTemp = new TempFile(_ours)) using (var theirsTemp = new TempFile(_theirs)) using (var ancestorTemp = new TempFile(_ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new PoorMansMergeStrategy(), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift[not(entry/@id='doomedByUs')]"); } }
public void DuplicateGuids_StillMergesWhatComesNext() { const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.13' producer='WeSay 1.0.0.0'> <entry id='everybody' guid='dded1f95-e382-11de-8a39-0800200c9add'/> <entry id='newGuy' guid='aaed1f95-e382-11de-8a39-0800200c9a66' /> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.13' producer='WeSay 1.0.0.0'> <entry id='everybody' guid='dded1f95-e382-11de-8a39-0800200c9add'/> <entry id='duplicate' guid='c1ed1f95-e382-11de-8a39-0800200c9a66' /> <entry id='duplicate' guid='c1ed1f95-e382-11de-8a39-0800200c9a66' /> <!-- everthing above this line was being merged, but not this --> <entry id='lostBoy' guid='bbed1f95-e382-11de-8a39-0800200c9a66' /> </lift>"; const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.13' producer='WeSay 1.0.0.0'> <entry id='everybody' guid='dded1f95-e382-11de-8a39-0800200c9add'/> </lift>"; using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new PoorMansMergeStrategy(), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "//entry[@id='newGuy']"); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "//entry[@id='lostBoy']"); Assert.AreEqual(1, listener.Warnings.Count); Assert.AreEqual(typeof(MergeWarning), listener.Warnings[0].GetType()); } }
public void OnlyModificationDateChanged_NoConflictOrRecordedChange() { const string template = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='blah' guid='c1ed1f93-e382-11de-8a39-0800200c9a66' dateModified='theDate'/> </lift>"; using (var oursTemp = new TempFile(template.Replace("theDate", "2009-07-08T01:47:02Z"))) using (var theirsTemp = new TempFile(template.Replace("theDate", "2009-07-09T01:47:03Z"))) using (var ancestorTemp = new TempFile(template.Replace("theDate", "2009-07-09T01:47:04Z"))) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); Assert.AreEqual(0, listener.Conflicts.Count); Assert.AreEqual(0, listener.Changes.Count); } }
public void DoomedByUs_OldWay_AndByThem_NewWay_HasNoChangeReports() { const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='noChangesInEither' guid='c1ed1fa1-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='a'> <text>form a</text> </form> </lexical-unit> </entry> <entry id='doomedByBoth' guid='c1ed1fa2-e382-11de-8a39-0800200c9a66' > <sense> <gloss lang='a'> <text>original</text> </gloss> </sense> </entry> </lift>"; // 'ours' does the older dateDeleted marking. const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='noChangesInEither' guid='c1ed1fa1-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='a'> <text>form a</text> </form> </lexical-unit> </entry> <entry id='doomedByBoth' guid='c1ed1fa2-e382-11de-8a39-0800200c9a66' dateDeleted='2011-03-15T12:15:05Z' /> </lift>"; // 'theirs' does the newer removal. const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='noChangesInEither' guid='c1ed1fa1-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='a'> <text>form a</text> </form> </lexical-unit> </entry> </lift>"; var listener = new ListenerForUnitTests(); using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new DropTheirsMergeStrategy(), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); Assert.IsTrue(result.ToLower().Contains("utf-8")); } listener.AssertExpectedConflictCount(0); listener.AssertExpectedChangesCount(0); }
public void WeEditedMainItemSenseGlossTheyDidNothingHasNoReports() { // New Style means the deleted entry was really removed from the file, not just marked as deleted. const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='noChangesInEither' guid='c1ed1f9d-e382-11de-8a39-0800200c9a66' /> <entry id='oneEdited' guid='c1ed1f9e-e382-11de-8a39-0800200c9a66' > <sense> <gloss lang='a'> <text>original</text> </gloss> </sense> </entry> </lift>"; const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='noChangesInEither' guid='c1ed1f9d-e382-11de-8a39-0800200c9a66' /> <entry id='oneEdited' guid='c1ed1f9e-e382-11de-8a39-0800200c9a66' > <sense> <gloss lang='a'> <text>ourNewGloss</text> </gloss> </sense> </entry> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='noChangesInEither' guid='c1ed1f9d-e382-11de-8a39-0800200c9a66' /> <entry id='oneEdited' guid='c1ed1f9e-e382-11de-8a39-0800200c9a66' > <sense> <gloss lang='a'> <text>original</text> </gloss> </sense> </entry> </lift>"; // We win merge situation. MergeSituation mergeSit = new NullMergeSituation(); DoMergeWithLiftEntryMergingStrategy(ancestor, ours, theirs, mergeSit, new[] { "lift/entry[@id='oneEdited']/sense/gloss/text[text()='ourNewGloss']" }, new[] { "lift/entry[@id='oneEdited']/sense/gloss/text[text()='original']" }, 0, null, 0, null); // They win merge situation. mergeSit = new NullMergeSituationTheyWin(); DoMergeWithLiftEntryMergingStrategy(ancestor, ours, theirs, mergeSit, new[] { "lift/entry[@id='oneEdited']/sense/gloss/text[text()='ourNewGloss']" }, new[] { "lift/entry[@id='oneEdited']/sense/gloss/text[text()='original']" }, 0, null, 0, null); }
public void NewWSAddedToNote_Merged() { const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.13' producer='WeSay 1.0.0.0'> <entry id='everybody' guid='dded1f95-e382-11de-8a39-0800200c9add'> <note><form lang='es'>hola</form></note> </entry> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.13' producer='WeSay 1.0.0.0'> <entry id='everybody' guid='dded1f95-e382-11de-8a39-0800200c9add'> <note> <form lang='en'>hello</form> </note> <note><form lang='es'>hola</form></note> </entry> </lift>"; const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.13' producer='WeSay 1.0.0.0'> <entry id='everybody' guid='dded1f95-e382-11de-8a39-0800200c9add'> <note><form lang='es'>hola</form></note> </entry> </lift>"; using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new PoorMansMergeStrategy(), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "//note/form[@lang='es']"); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "//note/form[@lang='en']"); } }
public void TheyEditedOptionalFirstElementHasNoReports() { const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <header id='originalHeader'/> <entry id='noChangesInEither' guid='c1ed1f9d-e382-11de-8a39-0800200c9a66' /> </lift>"; const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <header id='originalHeader'/> <entry id='noChangesInEither' guid='c1ed1f9d-e382-11de-8a39-0800200c9a66' /> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <header id='theirNewHeader'/> <entry id='noChangesInEither' guid='c1ed1f9d-e382-11de-8a39-0800200c9a66' /> </lift>"; // We win merge situation. MergeSituation mergeSit = new NullMergeSituation(); DoMergeWithLiftEntryMergingStrategy(ancestor, ours, theirs, mergeSit, new[] { "lift/header[@id='theirNewHeader']", "lift/entry[@id='noChangesInEither']" }, null, 0, null, 0, null); // They win merge situation. mergeSit = new NullMergeSituationTheyWin(); DoMergeWithLiftEntryMergingStrategy(ancestor, ours, theirs, mergeSit, new[] { "lift/header[@id='theirNewHeader']", "lift/entry[@id='noChangesInEither']" }, null, 0, null, 0, null); }
public void NewEntryFromUs_Conveyed() { using (var oursTemp = new TempFile(_ours)) using (var theirsTemp = new TempFile(_theirs)) using (var ancestorTemp = new TempFile(_ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new DropTheirsMergeStrategy(), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='usOnly']"); } }
public void GetMergedLift_LiftIsUnchanged_IndentingIsCorrect() { const string alpha = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='alpha' guid='c1ed1fa6-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='a'> <text>form alpha</text> </form> </lexical-unit> </entry> </lift>"; const string beta = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='alpha' guid='c1ed1fa6-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='a'> <text>form alpha</text> </form> </lexical-unit> </entry> </lift>"; const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='alpha' guid='c1ed1fa6-e382-11de-8a39-0800200c9a66' > <lexical-unit> <form lang='a'> <text>form alpha</text> </form> </lexical-unit> </entry> </lift>"; string expectedResult = ("<?xml version='1.0' encoding='utf-8'?>\r\n" + "<lift\r\n" + "\tproducer='WeSay 1.0.0.0'\r\n" + "\tversion='0.10'>\r\n" + "\t<entry\r\n" + "\t\tid='alpha'\r\n" + "\t\tguid='c1ed1fa6-e382-11de-8a39-0800200c9a66'>\r\n" + "\t\t<lexical-unit>\r\n" + "\t\t\t<form\r\n" + "\t\t\t\tlang='a'>\r\n" + "\t\t\t\t<text>form alpha</text>\r\n" + "\t\t\t</form>\r\n" + "\t\t</lexical-unit>\r\n" + "\t</entry>\r\n" + "</lift>").Replace('\'','\"'); using (var oursTemp = new TempFile(alpha)) using (var theirsTemp = new TempFile(beta)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); Console.WriteLine(result); Assert.AreEqual(expectedResult, result); } }
public void ResultIsUtf8() { using (var oursTemp = new TempFile(_ours)) using (var theirsTemp = new TempFile(_theirs)) using (var ancestorTemp = new TempFile(_ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new DropTheirsMergeStrategy(), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); Assert.IsTrue(result.ToLower().Contains("utf-8")); } }
public void Merge_EditAndDeleteEntry_GeneratesConflictWithContext() { const string pattern = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry dateCreated='2011-03-09T17:08:44Z' dateModified='2012-05-18T08:31:54Z' id='00853b73-fda2-4b12-8a89-6957cc7e7e79' guid='00853b73-fda2-4b12-8a89-6957cc7e7e79'> <lexical-unit> <form lang='ldb-fonipa-x-emic'> <text>{0}</text> </form> </lexical-unit> </entry> </lift>"; // We edited the text of the form slightly. string ours = string.Format(pattern, "asaten"); string ancestor = string.Format(pattern, "asat"); // they deleted the whole entry const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> </lift>"; using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; var mergeStrategy = new LiftEntryMergingStrategy(mergeOrder); var strategies = mergeStrategy.GetStrategies(); var entryStrategy = strategies.ElementStrategies["entry"]; entryStrategy.ContextDescriptorGenerator = new EnhancedEntrycontextGenerator(); XmlMergeService.Do3WayMerge(mergeOrder, mergeStrategy, false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); var conflict = listener.Conflicts[0]; Assert.That(conflict, Is.InstanceOf<EditedVsRemovedElementConflict>()); Assert.That(conflict.HtmlDetails, Is.StringContaining("my silly context"), "merger should have used the context generator to make the html details"); Assert.That(conflict.HtmlDetails.IndexOf("my silly context"), Is.EqualTo(conflict.HtmlDetails.LastIndexOf("my silly context")), "since one change is a delete, the details should only be present once"); var context = conflict.Context; Assert.That(context, Is.Not.Null, "the merge should supply a context for the conflict"); Assert.That(context.PathToUserUnderstandableElement, Is.Not.Null); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry/lexical-unit/form[@lang='ldb-fonipa-x-emic']/text[text()='asaten']"); } }
public void BothEditedFoo_WithEditVsDeleteOfBar_AndNoChangesToDull_ProducesTwoConflictRreports() { const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.13' producer='WeSay 1.0.0.0'> <entry id='dull' guid='C1EDBBDE-E382-11DE-8A39-0800200C9A66'> <lexical-unit> <form lang='en'> <text>dull</text> </form> </lexical-unit> </entry> <entry id='foo' guid='C1EDBBDF-E382-11DE-8A39-0800200C9A66'> <lexical-unit> <form lang='en'> <text>foo</text> </form> </lexical-unit> </entry> <entry id='bar' guid='C1EDBBE0-E382-11DE-8A39-0800200C9A66'> <lexical-unit> <form lang='en'> <text>bar</text> </form> </lexical-unit> </entry> </lift>"; const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.13' producer='WeSay 1.0.0.0'> <entry id='dull' guid='C1EDBBDE-E382-11DE-8A39-0800200C9A66'> <lexical-unit> <form lang='en'> <text>dull</text> </form> </lexical-unit> </entry> <entry id='foo' guid='C1EDBBDF-E382-11DE-8A39-0800200C9A66'> <lexical-unit> <form lang='en'> <text>ourfoo</text> </form> </lexical-unit> </entry> <entry id='bar' guid='C1EDBBE0-E382-11DE-8A39-0800200C9A66'> <lexical-unit> <form lang='en'> <text>mybar</text> </form> </lexical-unit> </entry> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.13' producer='WeSay 1.0.0.0'> <entry id='dull' guid='C1EDBBDE-E382-11DE-8A39-0800200C9A66'> <lexical-unit> <form lang='en'> <text>dull</text> </form> </lexical-unit> </entry> <entry id='foo' guid='C1EDBBDF-E382-11DE-8A39-0800200C9A66'> <lexical-unit> <form lang='en'> <text>theirfoo</text> </form> </lexical-unit> </entry> </lift>"; // This tests: http://jira.palaso.org/issues/browse/CHR-13 // In a test where all I did was an edited vs. delete test, the resulting conflict note listed the element as "unknown". // In a test where all I both a) had both parties edit the same field on record A and b) had parties edit vs. delete record B, the all resulting conflict notes were attached to A. using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { // 'We' (O) are set to win. // Both edited foo: O should win. // O edited bar, T deleted it. O should win. var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation { AlphaUserId = "O", BetaUserId = "T" }; var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='dull']"); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='foo']/lexical-unit/form/text[text()='ourfoo']"); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='bar']"); Assert.AreEqual(2, listener.Conflicts.Count); var firstConflict = listener.Conflicts[0]; var secondConflict = listener.Conflicts[1]; Assert.AreEqual(typeof(XmlTextBothEditedTextConflict), firstConflict.GetType()); Assert.AreEqual(typeof(EditedVsRemovedElementConflict), secondConflict.GetType()); // Doesn't work with ListenerForUnitTests, as ListenerForUnitTests doesn't set the Context on the conflict, as does the Chorus notes listener. //var annotationXml = XmlTestHelper.WriteConflictAnnotation(firstConflict); //var annotationXml = XmlTestHelper.WriteConflictAnnotation(secondConflict); } using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { // 'They' (T) are set to win. // Both edited foo: 'T' should win // O edited bar, T deleted it. O should win. var listener = new ListenerForUnitTests(); var situation = new NullMergeSituationTheyWin { AlphaUserId = "O", BetaUserId = "T" }; var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); var result = File.ReadAllText(mergeOrder.pathToOurs); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='dull']"); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='foo']/lexical-unit/form/text[text()='theirfoo']"); XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='bar']"); Assert.AreEqual(2, listener.Conflicts.Count); var firstConflict = listener.Conflicts[0]; var secondConflict = listener.Conflicts[1]; Assert.AreEqual(typeof(XmlTextBothEditedTextConflict), firstConflict.GetType()); Assert.AreEqual(typeof(RemovedVsEditedElementConflict), secondConflict.GetType()); // Doesn't work with ListenerForUnitTests, as ListenerForUnitTests doesn't set the Context on the conflict, as does the Chorus notes listener. //var annotationXml = XmlTestHelper.WriteConflictAnnotation(firstConflict); //var annotationXml = XmlTestHelper.WriteConflictAnnotation(secondConflict); } }
public void Merge_TheirDuplicateRelationDoesNotResultInEmptyRelationElement() { const string ours = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='Whoever'> <entry dateCreated='2012-04-16T07:27:11Z' dateModified='2012-08-12T09:46:54Z' id='आप्चो_27fcb6ac-b509-4463-aa12-36427ac9b427' guid='27fcb6ac-b509-4463-aa12-36427ac9b427'> <lexical-unit> <form lang='bhj'> <text>आप्चो</text> </form> </lexical-unit> <relation type='Compare' ref='आम्मे_1cc3b8eb-cc46-4ee9-9a53-9195a30cb6b4' /> <sense id='d4c1b46b-554a-4fc6-846b-b136b118817b' order='1'> <definition> <form lang='en'> <text>shoot</text> </form> <form lang='ne'> <text>हिर्काउ</text> </form> </definition> </sense> </entry> </lift>"; const string theirs = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='Whoever'> <entry dateCreated='2012-04-16T07:27:11Z' dateModified='2012-06-21T01:37:26Z' id='आप्चो_27fcb6ac-b509-4463-aa12-36427ac9b427' guid='27fcb6ac-b509-4463-aa12-36427ac9b427'> <lexical-unit> <form lang='bhj'> <text>आप्चो</text> </form> </lexical-unit> <relation type='Compare' ref='आम्मे_1cc3b8eb-cc46-4ee9-9a53-9195a30cb6b4' /> <relation type='Compare' ref='आम्मे_1cc3b8eb-cc46-4ee9-9a53-9195a30cb6b4' /> <sense id='d4c1b46b-554a-4fc6-846b-b136b118817b' order='1'> <definition> <form lang='en'> <text>shoot</text> </form> <form lang='ne'> <text>हीर्काउँ</text> </form> </definition> </sense> </entry> </lift>"; const string ancestor = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='Whoever'> <entry dateCreated='2012-04-16T07:27:11Z' dateModified='2012-06-21T01:37:26Z' id='आप्चो_27fcb6ac-b509-4463-aa12-36427ac9b427' guid='27fcb6ac-b509-4463-aa12-36427ac9b427'> <lexical-unit> <form lang='bhj'> <text>आप्चो</text> </form> </lexical-unit> <relation type='Compare' ref='आम्मे_1cc3b8eb-cc46-4ee9-9a53-9195a30cb6b4' /> <sense id='d4c1b46b-554a-4fc6-846b-b136b118817b' order='1'> <definition> <form lang='en'> <text>shoot</text> </form> <form lang='ne'> <text>हीर्काउँ</text> </form> </definition> </sense> </entry> </lift>"; using (var oursTemp = new TempFile(ours)) using (var theirsTemp = new TempFile(theirs)) using (var ancestorTemp = new TempFile(ancestor)) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); //this doesn't seem particular relevant, but senses are, in fact, ordered, so there is some ambiguity here var result = File.ReadAllText(mergeOrder.pathToOurs); //Assert.AreEqual(typeof(AmbiguousInsertConflict), listener.Conflicts[0].GetType()); // Check that the audio made it into the merge. XmlTestHelper.AssertXPathIsNull(result, "//relation[not(@type)]"); } }
public void Merge_RealConflictPlusModDateConflict_ModDateNotReportedAsConflict() { const string template = @"<?xml version='1.0' encoding='utf-8'?> <lift version='0.10' producer='WeSay 1.0.0.0'> <entry id='blah' guid='c1ed1f94-e382-11de-8a39-0800200c9a66' dateModified='theDate'> <lexical-unit> <form lang='a'> <text>theForm</text> </form> </lexical-unit> </entry> </lift>"; // NB: dateModified is set to ignore for LiftEntryMergingStrategy, thus no conflict report. using (var oursTemp = new TempFile(template.Replace("theDate", "2009-07-08T01:47:06Z").Replace("theForm", "1"))) using (var theirsTemp = new TempFile(template.Replace("theDate", "2009-07-09T01:47:05Z").Replace("theForm", "2"))) using (var ancestorTemp = new TempFile(template.Replace("theDate", "2009-07-09T01:47:04Z").Replace("theForm", "3"))) { var listener = new ListenerForUnitTests(); var situation = new NullMergeSituation(); var mergeOrder = new MergeOrder(oursTemp.Path, ancestorTemp.Path, theirsTemp.Path, situation) { EventListener = listener }; XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), false, "header", "entry", "guid"); listener.AssertExpectedConflictCount(1); listener.AssertFirstConflictType<XmlTextBothEditedTextConflict>(); listener.AssertExpectedChangesCount(0); } }