Example #1
0
        public void SkipConvertingElementToTextElementInAnotherFile()
        {
            // Hack conversion skip, because Flex exported some lift-ranges stuff that wasn't legal.
            const string data =
                @"<?xml version='1.0' encoding='utf-8'?>
<foo>
	<range
		id='theone'
		attr='data' >
							<form
								lang='ldb-fonipa-x-emic'>
								<element name='text'>myStuff</element>
							</form>
	</range>
</foo>";
            var originalValue = XmlMergeService.RemoveAmbiguousChildNodes;

            XmlMergeService.RemoveAmbiguousChildNodes = true;
            var doc = new XmlDocument();

            doc.LoadXml(data);
            XmlMergeService.RemoveAmbiguousChildren(new ListenerForUnitTests(), new MergeStrategies(), doc.DocumentElement);
            XmlMergeService.RemoveAmbiguousChildNodes = originalValue;
            Assert.That(doc.DocumentElement.OuterXml, Does.Not.Contain("<text>myStuff</text>"), "Converted <element> element to <text>, but should not have.");
            Assert.That(doc.DocumentElement.OuterXml, Does.Contain("<element name=\"text\">myStuff</element>"), "Element <element> went away, but should have been present.");
        }
Example #2
0
        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']");
                    }
        }
Example #3
0
 public void Do3WayMerge(MergeOrder order)
 {
     XmlMergeService.Do3WayMerge(order,
                                 new ChorusNotesAnnotationMergingStrategy(order),
                                 false,
                                 null,
                                 "annotation", "guid");
 }
Example #4
0
        [Test]         // See http://jira.palaso.org/issues/browse/CHR-18
        public void Merge_DuplicateGuidsInEntry_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'>
					</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'>
					</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'>
					</entry>
					<entry
						id='00853b73-fda2-4b12-8a89-6957cc7e7e79'
						guid='00853b73-fda2-4b12-8a89-6957cc7e7e79'>
						<lexical-unit>
							<form
								lang='en'>
								<text>goner 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[@guid='00853b73-fda2-4b12-8a89-6957cc7e7e79']");
                        XmlTestHelper.AssertXPathIsNull(result, "lift/entry[@guid='00853b73-fda2-4b12-8a89-6957cc7e7e79']/lexical-unit");
                        Assert.AreEqual(typeof(MergeWarning), listener.Warnings[0].GetType());
                    }
        }
Example #5
0
        public void GetMergedLift_ConflictingGlosses_ListenerIsNotifiedOfBothEditedConflict()
        {
            const string ours = @"<?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'>
								 <gloss lang='a'>
									<text>ourSense</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='test'  guid='F169EB3D-16F2-4eb0-91AA-FDB91636F8F6'>
							<sense id='123'>
								 <gloss lang='a'>
									<text>theirSense</text>
								 </gloss>
							 </sense>
						</entry>
					</lift>"                    ;
            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'>
								 <gloss lang='a'>
									<text>original</text>
								 </gloss>
							 </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");
                        var conflict = listener.Conflicts[0];
                        AssertConflictType <XmlTextBothEditedTextConflict>(conflict);
                        const string expectedContext = "lift://unknown?type=entry&id=F169EB3D-16F2-4eb0-91AA-FDB91636F8F6";
                        Assert.AreEqual(expectedContext, listener.Contexts[0].PathToUserUnderstandableElement,
                                        "the listener wasn't give the expected context");
                    }
        }
Example #6
0
 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>
 }
Example #7
0
        public void Merge_DuplicateKeyInGloss_NoThrow()
        {
            var ancestor =
                @"<?xml version='1.0' encoding='utf-8'?>
				<lift version='0.13' producer='FLEx 7.2.4'><entry id='lovely_f1c5a4c8-a24f-4351-8551-2b70d53a9256' guid='f1c5a4c8-a24f-4351-8551-2b70d53a9256'>
				<lexical-unit>
				<form lang='fr'><text>lovely</text></form>
				</lexical-unit>
				<trait name='morph-type' value='stem'/>
				<sense id='fist_0e0fc867-e56a-4df5-861a-1cb24d861037'>
				<grammatical-info
					value='Noun' />
				<gloss
					lang='en'>
					<text>base</text>
				</gloss>
				<gloss
					lang='swh'>
					<text>ngumi / mangumi</text>
				</gloss>
				<gloss
					lang='swh'>
					<text>konde / makonde</text>
				</gloss>
				</sense>
				</entry></lift>"                ;
            var ours   = ancestor.Replace("base", "ours");
            var theirs = ancestor.Replace("base", "theirs");

            Assert.DoesNotThrow(() =>
            {
                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);
                            //AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(@"/lift/entry/relation", 2);
                        }
            });
        }
