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 Do3WayMerge(MergeOrder order) { XmlMergeService.Do3WayMerge(order, new ChorusNotesAnnotationMergingStrategy(order), false, null, "annotation", "guid"); }
public void FixtureSetup() { _mdc = MetadataCache.TestOnlyNewCache; var mergeOrder = new MergeOrder(null, null, null, new NullMergeSituation()) { EventListener = new ListenerForUnitTests() }; _merger = FieldWorksMergeServices.CreateXmlMergerForFieldWorksData(mergeOrder, _mdc); }
/// <summary> /// Produce a string that represents the 3-way merger of the given three elements. /// </summary> public ChorusNotesAnnotationMergingStrategy(MergeOrder order) { _annotationMerger = new XmlMerger(order.MergeSituation) { EventListener = order.EventListener }; SetupElementStrategies(); }
internal static XmlMerger CreateXmlMergerForFieldWorksData(MergeOrder mergeOrder, MetadataCache mdc) { var merger = new XmlMerger(mergeOrder.MergeSituation) { EventListener = mergeOrder.EventListener }; BootstrapSystem(mdc, merger); return merger; }
internal static void DoMerge(MergeOrder mergeOrder, XmlMerger merger) { XmlNode ours; XmlNode theirs; XmlNode common; DoPreMerge(mergeOrder, out ours, out theirs, out common); var results = merger.Merge(ours, theirs, common); DoPostMerge(mergeOrder.pathToOurs, results.MergedNode); }
public void Do3WayMerge(MetadataCache mdc, MergeOrder mergeOrder) { var merger = new XmlMerger(mergeOrder.MergeSituation) { EventListener = mergeOrder.EventListener }; CustomLayoutMergeStrategiesMethod.AddElementStrategies(merger.MergeStrategies); CustomLayoutMergeService.DoMerge(mergeOrder, merger); }
//this one is only for deserializing private MergeSituation(string relativePathToFile, MergeOrder.ConflictHandlingModeChoices conflictHandlingMode) { ConflictHandlingMode = conflictHandlingMode; if (relativePathToFile != null) relativePathToFile = relativePathToFile.Trim(new[] { Path.DirectorySeparatorChar }); PathToFileInRepository = relativePathToFile; }
internal static void DoMerge(MergeOrder mergeOrder, XmlMerger merger) { XmlNode ours; XmlNode theirs; XmlNode common; DoPreMerge(mergeOrder, out ours, out theirs, out common); // The document element is being returned here, so our parent isn't relevant and won't be used by the merge var results = merger.Merge(null, ours, theirs, common); DoPostMerge(mergeOrder.pathToOurs, results.MergedNode); }
/// <summary> /// Constructor /// </summary> public LiftRangesMergingStrategy(MergeOrder mergeOrder) { _merger = new XmlMerger(mergeOrder.MergeSituation) { EventListener = mergeOrder.EventListener }; LiftBasicElementStrategiesMethod.AddLiftBasicElementStrategies(_merger.MergeStrategies); LiftRangesElementStrategiesMethod.AddLiftRangeElementStrategies(_merger.MergeStrategies); }
/// <summary> /// Produce a string that represents the 3-way merger of the given three elements. /// </summary> public LiftEntryMergingStrategy(MergeOrder mergeOrder) { _entryMerger = new XmlMerger(mergeOrder.MergeSituation) { MergeStrategies = {ElementToMergeStrategyKeyMapper = new LiftElementToMergeStrategyKeyMapper()}, EventListener = mergeOrder.EventListener }; LiftElementStrategiesMethod.AddLiftElementStrategies(_entryMerger.MergeStrategies); }
public override void TestSetup() { base.TestSetup(); Mdc.UpgradeToVersion(MetadataCache.MaximumModelVersion); var mergeOrder = new MergeOrder(null, null, null, new NullMergeSituation()) { EventListener = new ListenerForUnitTests() }; _merger = FieldWorksMergeServices.CreateXmlMergerForFieldWorksData(mergeOrder, Mdc); }
/// <summary> /// All callers merging FieldWorks data need to pass 'true', so the MDC will know about any custom properties for their classes. /// /// Non-object callers (currently only the merge of the custom property definitions themselves) shoudl pass 'false'. /// </summary> internal static void Do3WayMerge(MergeOrder mergeOrder, MetadataCache mdc, bool addcustomPropertyInformation) { // Skip doing this for the Custom property definiton file, since it has no real need for the custom prop definitions, // which are being merged (when 'false' is provided). if (addcustomPropertyInformation) mdc.AddCustomPropInfo(mergeOrder); // NB: Must be done before FieldWorksCommonMergeStrategy is created. since it used the MDC. var merger = FieldWorksMergeServices.CreateXmlMergerForFieldWorksData(mergeOrder, mdc); merger.EventListener = mergeOrder.EventListener; var mergeResults = merger.MergeFiles(mergeOrder.pathToOurs, mergeOrder.pathToTheirs, mergeOrder.pathToCommonAncestor); // Write out merged data. FileWriterService.WriteNestedFile(mergeOrder.pathToOurs, mergeResults.MergedNode); }
public void Do3WayMerge(MergeOrder mergeOrder) { // <mergenotice> // When the WeSay1.3 branch gets merged, do this: // 1. Keep this code and reject the WeSay1.3 changes. They were done as a partial port of some other code changes. // 2. Remove this <mergenotice> comment and its 'end tag' comment. // 3. The parm change from 'false' to 'true' is to be kept. XmlMergeService.Do3WayMerge(mergeOrder, new LiftEntryMergingStrategy(mergeOrder), true, "header", "entry", "guid"); // </mergenotice> }
public static int Main(string[] args) { try { #if MONO var ourFilePath = args[0]; var commonFilePath = args[1]; var theirFilePath = args[2]; #else // Convert the input arguments from cp1252 -> utf8 -> ucs2 // It always seems to be 1252, even when the input code page is actually something else. CP 2012-03 // var inputEncoding = Console.InputEncoding; var inputEncoding = Encoding.GetEncoding(1252); var ourFilePath = Encoding.UTF8.GetString(inputEncoding.GetBytes(args[0])); var commonFilePath = Encoding.UTF8.GetString(inputEncoding.GetBytes(args[1])); var theirFilePath = Encoding.UTF8.GetString(inputEncoding.GetBytes(args[2])); Console.WriteLine("ChorusMerge: Input encoding {0}", inputEncoding.EncodingName); #endif //this was originally put here to test if console writes were making it out to the linux log or not Console.WriteLine("ChorusMerge: {0}, {1}, {2}", ourFilePath, commonFilePath, theirFilePath); #if RUNINDEBUGGER var order = new MergeOrder(ourFilePath, commonFilePath, theirFilePath, new MergeSituation(ourFilePath, "Me", "CHANGETHIS", "YOU", "CHANGETHIS", MergeOrder.ConflictHandlingModeChoices.WeWin)); #else MergeOrder order = MergeOrder.CreateUsingEnvironmentVariables(ourFilePath, commonFilePath, theirFilePath); #endif var handlers = ChorusFileTypeHandlerCollection.CreateWithInstalledHandlers(); var handler = handlers.GetHandlerForMerging(order.pathToOurs); //DispatchingMergeEventListener listenerDispatcher = new DispatchingMergeEventListener(); //using (HumanLogMergeEventListener humanListener = new HumanLogMergeEventListener(order.pathToOurs + ".ChorusNotes.txt")) using (ChorusNotesMergeEventListener xmlListener = new ChorusNotesMergeEventListener(order.pathToOurs + ".NewChorusNotes")) { // listenerDispatcher.AddEventListener(humanListener); // listenerDispatcher.AddEventListener(xmlListener); order.EventListener = xmlListener; handler.Do3WayMerge(order); } } catch (Exception e) { Console.Error.WriteLine("ChorusMerge Error: " + e.Message); Console.Error.WriteLine(e.StackTrace); return 1; } return 0;//no error }
public void MergeConflictFiles_AncestorDidNotExist() { using (GroupOfConflictFiles group = new GroupOfConflictFiles("", "<notes><annotation guid='bobGuid'/></notes>", "<notes><annotation guid='sallyGuid'/></notes>")) { MergeOrder order = new MergeOrder(group.BobFile.Path, group.AncestorFile.Path, group.SallyFile.Path, new NullMergeSituation()); new ChorusNotesFileHandler().Do3WayMerge(order); XmlDocument doc = new XmlDocument(); doc.Load(group.BobFile.Path); Assert.AreEqual(2, doc.SelectNodes("notes/annotation").Count); } }
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 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 Do3WayMerge(MergeOrder mergeOrder) { // Debug.Fail("john"); Guard.AgainstNull(mergeOrder, "mergeOrder"); XmlMergeService.AddConflictToListener(mergeOrder.EventListener, new UnmergableFileTypeConflict(mergeOrder.MergeSituation)); switch (mergeOrder.MergeSituation.ConflictHandlingMode) { default: // just leave our file there break; case MergeOrder.ConflictHandlingModeChoices.WeWin: break;// just leave our file there case MergeOrder.ConflictHandlingModeChoices.TheyWin: File.Copy(mergeOrder.pathToTheirs, mergeOrder.pathToOurs, true); break; } }
public void BothDidSameUpgrade() { const string commonData = "{\"modelversion\": 7000044}"; const string ourData = "{\"modelversion\": 7000046}"; const string theirData = "{\"modelversion\": 7000046}"; File.WriteAllText(_commonFile.Path, commonData); File.WriteAllText(_ourFile.Path, ourData); File.WriteAllText(_theirFile.Path, theirData); var listener = new ListenerForUnitTests(); var mergeOrder = new MergeOrder(_ourFile.Path, _commonFile.Path, _ourFile.Path, new NullMergeSituation()) { EventListener = listener }; FileHandler.Do3WayMerge(mergeOrder); var mergedData = File.ReadAllText(_ourFile.Path); Assert.AreEqual(ourData, mergedData); listener.AssertExpectedConflictCount(0); listener.AssertExpectedChangesCount(1); listener.AssertFirstChangeType<FieldWorksModelVersionUpdatedReport>(); }
public void EnsureAllBinaryPropertiesAreSetUpCorrectly() { var mdc = MetadataCache.MdCache; var mergeOrder = new MergeOrder(null, null, null, new NullMergeSituation()) { EventListener = new ListenerForUnitTests() }; var merger = FieldWorksMergeServices.CreateXmlMergerForFieldWorksData(mergeOrder, mdc); foreach (var elementStrategy in mdc.AllConcreteClasses .SelectMany(classInfo => classInfo.AllProperties, (classInfo, propertyInfo) => new {classInfo, propertyInfo}) .Where(@t => @t.propertyInfo.DataType == DataType.Binary) .Select(@t => merger.MergeStrategies.ElementStrategies[string.Format("{0}{1}_{2}", @t.propertyInfo.IsCustomProperty ? "Custom_" : "", @t.classInfo.ClassName, @t.propertyInfo.PropertyName)])) { Assert.IsTrue(elementStrategy.IsAtomic); Assert.IsFalse(elementStrategy.OrderIsRelevant); Assert.IsFalse(elementStrategy.IsImmutable); Assert.AreEqual(NumberOfChildrenAllowed.ZeroOrMore, elementStrategy.NumberOfChildren); Assert.AreEqual(0, elementStrategy.AttributesToIgnoreForMerging.Count); Assert.IsInstanceOf<FindFirstElementWithSameName>(elementStrategy.MergePartnerFinder); } }
public MergeSituation(string relativePathToFile, string firstUserId, string firstUserRevision, string secondUserId, string secondRevision, MergeOrder.ConflictHandlingModeChoices conflictHandlingMode) : this(relativePathToFile, conflictHandlingMode) { switch (conflictHandlingMode) { case MergeOrder.ConflictHandlingModeChoices.TheyWin: AlphaUserId = secondUserId; BetaUserId = firstUserId; BetaUserRevision = firstUserRevision; AlphaUserRevision = secondRevision; break; default: AlphaUserId = firstUserId; BetaUserId = secondUserId; BetaUserRevision = secondRevision; AlphaUserRevision = firstUserRevision; break; } //we don't have access to this yet: AncestorRevision = ancestorRevision; }
public void Do3WayMerge(MetadataCache mdc, MergeOrder mergeOrder) { // NB: Doesn't need the mdc updated with custom props. if (mergeOrder.EventListener is NullMergeEventListener) mergeOrder.EventListener = new ChangeAndConflictAccumulator(); // The bigger model number wins, no matter if it came in ours or theirs. var commonData = File.ReadAllText(mergeOrder.pathToCommonAncestor); var commonNumber = Int32.Parse(SplitData(commonData)[1]); var ourData = File.ReadAllText(mergeOrder.pathToOurs); var ourNumber = Int32.Parse(SplitData(ourData)[1]); var theirData = File.ReadAllText(mergeOrder.pathToTheirs); var theirNumber = Int32.Parse(SplitData(theirData)[1]); if (commonNumber == ourNumber && commonNumber == theirNumber) return; // No changes. if (ourNumber < commonNumber || theirNumber < commonNumber) throw new InvalidOperationException("Downgrade in model version number."); var mergedNumber = ourNumber; var listener = mergeOrder.EventListener; if (ourNumber > theirNumber) { listener.ChangeOccurred(new FieldWorksModelVersionUpdatedReport(mergeOrder.pathToOurs, commonNumber, ourNumber)); } else { mergedNumber = theirNumber; // Put their number in our file. {"modelversion": #####} var newFileContents = "{\"modelversion\": " + theirNumber + "}"; File.WriteAllText(mergeOrder.pathToOurs, newFileContents); listener.ChangeOccurred(new FieldWorksModelVersionUpdatedReport(mergeOrder.pathToTheirs, commonNumber, theirNumber)); } mdc.UpgradeToVersion(mergedNumber); }
/// <summary> /// Do a 3-file merge, placing the result over the "ours" file and returning an error status /// </summary> /// <remarks>Implementations can exit with an exception, which the caller will catch and deal with. /// The must not have any UI, no interaction with the user.</remarks> public void Do3WayMerge(MergeOrder mergeOrder) { Guard.AgainstNull(mergeOrder, "mergeOrder"); if (mergeOrder == null) throw new ArgumentNullException("mergeOrder"); var merger = new XmlMerger(mergeOrder.MergeSituation); SetupElementStrategies(merger); merger.EventListener = mergeOrder.EventListener; using(var oursXml = new HtmlFileForMerging(mergeOrder.pathToOurs)) using(var theirsXml = new HtmlFileForMerging(mergeOrder.pathToTheirs)) using (var ancestorXml = new HtmlFileForMerging(mergeOrder.pathToCommonAncestor)) { var result = merger.MergeFiles(oursXml.GetPathToXHtml(), theirsXml.GetPathToXHtml(), ancestorXml.GetPathToXHtml()); CarefullyWriteOutResultingXml(oursXml, result); //now convert back to html oursXml.SaveHtml(); } }
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_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 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 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']"); } }