public void Sync_RepeatedMergeFailure_WeAreLeftOnOurOwnWorkingDefault()
        {
            using (var bob = new RepositoryWithFilesSetup("bob", "test.txt", "hello"))
                using (var sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
                    using (new FailureSimulator("TextMerger-test.txt"))
                    {
                        bob.WriteNewContentsToTestFile("bobWasHere");
                        bob.AddAndCheckIn();
                        sally.WriteNewContentsToTestFile("sallyWasHere");
                        var result = sally.CheckinAndPullAndMerge(bob);
                        Assert.That(result.Succeeded, Is.False);

                        //make sure we ended up on Sally's revision, even though Bob's are newer
                        var currentRevision = sally.Repository.GetRevisionWorkingSetIsBasedOn();
                        Assert.AreEqual("sally", sally.Repository.GetRevision(currentRevision.Number.Hash).UserId);

                        //Now do it again

                        bob.WriteNewContentsToTestFile("bobWasHere2");
                        bob.AddAndCheckIn();
                        Assert.AreEqual("bob", sally.Repository.GetTip().UserId, "if bob's not the tip, we're not testing the right situation");

                        result = sally.CheckinAndPullAndMerge(bob);
                        Assert.That(result.Succeeded, Is.False);
                        result = sally.CheckinAndPullAndMerge(bob);

                        Assert.AreEqual("sally", sally.Repository.GetRevisionWorkingSetIsBasedOn().UserId);


                        //sally.ShowInTortoise();
                    }
            File.Delete(Path.Combine(Path.GetTempPath(), "TextMerger-test.txt"));
        }
        public void Sync_WeHaveAFileWhichTheyAlsoEditedButHavenotCheckedIn_TheirsIsRenamedToSafetyAndTheyGetOurs()
        {
            using (RepositoryWithFilesSetup bob = new RepositoryWithFilesSetup("bob", "test.a9a", "original"))
            {
                using (RepositoryWithFilesSetup sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
                {
                    File.WriteAllText(bob.ProjectFolder.Combine("problem.txt"), "bob's problem");
                    //notice, we don't alter the include pattern on bob, so this doesn't get checked in
                    // on his side
                    bob.AddAndCheckIn();

                    sally.ReplaceSomething("sallyWasHere");
                    File.WriteAllText(sally.ProjectFolder.Combine("problem.txt"), "sally's problem");
                    sally.ProjectConfiguration.IncludePatterns.Add("problem.txt");

                    sally.CheckinAndPullAndMerge(bob);
                    sally.AssertNoErrorsReported();

                    //ok, so the problem is now lurking in bob's repo, but it doesn't hit him until
                    //he does at least an update

                    bob.CheckinAndPullAndMerge(sally);

                    var rescueFiles = Directory.GetFiles(bob.ProjectFolder.Path, "*.ChorusRescuedFile");
                    Assert.AreEqual(1, rescueFiles.Length);
                    Assert.AreEqual("bob's problem", File.ReadAllText(rescueFiles[0]));
                    sally.AssertFileContents("problem.txt", "sally's problem");
                }
            }
        }
        public void Sync_BothChangedBinaryFile_FailureReportedOneChosenSingleHead()
        {
            using (RepositoryWithFilesSetup bob = new RepositoryWithFilesSetup("bob", "test.a9a", "original"))
            {
                using (RepositoryWithFilesSetup sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
                {
                    bob.ReplaceSomething("bobWasHere");
                    bob.AddAndCheckIn();
                    sally.ReplaceSomething("sallyWasHere");

                    //now we have a merge of a file type that don't know how to merge
                    sally.CheckinAndPullAndMerge(bob);

                    sally.AssertSingleHead();
                    bob.AssertSingleHead();

                    //sally.AssertSingleConflict(c => c.GetType == typeof (UnmergableFileTypeConflict));
                    sally.AssertSingleConflictType <UnmergableFileTypeConflict>();

                    // nb: this is sally because the conflict handling mode is (at the time of this test
                    // writing) set to WeWin.
                    Assert.That(File.ReadAllText(sally.UserFile.Path), Does.Contain("sallyWasHere"));
                }
            }
        }
        public void Sync_ExceptionInMergeCode_LeftWith2HeadsAndErrorOutputToProgress()
        {
            using (RepositoryWithFilesSetup bob = RepositoryWithFilesSetup.CreateWithLiftFile("bob"))
            {
                using (RepositoryWithFilesSetup sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
                {
                    bob.ReplaceSomething("bobWasHere");
                    bob.AddAndCheckIn();
                    sally.ReplaceSomething("sallyWasHere");
                    using (new FailureSimulator("LiftMerger.FindEntryById"))
                    {
                        sally.CheckinAndPullAndMerge(bob);
                    }
                    Assert.That(sally.ProgressString, Does.Contain("InduceChorusFailure"));

                    sally.AssertHeadCount(2);
                    //ok, Bob's the tip, but...
                    Assert.AreEqual("bob", sally.Repository.GetTip().UserId);
                    //make sure we didn't move up to that tip, because we weren't able to merge with it
                    var currentRevision = sally.GetRepository().GetRevisionWorkingSetIsBasedOn();
                    Assert.AreEqual("sally", sally.GetRepository().GetRevision(currentRevision.Number.Hash).UserId);
                    Assert.That(File.ReadAllText(sally.UserFile.Path), Does.Contain("sallyWasHere"));

                    //and over at Bob's house, it's as if Sally had never connected

                    bob.AssertHeadCount(1);
                    Assert.AreEqual("bob", bob.Repository.GetTip().UserId);
                    Assert.That(File.ReadAllText(bob.UserFile.Path), Does.Contain("bobWasHere"));
                }
            }
            File.Delete(Path.Combine(Path.GetTempPath(), "LiftMerger.FindEntryById"));
        }
        public void Sync_NewFileWithNonAsciCharacters_FileAdded()
        {
            string name = "ŭburux.txt";

            using (RepositoryWithFilesSetup bob = new RepositoryWithFilesSetup("bob", name, "original"))
            {
                bob.AddAndCheckIn();
                bob.AssertNoErrorsReported();
            }
        }
        public void Sync_MergeWhenThereIsMoreThanOneHeadToMergeWith_MergesBoth()
        {
            using (RepositoryWithFilesSetup bob = new RepositoryWithFilesSetup("bob", "test.a9a", "original"))
                using (RepositoryWithFilesSetup sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
                {
                    var tip = sally.Repository.GetTip();
                    sally.ReplaceSomething("forbranch1");
                    sally.AddAndCheckIn();
                    sally.Repository.Update(tip.Number.Hash);

                    sally.ReplaceSomething("forbranch1");
                    sally.AddAndCheckIn();
                    sally.Repository.Update(tip.Number.Hash);

                    sally.ReplaceSomething("forbranch2");
                    sally.AddAndCheckIn();
                    sally.Repository.Update(tip.Number.Hash);

                    sally.ReplaceSomething("forbranch3");
                    sally.AddAndCheckIn();
                    sally.Repository.Update(tip.Number.Hash);

                    sally.AssertHeadCount(4);

                    bob.ReplaceSomething("bobWasHere");
                    bob.AddAndCheckIn();
                    sally.ReplaceSomething("sallyWasHere");
                    sally.CheckinAndPullAndMerge(bob);

                    sally.AssertNoErrorsReported();

                    var rescueFiles = Directory.GetFiles(sally.ProjectFolder.Path, "*.ChorusRescuedFile");
                    Assert.AreEqual(0, rescueFiles.Length);

                    sally.AssertHeadCount(1);
                }
        }
예제 #7
0
        public void ConflictFileIsCheckedIn()
        {
            using (RepositoryWithFilesSetup bob = RepositoryWithFilesSetup.CreateWithLiftFile("bob"))
            {
                using (RepositoryWithFilesSetup sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
                {
                    bob.ReplaceSomething("bob");
                    bob.AddAndCheckIn();
                    sally.ReplaceSomething("sally");
                    sally.CheckinAndPullAndMerge(bob);

                    string notesFile = ChorusNotesMergeEventListener.GetChorusNotesFilePath(sally.UserFile.Path);
                    Console.WriteLine("notesFile '{0}'", notesFile);
                    Assert.That(notesFile, Does.Exist, "Conflict file should have been in working set");
                    Assert.That(sally.Synchronizer.Repository.GetFileIsInRepositoryFromFullPath(notesFile), Is.True, "Notes file should have been added to repository");
                }
            }
        }
 public void Sync_MergeFailure_LeavesNoChorusMergeProcessAlive()
 {
     using (RepositoryWithFilesSetup bob = RepositoryWithFilesSetup.CreateWithLiftFile("bob"))
     {
         using (RepositoryWithFilesSetup sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
         {
             bob.ReplaceSomething("bobWasHere");
             bob.AddAndCheckIn();
             sally.ReplaceSomething("sallyWasHere");
             using (new FailureSimulator("LiftMerger.FindEntryById"))
             {
                 sally.CheckinAndPullAndMerge(bob);
             }
             Assert.AreEqual(0, Process.GetProcessesByName("ChorusMerge").Length);
         }
     }
     File.Delete(Path.Combine(Path.GetTempPath(), "LiftMerger.FindEntryById"));
 }
        public void Sync_WeHaveUntrackedFile_NotRenamed()
        {
            using (RepositoryWithFilesSetup bob = new RepositoryWithFilesSetup("bob", "test.a9a", "original"))
            {
                using (RepositoryWithFilesSetup sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
                {
                    File.WriteAllText(bob.ProjectFolder.Combine("somethingNew.txt"), "blah");
                    bob.ProjectConfiguration.IncludePatterns.Add("somethingNew.txt");
                    bob.AddAndCheckIn();
                    sally.ReplaceSomething("sallyWasHere");
                    File.WriteAllText(sally.ProjectFolder.Combine("untracked.txt"), "foo");
                    sally.CheckinAndPullAndMerge(bob);

                    sally.AssertNoErrorsReported();

                    var rescueFiles = Directory.GetFiles(sally.ProjectFolder.Path, "*.ChorusRescuedFile");
                    Assert.AreEqual(0, rescueFiles.Length);
                }
            }
        }
        public void Sync_BothChangedBinaryFile_FailureReportedOneChosenSingleHead()
        {
            using (RepositoryWithFilesSetup bob = new RepositoryWithFilesSetup("bob", "test.a9a", "original"))
            {
                using (RepositoryWithFilesSetup sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
                {
                    bob.ReplaceSomething("bobWasHere");
                    bob.AddAndCheckIn();
                    sally.ReplaceSomething("sallyWasHere");

                    //now we have a merge of a file type that don't know how to merge
                    sally.CheckinAndPullAndMerge(bob);

                    sally.AssertSingleHead();
                    bob.AssertSingleHead();

                    //sally.AssertSingleConflict(c => c.GetType == typeof (UnmergableFileTypeConflict));
                    sally.AssertSingleConflictType<UnmergableFileTypeConflict>();

                    // nb: this is sally because the conflict handling mode is (at the time of this test
                    // writing) set to WeWin.
					Assert.IsTrue(File.ReadAllText(sally.UserFile.Path).Contains("sallyWasHere"));
                }

            }
        }
예제 #11
0
        [Category("UnknownMonoIssue")]         // It insists on failing on mono, for some reason.
        public void EnsureRightPersonMadeChanges()
        {
            const string commonAncestor =
                @"<?xml version='1.0' encoding='utf-8'?>
<Lexicon>
	<header>
		<LexDb guid='2d23f428-83a9-44ba-90f1-9e3264b5b982' >
			<DateCreated val='2012-12-10 6:29:17.117' />
			<DateModified val='2012-12-10 6:29:17.117' />
			<IsHeadwordCitationForm val='True' />
			<IsBodyInSeparateSubentry val='True' />
		</LexDb>
	</header>
	<LexEntry guid='ffdc58c9-5cc3-469f-9118-9f18c0138d02'>
		<DateCreated val='2012-12-10 6:29:17.117' />
		<DateModified val='2012-12-10 6:29:17.117' />
		<HomographNumber val='1' />
		<DoNotUseForParsing val='True' />
		<ExcludeAsHeadword val='True' />
		<Senses>
			<ownseq class='LexSense' guid='97129e67-e0a5-47c4-a875-05c2b2e1b7df'>
				<Custom
					name='Paradigm'>
					<AStr
						ws='qaa-x-ezpi'>
						<Run
							ws='qaa-x-ezpi'>saklo, yzaklo, rzaklo, wzaklo, nzaklo, -</Run>
					</AStr>
				</Custom>
			</ownseq>
		</Senses>
	</LexEntry>
</Lexicon>";
            const string sue =
                @"<?xml version='1.0' encoding='utf-8'?>
<Lexicon>
	<header>
		<LexDb guid='2d23f428-83a9-44ba-90f1-9e3264b5b982' >
			<DateCreated val='2012-12-10 6:29:17.117' />
			<DateModified val='2012-12-10 6:29:17.117' />
			<IsHeadwordCitationForm val='True' />
			<IsBodyInSeparateSubentry val='True' />
		</LexDb>
	</header>
	<LexEntry guid='ffdc58c9-5cc3-469f-9118-9f18c0138d02'>
		<DateCreated val='2012-12-10 6:29:17.117' />
		<DateModified val='2012-12-10 6:29:17.117' />
		<HomographNumber val='1' />
		<DoNotUseForParsing val='True' />
		<ExcludeAsHeadword val='True' />
		<Senses>
			<ownseq class='LexSense' guid='97129e67-e0a5-47c4-a875-05c2b2e1b7df'>
				<Custom
					name='Paradigm'>
					<AStr
						ws='qaa-x-ezpi'>
						<Run
							ws='qaa-x-ezpi'>saglo, yzaglo, rzaglo, wzaglo, nzaglo, -</Run>
					</AStr>
				</Custom>
			</ownseq>
		</Senses>
	</LexEntry>
</Lexicon>";
            const string randy =
                @"<?xml version='1.0' encoding='utf-8'?>
<Lexicon>
	<header>
		<LexDb guid='2d23f428-83a9-44ba-90f1-9e3264b5b982' >
		</LexDb>
	</header>
	<LexEntry guid='ffdc58c9-5cc3-469f-9118-9f18c0138d02'>
		<Senses>
			<ownseq class='LexSense' guid='97129e67-e0a5-47c4-a875-05c2b2e1b7df'>
				<Custom
					name='Paradigm'>
					<AStr
						ws='zpi'>
						<Run
							ws='zpi'>saklo, yzaklo, rzaklo, wzaklo, nzaklo, -</Run>
					</AStr>
				</Custom>
			</ownseq>
		</Senses>
	</LexEntry>
</Lexicon>";

            var mdc = MetadataCache.TestOnlyNewCache;

            using (var sueRepo = new RepositoryWithFilesSetup("Sue", string.Format("{0}_01.{1}", SharedConstants.Lexicon, SharedConstants.Lexdb), commonAncestor))
            {
                var sueProjPath = sueRepo.ProjectFolder.Path;
                // Add model version number file.
                var modelVersionPathname = Path.Combine(sueProjPath, SharedConstants.ModelVersionFilename);
                File.WriteAllText(modelVersionPathname, AnnotationImages.kModelVersion);
                sueRepo.Repository.TestOnlyAddSansCommit(modelVersionPathname);
                // Add custom property data file.
                var customPropsPathname = Path.Combine(sueProjPath, SharedConstants.CustomPropertiesFilename);
                File.WriteAllText(customPropsPathname, CustomPropData);
                sueRepo.Repository.TestOnlyAddSansCommit(customPropsPathname);
                sueRepo.AddAndCheckIn();

                using (var randyRepo = RepositoryWithFilesSetup.CreateByCloning("Randy", sueRepo))
                {
                    // By doing the clone first, we get the common starting state in both repos.
                    sueRepo.WriteNewContentsToTestFile(sue);
                    sueRepo.AddAndCheckIn();

                    var mergeConflictsNotesFile = ChorusNotesMergeEventListener.GetChorusNotesFilePath(randyRepo.UserFile.Path);
                    Assert.IsFalse(File.Exists(mergeConflictsNotesFile), "ChorusNotes file should NOT have been in working set.");
                    randyRepo.WriteNewContentsToTestFile(randy);
                    randyRepo.CheckinAndPullAndMerge(sueRepo);
                    Assert.IsTrue(File.Exists(mergeConflictsNotesFile), "ChorusNotes file should have been in working set.");
                    var notesContents = File.ReadAllText(mergeConflictsNotesFile);
                    Assert.IsNotNullOrEmpty(notesContents);
                    Assert.That(notesContents, Is.StringContaining("Removed Vs Edited Element Conflict"));
                    Assert.That(notesContents, Is.StringContaining("Randy deleted this element"));
                    Assert.That(notesContents, Is.StringContaining("Sue edited it"));
                    Assert.That(notesContents, Is.StringContaining("The merger kept the change made by Sue."));
                    Assert.That(notesContents, Is.StringContaining("whoWon=\"Sue\""));
                    Assert.That(notesContents, Is.StringContaining("alphaUserId=\"Randy\""));
                    Assert.That(notesContents, Is.StringContaining("betaUserId=\"Sue\""));

                    // Make sure merged file has both alts.
                    var doc = XDocument.Load(randyRepo.UserFile.Path);
                    var customParadigmElement = doc.Root.Element("LexEntry").Element("Senses").Element("ownseq").Element("Custom");
                    var aStrElements          = customParadigmElement.Elements("AStr").ToList();
                    Assert.AreEqual(2, aStrElements.Count);
                    var aStrZpi = aStrElements.FirstOrDefault(el => el.Attribute("ws").Value == "zpi");
                    Assert.IsNotNull(aStrZpi);
                    Assert.IsTrue(aStrZpi.Element("Run").Value == "saklo, yzaklo, rzaklo, wzaklo, nzaklo, -");
                    var aStrEzpi = aStrElements.FirstOrDefault(el => el.Attribute("ws").Value == "qaa-x-ezpi");
                    Assert.IsNotNull(aStrEzpi);
                    Assert.IsTrue(aStrEzpi.Element("Run").Value == "saglo, yzaglo, rzaglo, wzaglo, nzaglo, -");
                }
            }
        }
예제 #12
0
        [Category("UnknownMonoIssue")]         // Do3WayMerge is never called on Mono, for some reason.
        public void EnsureDictionaryConfigsUseDictionaryStrategy()
        {
            const string commonAncestor = @"<?xml version='1.0' encoding='utf-8'?>
<DictionaryConfiguration name='Root-based (complex forms as subentries)' allPublications='true' version='1' lastModified='2014-10-07'>
  <ConfigurationItem name='Main Entry' style='Dictionary-Normal' isEnabled='true' field='LexEntry' cssClassNameOverride='entry'>
  <ParagraphOptions paragraphStyle='Dictionary-Normal' continuationParagraphStyle='Dictionary-Continuation' />
	<ConfigurationItem name='Headword' between=' ' after='  ' style='Dictionary-Headword' isEnabled='true' field='MLHeadWord' cssClassNameOverride='mainheadword'>
	  <WritingSystemOptions writingSystemType='vernacular' displayWSAbreviation='false'>
		<Option id='vernacular' isEnabled='true'/>
	  </WritingSystemOptions>
	</ConfigurationItem>
	<ConfigurationItem name='Variant Forms' before='(' between='; ' after=') ' isEnabled='true' field='VariantFormEntryBackRefs'>
	  <ListTypeOptions list='variant'>
		<Option isEnabled='true' id='b0000000-c40e-433e-80b5-31da08771344'/>
		<Option isEnabled='false' id='0c4663b3-4d9a-47af-b9a1-c8565d8112ed'/>
	  </ListTypeOptions>
	</ConfigurationItem>
  </ConfigurationItem>
</DictionaryConfiguration>";

            const string sue = @"<?xml version='1.0' encoding='utf-8'?>
<DictionaryConfiguration name='Root-based (complex forms as subentries)' allPublications='true' version='1' lastModified='2014-10-07'>
  <ConfigurationItem name='Main Entry' style='Dictionary-Normal' isEnabled='true' field='LexEntry' cssClassNameOverride='entry'>
  <ParagraphOptions paragraphStyle='Dictionary-Normal' continuationParagraphStyle='Dictionary-Continuation' />
	<ConfigurationItem name='Headword' between=' ' after='  ' style='Dictionary-Headword' isEnabled='true' field='MLHeadWord' cssClassNameOverride='mainheadword'>
	  <WritingSystemOptions writingSystemType='vernacular' displayWSAbreviation='false'>
		<Option id='vernacular' isEnabled='false'/>
		<Option id='fr' isEnabled='true' />
	  </WritingSystemOptions>
	</ConfigurationItem>
	<ConfigurationItem name='Variant Forms' before='(' between='; ' after=') ' isEnabled='true' field='VariantFormEntryBackRefs'>
	  <ListTypeOptions list='variant'>
		<Option isEnabled='true' id='b0000000-c40e-433e-80b5-31da08771344'/>
		<Option isEnabled='false' id='0c4663b3-4d9a-47af-b9a1-c8565d8112ed'/>
	  </ListTypeOptions>
	</ConfigurationItem>
  </ConfigurationItem>
</DictionaryConfiguration>";

            const string randy = @"<?xml version='1.0' encoding='utf-8'?>
<DictionaryConfiguration name='Root-based (complex forms as subentries)' allPublications='true' version='1' lastModified='2014-10-07'>
  <ConfigurationItem name='Main Entry' style='Dictionary-Normal' isEnabled='true' field='LexEntry' cssClassNameOverride='entry'>
  <ParagraphOptions paragraphStyle='Dictionary-Normal' continuationParagraphStyle='Dictionary-Continuation' />
	<ConfigurationItem name='Headword' between=' ' after='  ' style='Dictionary-Headword' isEnabled='true' field='MLHeadWord' cssClassNameOverride='mainheadword'>
	  <WritingSystemOptions writingSystemType='vernacular' displayWSAbreviation='false'>
		<Option id='vernacular' isEnabled='true'/>
	  </WritingSystemOptions>
	</ConfigurationItem>
	<ConfigurationItem name='Variant Forms' before='(' between='; ' after=') ' isEnabled='true' field='VariantFormEntryBackRefs'>
	  <ListTypeOptions list='variant'>
		<Option isEnabled='false' id='b0000000-c40e-433e-80b5-31da08771344'/>
		<Option isEnabled='true' id='0c4663b3-4d9a-47af-b9a1-c8565d8112ed'/>
	  </ListTypeOptions>
	</ConfigurationItem>
  </ConfigurationItem>
</DictionaryConfiguration>";

            using (var tempFolder = new TemporaryFolder("Temp"))
            {
                // Copy the Dictionary Configuration Schema to where the Dictionary Configuration Handler Strategy looks
                var appsDir       = Path.GetDirectoryName(Utilities.StripFilePrefix(Assembly.GetExecutingAssembly().CodeBase));
                var xsdPath       = Path.Combine(appsDir, "TestData", "Language Explorer", "Configuration", SharedConstants.DictConfigSchemaFilename);
                var xsdPathInProj = Path.Combine(tempFolder.Path, SharedConstants.DictConfigSchemaFilename);
                File.Copy(xsdPath, xsdPathInProj, true);

                using (var sueRepo = new RepositoryWithFilesSetup("Sue", string.Format("root.{0}", SharedConstants.fwdictconfig), commonAncestor))
                    using (var randyRepo = RepositoryWithFilesSetup.CreateByCloning("Randy", sueRepo))
                    {
                        // By doing the clone before making Sue's changes, we get the common starting state in both repos.
                        sueRepo.WriteNewContentsToTestFile(sue);
                        sueRepo.AddAndCheckIn();

                        var mergeConflictsNotesFile = ChorusNotesMergeEventListener.GetChorusNotesFilePath(randyRepo.UserFile.Path);
                        Assert.IsFalse(File.Exists(mergeConflictsNotesFile), "ChorusNotes file should NOT have been in working set.");
                        randyRepo.WriteNewContentsToTestFile(randy);
                        randyRepo.CheckinAndPullAndMerge(sueRepo);
                        Assert.IsTrue(File.Exists(mergeConflictsNotesFile), "ChorusNotes file should have been in working set.");
                        var notesContents = File.ReadAllText(mergeConflictsNotesFile);
                        Assert.IsNotNullOrEmpty(notesContents);
                        Assert.That(notesContents, Is.StringContaining("Randy and Sue edited the same part of this data."));
                        Assert.That(notesContents, Is.StringContaining("The merger kept the change made by Randy."));
                        Assert.That(notesContents, Is.StringContaining("alphaUserId=\"Randy\""));
                        Assert.That(notesContents, Is.StringContaining("betaUserId=\"Sue\""));

                        // Make sure merged file has Randy's changes
                        var doc     = XDocument.Load(randyRepo.UserFile.Path);
                        var options = doc.Root.Element("ConfigurationItem").Elements("ConfigurationItem").Last(/*Variant Forms*/)
                                      .Element("ListTypeOptions").Elements("Option").ToList();
                        Assert.AreEqual(2, options.Count, "There should be two Variant Forms options");
                        Assert.AreEqual("b0000000-c40e-433e-80b5-31da08771344", options[0].Attribute("id").Value, "Options are out of order");
                        Assert.AreEqual("0c4663b3-4d9a-47af-b9a1-c8565d8112ed", options[1].Attribute("id").Value, "Options are out of order");
                        Assert.AreEqual("false", options[0].Attribute("isEnabled").Value, "First option should be disabled");
                        Assert.AreEqual("true", options[1].Attribute("isEnabled").Value, "Second option should be enabled");

                        // Make sure merged file does *not* have Sue's changes
                        options = doc.Root.Element("ConfigurationItem").Element("ConfigurationItem" /*Headword*/)
                                  .Element("WritingSystemOptions").Elements("Option").ToList();
                        Assert.AreEqual(1, options.Count, "There should be only one WS Option");
                        Assert.AreEqual("vernacular", options[0].Attribute("id").Value, "should be default vernacular");
                        Assert.AreEqual("true", options[0].Attribute("isEnabled").Value, "should be enabled");
                    }
            }
        }
 public void Sync_NewFileWithNonAsciCharacters_FileAdded()
 {
     string name = "ŭburux.txt";
     using (RepositoryWithFilesSetup bob = new RepositoryWithFilesSetup("bob", name, "original"))
     {
                bob.AddAndCheckIn();
                bob.AssertNoErrorsReported();
     }
 }
        public void Sync_WeHaveAFileWhichTheyAlsoEditedButHavenotCheckedIn_TheirsIsRenamedToSafetyAndTheyGetOurs()
        {
            using (RepositoryWithFilesSetup bob = new RepositoryWithFilesSetup("bob", "test.a9a", "original"))
            {
                using (RepositoryWithFilesSetup sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
                {
                    File.WriteAllText(bob.ProjectFolder.Combine("problem.txt"), "bob's problem");
                    //notice, we don't alter the include pattern on bob, so this doesn't get checked in 
                    // on his side
                    bob.AddAndCheckIn();

                    sally.ReplaceSomething("sallyWasHere");
                    File.WriteAllText(sally.ProjectFolder.Combine("problem.txt"), "sally's problem");
                    sally.ProjectConfiguration.IncludePatterns.Add("problem.txt");

                    sally.CheckinAndPullAndMerge(bob);
                    sally.AssertNoErrorsReported();

                    //ok, so the problem is now lurking in bob's repo, but it doesn't hit him until
                    //he does at least an update
                    
                    bob.CheckinAndPullAndMerge(sally);

                    var rescueFiles = Directory.GetFiles(bob.ProjectFolder.Path, "*.ChorusRescuedFile");
                    Assert.AreEqual(1, rescueFiles.Length);
                    Assert.AreEqual("bob's problem", File.ReadAllText(rescueFiles[0]));
                    sally.AssertFileContents("problem.txt", "sally's problem");
                }

            }
        }
        public void Sync_MergeWhenThereIsMoreThanOneHeadToMergeWith_MergesBoth()
        {
            using (RepositoryWithFilesSetup bob = new RepositoryWithFilesSetup("bob", "test.a9a", "original"))
            using (RepositoryWithFilesSetup sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
            {
                var tip = sally.Repository.GetTip();
                sally.ReplaceSomething("forbranch1");
                sally.AddAndCheckIn();
                 sally.Repository.Update(tip.Number.Hash);

                sally.ReplaceSomething("forbranch1");
                sally.AddAndCheckIn();
                 sally.Repository.Update(tip.Number.Hash);

                sally.ReplaceSomething("forbranch2");
                sally.AddAndCheckIn();
                sally.Repository.Update(tip.Number.Hash);

                sally.ReplaceSomething("forbranch3");
                sally.AddAndCheckIn();
                sally.Repository.Update(tip.Number.Hash);

                sally.AssertHeadCount(4);

                bob.ReplaceSomething("bobWasHere");
                bob.AddAndCheckIn();
                sally.ReplaceSomething("sallyWasHere");
                sally.CheckinAndPullAndMerge(bob);

                sally.AssertNoErrorsReported();

                var rescueFiles = Directory.GetFiles(sally.ProjectFolder.Path, "*.ChorusRescuedFile");
                Assert.AreEqual(0, rescueFiles.Length);

                sally.AssertHeadCount(1);
            }

        }
        public void Sync_WeHaveUntrackedFile_NotRenamed()
        {
            using (RepositoryWithFilesSetup bob = new RepositoryWithFilesSetup("bob", "test.a9a", "original"))
            {
                using (RepositoryWithFilesSetup sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
                {
                    File.WriteAllText(bob.ProjectFolder.Combine("somethingNew.txt"), "blah");
                    bob.ProjectConfiguration.IncludePatterns.Add("somethingNew.txt");
                    bob.AddAndCheckIn();
                    sally.ReplaceSomething("sallyWasHere");
                    File.WriteAllText(sally.ProjectFolder.Combine("untracked.txt"), "foo");
                    sally.CheckinAndPullAndMerge(bob);

                    sally.AssertNoErrorsReported();

                    var rescueFiles = Directory.GetFiles(sally.ProjectFolder.Path, "*.ChorusRescuedFile");
                    Assert.AreEqual(0, rescueFiles.Length);
                }
            }
        }
예제 #17
0
		[Category("UnknownMonoIssue")] // It insists on failing on mono, for some reason.
		public void EnsureRightPersonMadeChanges()
		{
			const string commonAncestor =
@"<?xml version='1.0' encoding='utf-8'?>
<Lexicon>
	<header>
		<LexDb guid='2d23f428-83a9-44ba-90f1-9e3264b5b982' >
			<DateCreated val='2012-12-10 6:29:17.117' />
			<DateModified val='2012-12-10 6:29:17.117' />
			<IsHeadwordCitationForm val='True' />
			<IsBodyInSeparateSubentry val='True' />
		</LexDb>
	</header>
	<LexEntry guid='ffdc58c9-5cc3-469f-9118-9f18c0138d02'>
		<DateCreated val='2012-12-10 6:29:17.117' />
		<DateModified val='2012-12-10 6:29:17.117' />
		<HomographNumber val='1' />
		<DoNotUseForParsing val='True' />
		<ExcludeAsHeadword val='True' />
		<Senses>
			<ownseq class='LexSense' guid='97129e67-e0a5-47c4-a875-05c2b2e1b7df'>
				<Custom
					name='Paradigm'>
					<AStr
						ws='qaa-x-ezpi'>
						<Run
							ws='qaa-x-ezpi'>saklo, yzaklo, rzaklo, wzaklo, nzaklo, -</Run>
					</AStr>
				</Custom>
			</ownseq>
		</Senses>
	</LexEntry>
</Lexicon>";
			const string sue =
@"<?xml version='1.0' encoding='utf-8'?>
<Lexicon>
	<header>
		<LexDb guid='2d23f428-83a9-44ba-90f1-9e3264b5b982' >
			<DateCreated val='2012-12-10 6:29:17.117' />
			<DateModified val='2012-12-10 6:29:17.117' />
			<IsHeadwordCitationForm val='True' />
			<IsBodyInSeparateSubentry val='True' />
		</LexDb>
	</header>
	<LexEntry guid='ffdc58c9-5cc3-469f-9118-9f18c0138d02'>
		<DateCreated val='2012-12-10 6:29:17.117' />
		<DateModified val='2012-12-10 6:29:17.117' />
		<HomographNumber val='1' />
		<DoNotUseForParsing val='True' />
		<ExcludeAsHeadword val='True' />
		<Senses>
			<ownseq class='LexSense' guid='97129e67-e0a5-47c4-a875-05c2b2e1b7df'>
				<Custom
					name='Paradigm'>
					<AStr
						ws='qaa-x-ezpi'>
						<Run
							ws='qaa-x-ezpi'>saglo, yzaglo, rzaglo, wzaglo, nzaglo, -</Run>
					</AStr>
				</Custom>
			</ownseq>
		</Senses>
	</LexEntry>
</Lexicon>";
			const string randy =
@"<?xml version='1.0' encoding='utf-8'?>
<Lexicon>
	<header>
		<LexDb guid='2d23f428-83a9-44ba-90f1-9e3264b5b982' >
		</LexDb>
	</header>
	<LexEntry guid='ffdc58c9-5cc3-469f-9118-9f18c0138d02'>
		<Senses>
			<ownseq class='LexSense' guid='97129e67-e0a5-47c4-a875-05c2b2e1b7df'>
				<Custom
					name='Paradigm'>
					<AStr
						ws='zpi'>
						<Run
							ws='zpi'>saklo, yzaklo, rzaklo, wzaklo, nzaklo, -</Run>
					</AStr>
				</Custom>
			</ownseq>
		</Senses>
	</LexEntry>
</Lexicon>";

			const string customPropData =
@"<?xml version='1.0' encoding='utf-8'?>
<AdditionalFields>
	<CustomField
		class='LexEntry'
		destclass='7'
		key='LexEntryTone'
		listRoot='53241fd4-72ae-4082-af55-6b659657083c'
		name='Tone'
		type='ReferenceCollection' />
	<CustomField
		class='LexSense'
		key='LexSenseParadigm'
		name='Paradigm'
		type='MultiString'
		wsSelector='-2' />
	<CustomField
		class='WfiWordform'
		key='WfiWordformCertified'
		name='Certified'
		type='Boolean' />
</AdditionalFields>";

			var mdc = MetadataCache.TestOnlyNewCache;
			using (var sueRepo = new RepositoryWithFilesSetup("Sue", string.Format("{0}_01.{1}", SharedConstants.Lexicon, SharedConstants.Lexdb), commonAncestor))
			{
				var sueProjPath = sueRepo.ProjectFolder.Path;
				// Add model version number file.
				var modelVersionPathname = Path.Combine(sueProjPath, SharedConstants.ModelVersionFilename);
				File.WriteAllText(modelVersionPathname, AnnotationImages.kModelVersion);
				sueRepo.Repository.TestOnlyAddSansCommit(modelVersionPathname);
				// Add custom property data file.
				var customPropsPathname = Path.Combine(sueProjPath, SharedConstants.CustomPropertiesFilename);
				File.WriteAllText(customPropsPathname, customPropData);
				sueRepo.Repository.TestOnlyAddSansCommit(customPropsPathname);
				sueRepo.AddAndCheckIn();

				using (var randyRepo = RepositoryWithFilesSetup.CreateByCloning("Randy", sueRepo))
				{
					// By doing the clone first, we get the common starting state in both repos.
					sueRepo.WriteNewContentsToTestFile(sue);
					sueRepo.AddAndCheckIn();

					var mergeConflictsNotesFile = ChorusNotesMergeEventListener.GetChorusNotesFilePath(randyRepo.UserFile.Path);
					Assert.IsFalse(File.Exists(mergeConflictsNotesFile), "ChorusNotes file should NOT have been in working set.");
					randyRepo.WriteNewContentsToTestFile(randy);
					randyRepo.CheckinAndPullAndMerge(sueRepo);
					Assert.IsTrue(File.Exists(mergeConflictsNotesFile), "ChorusNotes file should have been in working set.");
					var notesContents = File.ReadAllText(mergeConflictsNotesFile);
					Assert.IsNotNullOrEmpty(notesContents);
					Assert.IsTrue(notesContents.Contains("Removed Vs Edited Element Conflict"));
					Assert.IsTrue(notesContents.Contains("Randy deleted this element"));
					Assert.IsTrue(notesContents.Contains("Sue edited it"));
					Assert.IsTrue(notesContents.Contains("The merger kept the change made by Sue."));
					Assert.IsTrue(notesContents.Contains("whoWon=\"Sue\""));
					Assert.IsTrue(notesContents.Contains("alphaUserId=\"Randy\""));
					Assert.IsTrue(notesContents.Contains("betaUserId=\"Sue\""));

					// Make sure merged file has both alts.
					var doc = XDocument.Load(randyRepo.UserFile.Path);
					var customParadigmElement = doc.Root.Element("LexEntry").Element("Senses").Element("ownseq").Element("Custom");
					var aStrElements = customParadigmElement.Elements("AStr").ToList();
					Assert.AreEqual(2, aStrElements.Count);
					var aStrZpi = aStrElements.FirstOrDefault(el => el.Attribute("ws").Value == "zpi");
					Assert.IsNotNull(aStrZpi);
					Assert.IsTrue(aStrZpi.Element("Run").Value == "saklo, yzaklo, rzaklo, wzaklo, nzaklo, -");
					var aStrEzpi = aStrElements.FirstOrDefault(el => el.Attribute("ws").Value == "qaa-x-ezpi");
					Assert.IsNotNull(aStrEzpi);
					Assert.IsTrue(aStrEzpi.Element("Run").Value == "saglo, yzaglo, rzaglo, wzaglo, nzaglo, -");
				}
			}
		}
        public void Sync_RepeatedMergeFailure_WeAreLeftOnOurOwnWorkingDefault()
        {
            using (var bob = new RepositoryWithFilesSetup("bob", "test.txt", "hello"))
            using (var sally = RepositoryWithFilesSetup.CreateByCloning("sally",bob))
            using (new FailureSimulator("TextMerger-test.txt"))
            {
                bob.WriteNewContentsToTestFile("bobWasHere");
                bob.AddAndCheckIn();
                sally.WriteNewContentsToTestFile("sallyWasHere");
                var result = sally.CheckinAndPullAndMerge(bob);
                Assert.IsFalse(result.Succeeded);

                //make sure we ended up on Sally's revision, even though Bob's are newer
                var currentRevision = sally.Repository.GetRevisionWorkingSetIsBasedOn();
                Assert.AreEqual("sally", sally.Repository.GetRevision(currentRevision.Number.Hash).UserId);

                //Now do it again

                bob.WriteNewContentsToTestFile("bobWasHere2");
                bob.AddAndCheckIn();
                Assert.AreEqual("bob", sally.Repository.GetTip().UserId,"if bob's not the tip, we're not testing the right situation");
                
                result = sally.CheckinAndPullAndMerge(bob);
                Assert.IsFalse(result.Succeeded);
                result = sally.CheckinAndPullAndMerge(bob);
   
                Assert.AreEqual("sally",sally.Repository.GetRevisionWorkingSetIsBasedOn().UserId);
                

                //sally.ShowInTortoise();

			}
			File.Delete(Path.Combine(Path.GetTempPath(), "TextMerger-test.txt"));
        }