Example #8
0
        public void EachHasNewSense_BothSensesCoveyed()
        {
            const string ours = @"<?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'>
								 <gloss lang='a'>
									<text>ourSense</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='test'  guid='F169EB3D-16F2-4eb0-91AA-FDB91636F8F6'>
							<sense id='456'>
								 <gloss lang='a'>
									<text>theirSense</text>
								 </gloss>
							 </sense>
						</entry>
					</lift>"                    ;
            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' />
					</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
                        Assert.AreEqual(typeof(AmbiguousInsertConflict), listener.Conflicts[0].GetType());
                        var result = File.ReadAllText(mergeOrder.pathToOurs);
                        XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='test']");
                        XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='test' and sense[@id='123']/gloss/text='ourSense']");
                        XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='test' and sense[@id='456']/gloss/text='theirSense']");
                    }
        }
        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]");
                    }
        }
Example #10
0
        internal void WarningOccurred(IConflict warning)
        {
            if (_htmlContextGenerator == null)
            {
                _htmlContextGenerator = new SimpleHtmlGenerator();
            }

            XmlMergeService.AddWarningToListener(
                EventListener,
                warning,
                _oursContext,
                _theirsContext,
                _ancestorContext,
                _htmlContextGenerator);
        }
Example #11
0
        internal void ConflictOccurred(IConflict conflict)
        {
            if (_htmlContextGenerator == null)
            {
                _htmlContextGenerator = new SimpleHtmlGenerator();
            }

            XmlMergeService.AddConflictToListener(
                EventListener,
                conflict,
                _oursContext,
                _theirsContext,
                _ancestorContext,
                _htmlContextGenerator);
        }
        public void EachHasNewSense_BothSensesCoveyed()
        {
            const string ours = @"<?xml version='1.0' encoding='utf-8'?>
					<lift version='0.10' producer='WeSay 1.0.0.0'>
						<entry id='test' guid='c1ed1fa8-e382-11de-8a39-0800200c9a66' >
							<sense>
								 <gloss lang='a'>
									<text>ourSense</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='test' guid='c1ed1fa8-e382-11de-8a39-0800200c9a66' >
							<sense>
								 <gloss lang='a'>
									<text>theirSense</text>
								 </gloss>
							 </sense>
						</entry>
					</lift>"                    ;
            const string ancestor = @"<?xml version='1.0' encoding='utf-8'?>
					<lift version='0.10' producer='WeSay 1.0.0.0'>
						<entry id='test' guid='c1ed1fa8-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 LiftEntryMergingStrategy(mergeOrder),
                                                    false,
                                                    "header",
                                                    "entry", "guid");
                        var result = File.ReadAllText(mergeOrder.pathToOurs);
                        XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='test']");
                        XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='test' and sense/gloss/text='ourSense']");
                        XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry[@id='test' and sense/gloss/text='theirSense']");
                    }
        }
Example #13
0
        internal void ConflictOccurred(IConflict conflict, XmlNode nodeToFindGeneratorFrom)
        {
            var contextDescriptorGenerator = GetContextDescriptorGenerator(nodeToFindGeneratorFrom);

            _htmlContextGenerator = (contextDescriptorGenerator as IGenerateHtmlContext) ?? new SimpleHtmlGenerator();

            XmlMergeService.AddConflictToListener(
                EventListener,
                conflict,
                _oursContext,
                _theirsContext,
                _ancestorContext,
                _htmlContextGenerator,
                this,
                nodeToFindGeneratorFrom);
        }
Example #14
0
        public void DuplicateSpecialElementsAreRemoved()
        {
            const string badData =
                @"<ldml>
<special xmlns:palaso='urn://palaso.org/ldmlExtensions/v1' />
<special xmlns:palaso='urn://palaso.org/ldmlExtensions/v1' goner='true' />
<special xmlns:palaso2='urn://palaso.org/ldmlExtensions/v2' />
<special xmlns:palaso2='urn://palaso.org/ldmlExtensions/v2' goner='true' />
<special xmlns:fw='urn://fieldworks.sil.org/ldmlExtensions/v1' />
<special xmlns:fw='urn://fieldworks.sil.org/ldmlExtensions/v1' goner='true' />
</ldml>";
            var doc         = new XmlDocument();
            var badRootNode = XmlUtilities.GetDocumentNodeFromRawXml(badData, doc);
            var merger      = new XmlMerger(new NullMergeSituation());

            merger.EventListener = new ListenerForUnitTests();
            LdmlFileHandler.SetupElementStrategies(merger);
            var oldValue = XmlMergeService.RemoveAmbiguousChildNodes;

            XmlMergeService.RemoveAmbiguousChildNodes = true;
            XmlMergeService.RemoveAmbiguousChildren(merger.EventListener, merger.MergeStrategies, badRootNode);
            XmlMergeService.RemoveAmbiguousChildNodes = oldValue;
            var childNodes = badRootNode.SelectNodes("special");

            Assert.IsTrue(childNodes.Count == 3);
            for (var idx = 0; idx < 3; ++idx)
            {
                XmlNode currentNode = childNodes[idx];
                switch (idx)
                {
                case 0:
                    Assert.IsNotNull(currentNode.Attributes["xmlns:palaso"]);
                    break;

                case 1:
                    Assert.IsNotNull(currentNode.Attributes["xmlns:palaso2"]);
                    break;

                case 2:
                    Assert.IsNotNull(currentNode.Attributes["xmlns:fw"]);
                    break;
                }
                Assert.IsNull(currentNode.Attributes["goner"]);
            }
        }
Example #15
0
        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;
            }
        }
Example #16
0
 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");
                    }
        }
        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 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);
                    }
        }
Example #20
0
        public void DuplicateWritingSystemsElementsAreRemoved()
        {
            const string badData =
                @"<UserLexiconSettings>
<WritingSystems />
<WritingSystems goner='true' />
</UserLexiconSettings>";
            var doc         = new XmlDocument();
            var badRootNode = XmlUtilities.GetDocumentNodeFromRawXml(badData, doc);
            var merger      = new XmlMerger(new NullMergeSituation());

            merger.EventListener = new ListenerForUnitTests();
            ProjectLexiconSettingsFileHandler.SetupElementStrategies(merger);
            var oldValue = XmlMergeService.RemoveAmbiguousChildNodes;

            XmlMergeService.RemoveAmbiguousChildNodes = true;
            XmlMergeService.RemoveAmbiguousChildren(merger.EventListener, merger.MergeStrategies, badRootNode);
            XmlMergeService.RemoveAmbiguousChildNodes = oldValue;
            var childNodes = badRootNode.SelectNodes("WritingSystems");

            Assert.That(childNodes, Is.Not.Null);
            Assert.That(childNodes.Count, Is.EqualTo(1));
            Assert.That(childNodes[0].Attributes["goner"], Is.Null);
        }
Example #21
0
        public void ConvertBogusElementToTextElementInLiftRangesFile()
        {
            // Hack conversion, because Flex exported some lift-ranges stuff that wasn't legal.
            const string data =
                @"<range
		id='theone'
		attr='data' >
							<form
								lang='ldb-fonipa-x-emic'>
								<element name='text'>myStuff</element>
							</form>
	</range>"    ;
            var originalValue = XmlMergeService.RemoveAmbiguousChildNodes;

            XmlMergeService.RemoveAmbiguousChildNodes = true;
            var doc = new XmlDocument();

            doc.LoadXml(data);
            var results = XmlMergeService.RemoveAmbiguousChildren(new ListenerForUnitTests(), new MergeStrategies(), data, "some.lift-ranges");

            XmlMergeService.RemoveAmbiguousChildNodes = originalValue;
            Assert.That(results, Does.Not.Contain("<element name=\"text\">first</element>"), "Still has bogus <element> element.");
            Assert.That(results, Does.Contain("<text>myStuff</text>"), "Converted <text> element is not present.");
        }
Example #22
0
        public void ConvertBogusElementToTextElementInLiftFile()
        {
            // Hack conversion, because Flex exported some lift-ranges stuff that wasn't legal.
            const string data          = @"<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'>
								<element name='text'>myStuff</element>
							</form>
						</lexical-unit>
					</entry>"                    ;
            var          originalValue = XmlMergeService.RemoveAmbiguousChildNodes;

            XmlMergeService.RemoveAmbiguousChildNodes = true;
            var result = XmlMergeService.RemoveAmbiguousChildren(new ListenerForUnitTests(), new MergeStrategies(), data, "some.lift");

            XmlMergeService.RemoveAmbiguousChildNodes = originalValue;
            Assert.That(result, Does.Not.Contain("<element name=\"text\">first</element>"), "Still has bogus <element> element.");
            Assert.That(result, Does.Contain("<text>myStuff</text>"), "Converted <text> element is not present.");
        }
        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");
                    }
        }
Example #24
0
        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)]");
                    }
        }
Example #25
0
        [Test]         // See http://jira.palaso.org/issues/browse/CHR-18
        public void Merge_DefinitionAncestorAndOursSameTheirsHasAdditionalForm_ResultHasAdditionalFormAlso()
        {
            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'>
						<sense id='123'>
							<definition>
								<form lang='a'>
									<text>aSense</text>
								</form>
							</definition>
						 </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='???_00853b73-fda2-4b12-8a89-6957cc7e7e79'
						dateCreated='2011-03-09T05:08:44Z'
						dateModified='2012-05-14T02:38:00Z'
						guid='00853b73-fda2-4b12-8a89-6957cc7e7e79'>
						<sense id='123'>
							<definition>
								<form lang='a'>
									<text>aSense</text>
								</form>
								<form lang='b'>
									<text>bSense</text>
								</form>
							</definition>
						 </sense>
					</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'>
						<sense id='123'>
							<definition>
								<form lang='a'>
									<text>aSense</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.AssertXPathMatchesExactlyOne(result, "lift/entry/sense/definition/form[@lang='a']");
                        XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry/sense/definition/form[@lang='b']");
                    }
        }
Example #26
0
        private void RoundTripData(Stopwatch breakupTimer, Stopwatch restoreTimer, Stopwatch ambiguousTimer, StringBuilder sbValidation)
        {
            File.Copy(_srcFwdataPathname, _srcFwdataPathname + ".orig", true); // Keep it safe.
            GetFreshMdc();                                                     // Want it fresh.
            breakupTimer.Start();
            FLExProjectSplitter.PushHumptyOffTheWall(new NullProgress(), _srcFwdataPathname);
            breakupTimer.Stop();
            GC.Collect(2, GCCollectionMode.Forced);

            if (_cbCheckAmbiguousElements.Checked)
            {
                var allDataFiles = new HashSet <string>();
                var currentDir   = Path.Combine(_workingDir, "Linguistics");
                if (Directory.Exists(currentDir))
                {
                    allDataFiles.UnionWith(from pathname in Directory.GetFiles(currentDir, "*.*", SearchOption.AllDirectories)
                                           where !pathname.ToLowerInvariant().EndsWith("chorusnotes")
                                           select pathname);
                }
                currentDir = Path.Combine(_workingDir, "Anthropology");
                if (Directory.Exists(currentDir))
                {
                    allDataFiles.UnionWith(from pathname in Directory.GetFiles(currentDir, "*.*", SearchOption.AllDirectories)
                                           where !pathname.ToLowerInvariant().EndsWith("chorusnotes")
                                           select pathname);
                }
                currentDir = Path.Combine(_workingDir, "Other");
                if (Directory.Exists(currentDir))
                {
                    allDataFiles.UnionWith(
                        from pathname in Directory.GetFiles(currentDir, "*.*", SearchOption.AllDirectories)
                        where !pathname.ToLowerInvariant().EndsWith("chorusnotes")
                        select pathname);
                }
                currentDir = Path.Combine(_workingDir, "General");
                if (Directory.Exists(currentDir))
                {
                    allDataFiles.UnionWith(from pathname in Directory.GetFiles(currentDir, "*.*", SearchOption.AllDirectories)
                                           where !pathname.ToLowerInvariant().EndsWith("chorusnotes")
                                           select pathname);
                }
                var mergeOrder = new MergeOrder(null, null, null, new NullMergeSituation())
                {
                    EventListener = new ChangeAndConflictAccumulator()
                };
                var merger = FieldWorksMergeServices.CreateXmlMergerForFieldWorksData(mergeOrder, MetadataCache.MdCache);
                ambiguousTimer.Start();
                foreach (var dataFile in allDataFiles)
                {
                    var    extension           = Path.GetExtension(dataFile).Substring(1);
                    string optionalElementName = null;
                    string mainRecordName      = null;
                    switch (extension)
                    {
                    case SharedConstants.Style:
                        mainRecordName = SharedConstants.StStyle;
                        break;

                    case SharedConstants.List:
                        mainRecordName = SharedConstants.CmPossibilityList;
                        break;

                    case SharedConstants.langproj:
                        mainRecordName = SharedConstants.LangProject;
                        break;

                    case SharedConstants.Annotation:
                        mainRecordName = SharedConstants.CmAnnotation;
                        break;

                    case SharedConstants.Filter:
                        mainRecordName = SharedConstants.CmFilter;
                        break;

                    case SharedConstants.orderings:
                        mainRecordName = SharedConstants.VirtualOrdering;
                        break;

                    case SharedConstants.pictures:
                        mainRecordName = SharedConstants.CmPicture;
                        break;

                    case SharedConstants.ArchivedDraft:
                        mainRecordName = SharedConstants.ScrDraft;
                        break;

                    case SharedConstants.ImportSetting:
                        mainRecordName = SharedConstants.ScrImportSet;
                        break;

                    case SharedConstants.Srs:
                        mainRecordName = SharedConstants.ScrRefSystem;
                        break;

                    case SharedConstants.Trans:
                        mainRecordName = SharedConstants.Scripture;
                        break;

                    case SharedConstants.bookannotations:
                        mainRecordName = SharedConstants.ScrBookAnnotations;
                        break;

                    case SharedConstants.book:
                        mainRecordName = SharedConstants.ScrBook;
                        break;

                    case SharedConstants.Ntbk:
                        optionalElementName = SharedConstants.Header;
                        mainRecordName      = SharedConstants.RnGenericRec;
                        break;

                    case SharedConstants.Reversal:
                        optionalElementName = SharedConstants.Header;
                        mainRecordName      = SharedConstants.ReversalIndexEntry;
                        break;

                    case SharedConstants.Lexdb:
                        optionalElementName = SharedConstants.Header;
                        mainRecordName      = SharedConstants.LexEntry;
                        break;

                    case SharedConstants.TextInCorpus:
                        mainRecordName = SharedConstants.Text;
                        break;

                    case SharedConstants.Inventory:
                        optionalElementName = SharedConstants.Header;
                        mainRecordName      = SharedConstants.WfiWordform;
                        break;

                    case SharedConstants.DiscourseExt:
                        optionalElementName = SharedConstants.Header;
                        mainRecordName      = SharedConstants.DsChart;
                        break;

                    case SharedConstants.Featsys:
                        mainRecordName = SharedConstants.FsFeatureSystem;
                        break;

                    case SharedConstants.Phondata:
                        mainRecordName = SharedConstants.PhPhonData;
                        break;

                    case SharedConstants.Morphdata:
                        mainRecordName = SharedConstants.MoMorphData;
                        break;

                    case SharedConstants.Agents:
                        mainRecordName = SharedConstants.CmAgent;
                        break;
                    }
                    using (var fastSplitter = new FastXmlElementSplitter(dataFile))
                    {
                        bool foundOptionalFirstElement;
                        foreach (var record in fastSplitter.GetSecondLevelElementBytes(optionalElementName, mainRecordName, out foundOptionalFirstElement))
                        {
                            XmlMergeService.RemoveAmbiguousChildren(merger.EventListener, merger.MergeStrategies, CreateXmlNodeFromBytes(record));
                        }
                    }
                }
                ambiguousTimer.Stop();
                foreach (var warning in ((ChangeAndConflictAccumulator)merger.EventListener).Warnings)
                {
                    sbValidation.AppendLine(warning.Description);
                    sbValidation.AppendLine();
                    sbValidation.AppendLine(warning.HtmlDetails);
                    sbValidation.AppendLine();
                }
                GC.Collect(2, GCCollectionMode.Forced);
            }
            restoreTimer.Start();
            FLExProjectUnifier.PutHumptyTogetherAgain(new NullProgress(), _srcFwdataPathname);
            restoreTimer.Stop();
            GC.Collect(2, GCCollectionMode.Forced);
        }
Example #27
0
        public NodeMergeResult Merge(XmlNode ourParent, XmlNode ours, XmlNode theirs, XmlNode ancestor)
        {
            SendMergeHeartbeat();
            if (ours == null && theirs == null && ancestor == null)
            {
                throw new InvalidOperationException("At least one node has to exist.");
            }

            var result   = new NodeMergeResult();
            var listener = EventListener as DispatchingMergeEventListener;

            if (listener == null)
            {
                var dispatcher = new DispatchingMergeEventListener();
                dispatcher.AddEventListener(result);
                if (EventListener != null)
                {
                    dispatcher.AddEventListener(EventListener);
                }
                EventListener = dispatcher;
            }
            else
            {
                listener.AddEventListener(result);
            }

            if (XmlMergeService.RemoveAmbiguousChildNodes)
            {
                // Remove any duplicate child nodes in all three.
                XmlMergeService.RemoveAmbiguousChildren(EventListener, MergeStrategies, ours);
                XmlMergeService.RemoveAmbiguousChildren(EventListener, MergeStrategies, theirs);
                XmlMergeService.RemoveAmbiguousChildren(EventListener, MergeStrategies, ancestor);
            }

            if (ancestor == null)
            {
                if (ours == null)
                {
                    // tested
                    EventListener.ChangeOccurred(new XmlAdditionChangeReport(MergeSituation.PathToFileInRepository, theirs));
                    result.MergedNode = theirs;
                }
                else if (theirs == null)
                {
                    // tested
                    EventListener.ChangeOccurred(new XmlAdditionChangeReport(MergeSituation.PathToFileInRepository, ours));
                    result.MergedNode = ours;
                }
                else
                {
                    // Both added.
                    if (XmlUtilities.AreXmlElementsEqual(ours, theirs))
                    {
                        // Same thing. (tested)
                        EventListener.ChangeOccurred(new XmlBothAddedSameChangeReport(MergeSituation.PathToFileInRepository, ours));
                        result.MergedNode = ours;
                    }
                    else
                    {
                        // But, not the same thing.
                        if (MergeSituation.ConflictHandlingMode == MergeOrder.ConflictHandlingModeChoices.WeWin)
                        {
                            // tested
                            ConflictOccurred(new BothAddedMainElementButWithDifferentContentConflict(ours.Name, ours, theirs, MergeSituation, MergeStrategies.GetElementStrategy(ours), MergeSituation.AlphaUserId));
                            result.MergedNode = ours;
                        }
                        else
                        {
                            // tested
                            ConflictOccurred(new BothAddedMainElementButWithDifferentContentConflict(theirs.Name, theirs, ours, MergeSituation, MergeStrategies.GetElementStrategy(ours), MergeSituation.BetaUserId));
                            result.MergedNode = theirs;
                        }
                    }
                }
                return(result);
            }

            // ancestor exists
            if (ours == null && theirs == null)
            {
                // tested
                EventListener.ChangeOccurred(new XmlBothDeletionChangeReport(MergeSituation.PathToFileInRepository, ancestor));
                result.MergedNode = null;
                return(result);
            }
            if (ours == null)
            {
                if (XmlUtilities.AreXmlElementsEqual(ancestor, theirs))
                {
                    // tested
                    EventListener.ChangeOccurred(new XmlDeletionChangeReport(MergeSituation.PathToFileInRepository, ancestor, theirs));
                    result.MergedNode = null;
                }
                else
                {
                    // tested
                    ConflictOccurred(new RemovedVsEditedElementConflict(ancestor.Name, null, theirs, ancestor, MergeSituation, MergeStrategies.GetElementStrategy(ancestor), MergeSituation.BetaUserId));
                    result.MergedNode = theirs;
                }
                return(result);
            }
            if (theirs == null)
            {
                if (XmlUtilities.AreXmlElementsEqual(ancestor, ours))
                {
                    // tested
                    EventListener.ChangeOccurred(new XmlDeletionChangeReport(MergeSituation.PathToFileInRepository, ancestor, ours));
                    result.MergedNode = null;
                }
                else
                {
                    // tested
                    ConflictOccurred(new EditedVsRemovedElementConflict(ancestor.Name, ours, null, ancestor, MergeSituation, MergeStrategies.GetElementStrategy(ancestor), MergeSituation.AlphaUserId));
                    result.MergedNode = ours;
                }
                return(result);
            }

            // All three nodes exist.
            MergeInner(ourParent, ref ours, theirs, ancestor);
            result.MergedNode = ours;

            return(result);
        }
Example #28
0
        public void GetMergedLift_MysteryDroppedGloss()
        {
            const string ours = @"<?xml version='1.0' encoding='utf-8'?>
					<lift version='0.13' producer='WeSay 1.0.0.0'>
					   <entry
		id='nɪntɔnnʊ_49327c35-759e-4db3-984a-b7dc5af1b1b0'
		dateCreated='2012-01-30T10:45:04Z'
		dateModified='2012-02-23T08:52:25Z'
		guid='49327c35-759e-4db3-984a-b7dc5af1b1b0'>
		<lexical-unit>
			<form
				lang='vag-fonipa-x-etic'>
				<text>nɪ́ntɔ́nnʊ̄</text>
			</form>
		</lexical-unit>
		<field
			type='pl'>
			<form
				lang='vag-fonipa-x-etic'>
				<text>nɪ́ntɔ́ntʊ́</text>
			</form>
		</field>
		<field
			type='tn'>
			<form
				lang='fr'>
				<text>HHM</text>
			</form>
		</field>
		<field
			type='tnpl'>
			<form
				lang='fr'>
				<text>HHH</text>
			</form>
		</field>
		<sense
			id='lip_39e4b942-0bf6-4494-aa9b-7f5163feb2bc'>
			<grammatical-info
				value='Noun' />
			<gloss
				lang='en'>
				<text>lip</text>
			</gloss>
			<gloss
				lang='es'>
				<text>labio</text>
			</gloss>
			<gloss
				lang='fr'>
				<text>lèvre</text>
			</gloss>
			<gloss
				lang='ha'>
				<text>bā̀kī</text>
			</gloss>
			<gloss
				lang='nku-fonipa-x-etic'>
				<text>nwɔ́gbɛ́ɟɛ̀</text>
			</gloss>
			<gloss
				lang='swh'>
				<text>mdomo / midomo</text>
			</gloss>
			<definition>
				<form
					lang='en'>
					<text>lip</text>
				</form>
				<form
					lang='es'>
					<text>labio</text>
				</form>
				<form
					lang='fr'>
					<text>lèvre</text>
				</form>
				<form
					lang='ha'>
					<text>bā̀kī</text>
				</form>
				<form
					lang='id'>
					<text>bibir</text>
				</form>
				<form
					lang='pt'>
					<text>lábio</text>
				</form>
				<form
					lang='swh'>
					<text>mdomo / midomo</text>
				</form>
			</definition>
			<note
				type='source'>
				<form
					lang='x-unk'>
					<text>
			00<span
							lang='en'>16</span></text>
				</form>
			</note>
			<field
				type='SILCAWL'>
				<form
					lang='en'>
					<text>0016</text>
				</form>
			</field>
			<trait
				name='semantic-domain-ddp4'
				value='2.1.1.4 Mouth' />
		</sense>
	</entry>

					</lift>"                    ;

            const string theirs   = @"<?xml version='1.0' encoding='utf-8'?>
					<lift version='0.13' producer='WeSay 1.0.0.0'>
						<entry
		id='nɪntɔnnʊ_49327c35-759e-4db3-984a-b7dc5af1b1b0'
		dateCreated='2012-01-30T10:45:04Z'
		dateModified='2012-01-30T10:59:31Z'
		guid='49327c35-759e-4db3-984a-b7dc5af1b1b0'>
		<lexical-unit>
			<form
				lang='vag-fonipa-x-etic'>
				<text>nɪ́ntɔ́nnʊ̄</text>
			</form>
		</lexical-unit>

		<field
			type='pl'>
			<form
				lang='vag-fonipa-x-etic'>
				<text>nɪ́ntɔ́ntʊ́</text>
			</form>
		</field>
		<note>
			<form
				lang='fr'>
				<text>Homonyme avec l'ethnie lobi sg pl. A faire.</text>
			</form>
		</note>

		<field
			type='tn'>
			<form
				lang='fr'>
				<text>HHM</text>
			</form>
		</field>
		<field
			type='tnpl'>
			<form
				lang='fr'>
				<text>HHH</text>
			</form>
		</field>
		<sense
			id='lip_39e4b942-0bf6-4494-aa9b-7f5163feb2bc'>
			<grammatical-info
				value='Noun' />
			<gloss
				lang='en'>
				<text>lip</text>
			</gloss>
			<gloss
				lang='es'>
				<text>labio</text>
			</gloss>
			<gloss
				lang='fr'>
				<text>lèvre</text>
			</gloss>
			<gloss
				lang='ha'>
				<text>bā̀kī</text>
			</gloss>
			<gloss
				lang='swh'>
				<text>mdomo / midomo</text>
			</gloss>
			<definition>
				<form
					lang='en'>
					<text>lip</text>
				</form>
				<form
					lang='es'>
					<text>labio</text>
				</form>
				<form
					lang='fr'>
					<text>lèvre</text>
				</form>
				<form
					lang='ha'>
					<text>bā̀kī</text>
				</form>
				<form
					lang='id'>
					<text>bibir</text>
				</form>
				<form
					lang='pt'>
					<text>lábio</text>
				</form>
				<form
					lang='swh'>
					<text>mdomo / midomo</text>
				</form>
			</definition>
			<note
				type='source'>
				<form
					lang='x-unk'>
					<text>
			00<span
							lang='en'>16</span></text>
				</form>
			</note>
			<field
				type='SILCAWL'>
				<form
					lang='en'>
					<text>0016</text>
				</form>
			</field>
			<trait
				name='semantic-domain-ddp4'
				value='2.1.1.4 Mouth' />
		</sense>
	</entry>

					</lift>"                    ;
            const string ancestor = @"<?xml version='1.0' encoding='utf-8'?>
					<lift version='0.13' producer='WeSay 1.0.0.0'>
						<entry
		id='nɪntɔnnʊ_49327c35-759e-4db3-984a-b7dc5af1b1b0'
		dateCreated='2012-01-30T10:45:04Z'
		dateModified='2012-01-30T10:59:31Z'
		guid='49327c35-759e-4db3-984a-b7dc5af1b1b0'>
		<lexical-unit>
			<form
				lang='vag-fonipa-x-etic'>
				<text>nɪ́ntɔ́nnʊ̄</text>
			</form>
		</lexical-unit>
		<annotation
			name='sorted-index'
			value='10' />
		<field
			type='pl'>
			<form
				lang='vag-fonipa-x-etic'>
				<text>nɪ́ntɔ́ntʊ́</text>
			</form>
		</field>
		<field
			type='tn'>
			<form
				lang='fr'>
				<text>HHM</text>
			</form>
		</field>
		<field
			type='tnpl'>
			<form
				lang='fr'>
				<text>HHH</text>
			</form>
		</field>
		<sense
			id='lip_39e4b942-0bf6-4494-aa9b-7f5163feb2bc'>
			<grammatical-info
				value='Noun' />
			<gloss
				lang='en'>
				<text>lip</text>
			</gloss>
			<gloss
				lang='es'>
				<text>labio</text>
			</gloss>
			<gloss
				lang='fr'>
				<text>lèvre</text>
			</gloss>
			<gloss
				lang='ha'>
				<text>bā̀kī</text>
			</gloss>
			<gloss
				lang='swh'>
				<text>mdomo / midomo</text>
			</gloss>
			<definition>
				<form
					lang='en'>
					<text>lip</text>
				</form>
				<form
					lang='es'>
					<text>labio</text>
				</form>
				<form
					lang='fr'>
					<text>lèvre</text>
				</form>
				<form
					lang='ha'>
					<text>bā̀kī</text>
				</form>
				<form
					lang='id'>
					<text>bibir</text>
				</form>
				<form
					lang='pt'>
					<text>lábio</text>
				</form>
				<form
					lang='swh'>
					<text>mdomo / midomo</text>
				</form>
			</definition>
			<note
				type='source'>
				<form
					lang='x-unk'>
					<text>
			00<span
							lang='en'>16</span></text>
				</form>
			</note>
			<field
				type='SILCAWL'>
				<form
					lang='en'>
					<text>0016</text>
				</form>
			</field>
			<trait
				name='semantic-domain-ddp4'
				value='2.1.1.4 Mouth' />
		</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");
                        var result = File.ReadAllText(mergeOrder.pathToOurs);
                        //each of these are things we saw go wrong in the user's failed merge. we combined all the missing data
                        //into a single entry.  This never did demonstrate the problem, but it ruled out that the problem
                        //was a simple one of failure to merge entries properly!


                        //glosses like this were being lost
                        XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry/sense/gloss[@lang='nku-fonipa-x-etic']");

                        //there was a case where the <annotation> was in the base, but not the piers, yet it showed up in the merge!
                        XmlTestHelper.AssertXPathIsNull(result, "lift/entry/annotation");

                        //notes were being lost
                        XmlTestHelper.AssertXPathMatchesExactlyOne(result, "lift/entry/note/form[@lang='fr']");
                    }
        }
Example #29
0
        public void ClassSpansMerge()
        {
            var ancestor =
                @"<?xml version='1.0' encoding='utf-8'?>
				<lift version='0.13' producer='FLEx 7.2.4'>
				<entry id='lovely_f1c5a4c8-a24f-4351-8551-2b70d53a9256' guid='f1c5a4c8-a24f-4351-8551-2b70d53a9256'>
				<lexical-unit>
				<form lang='fr'><text>lovely</text></form>
				</lexical-unit>
				<trait name='morph-type' value='stem'/>
				<sense id='de53a9a1-5b70-49e5-8dbe-171bff37d624'>
				<example>
				<form lang='fr'>
				<text>This is <span
					class='Strong'>an</span> example.</text>
				</form>
				<translation
				  type='Free translation'>
				  <form
					lang='en'>
					<text>A translation of <span
						class='Strong'>the</span> example</text>
				  </form>
				</translation>
				</example>
				</sense>
				</entry>
				</lift>"                ;
            var ours =             // add 'sentence' to example
                       @"<?xml version='1.0' encoding='utf-8'?>
				<lift version='0.13' producer='FLEx 7.2.4'>
				<entry id='lovely_f1c5a4c8-a24f-4351-8551-2b70d53a9256' guid='f1c5a4c8-a24f-4351-8551-2b70d53a9256'>
				<lexical-unit>
				<form lang='fr'><text>lovely</text></form>
				</lexical-unit>
				<trait name='morph-type' value='stem'/>
				<sense id='de53a9a1-5b70-49e5-8dbe-171bff37d624'>
				<example>
				<form lang='fr'>
				<text>This is <span
					class='Strong'>an</span> example sentence.</text>
				</form>
				<translation
				  type='Free translation'>
				  <form
					lang='en'>
					<text>A translation of <span
						class='Strong'>the</span> example</text>
				  </form>
				</translation>
				</example>
				</sense>
				</entry>
				</lift>"                ;
            var theirs =           // add 'sentence' to TRANSLATION of example
                         @"<?xml version='1.0' encoding='utf-8'?>
				<lift version='0.13' producer='FLEx 7.2.4'>
				<entry id='lovely_f1c5a4c8-a24f-4351-8551-2b70d53a9256' guid='f1c5a4c8-a24f-4351-8551-2b70d53a9256'>
				<lexical-unit>
				<form lang='fr'><text>lovely</text></form>
				</lexical-unit>
				<trait name='morph-type' value='stem'/>
				<sense id='de53a9a1-5b70-49e5-8dbe-171bff37d624'>
				<example>
				<form lang='fr'>
				<text>This is <span
					class='Strong'>an</span> example.</text>
				</form>
				<translation
				  type='Free translation'>
				  <form
					lang='en'>
					<text>A translation of <span
						class='Strong'>the</span> example sentence</text>
				  </form>
				</translation>
				</example>
				</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");
                        var result = File.ReadAllText(mergeOrder.pathToOurs);
                        AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(@"/lift/entry/sense/example/form/text/span", 1);
                        AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(@"/lift/entry/sense/example/translation/form/text/span", 1);
                    }
        }
Example #30
0
        public void RelationsMergeWithoutThrowing()
        {
            var ancestor =
                @"<?xml version='1.0' encoding='utf-8'?>
				<lift version='0.13' producer='FLEx 7.2.4'><entry id='lovely_f1c5a4c8-a24f-4351-8551-2b70d53a9256' guid='f1c5a4c8-a24f-4351-8551-2b70d53a9256'>
				<lexical-unit>
				<form lang='fr'><text>lovely</text></form>
				</lexical-unit>
				<trait name='morph-type' value='stem'/>
				<sense id='de53a9a1-5b70-49e5-8dbe-171bff37d624'>
				<example>
				<form lang='fr'><text>This is example sentence one</text></form>
				</example>
				<example>
				<form lang='fr'><text>This is example sentence two.</text></form>
				<translation type='Free translation'>
				<form lang='en'><text>This is a translation of two</text></form>
				</translation>
				</example>
				</sense>
				</entry>
				<entry id='love_92b74399-ce6e-4f24-8412-784e0227d3eb' guid='92b74399-ce6e-4f24-8412-784e0227d3eb'>
				<lexical-unit>
				<form lang='fr'><text>love</text></form>
				</lexical-unit>
				<trait  name='morph-type' value='stem'/>
				<etymology type='proto' source='French'>
				<form lang='fr'><text>It came from </text></form>
				<form lang='en'><text>the deep</text></form>
				</etymology>
				<relation type='_component-lexeme' ref='lovely_f1c5a4c8-a24f-4351-8551-2b70d53a9256'>
				<trait name='is-primary' value='true'/>
				<trait name='complex-form-type' value=''/>
				</relation>
				<sense id='3185e889-eec3-4148-8df9-8f446bc498b7'>
				</sense>
				</entry></lift>"                ;
            var ours   = ancestor.Replace(@"It came from", @"May have come from");
            var theirs = ancestor.Replace(@"</entry></lift>",
                                          @"</entry><entry id='newentry' guid='fffffff-ffff-ffff-ffff-ffffffff'><lexical-unit><form lang='fr'><text>loverly</text></form></lexical-unit></entry></lift>");

            theirs = theirs.Replace(@"</relation>",
                                    @"</relation><relation type='_component-lexeme' ref='newentry'><trait name='is-primary' value='true'/><trait name='complex-form-type' value=''/></relation>");

            Assert.DoesNotThrow(() =>
            {
                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);
                            AssertThatXmlIn.String(result).HasSpecifiedNumberOfMatchesForXpath(@"/lift/entry/relation", 2);
                        }
            });
        }