public void Setup() { _progress = new StringBuilderProgress(); _pathToTestRoot = Path.Combine(Path.GetTempPath(), "ChorusHistoryPaneTest"); // Don't use 'standard' ChorusTest, since it will fial, if the tests are run in seperate processes (R# 6). if (Directory.Exists(_pathToTestRoot)) { Directory.Delete(_pathToTestRoot, true); } Directory.CreateDirectory(_pathToTestRoot); string pathToText = WriteTestFile("version one of my pretend txt"); RepositorySetup.MakeRepositoryForTest(_pathToTestRoot, "bob", _progress); _project = new ProjectFolderConfiguration(_pathToTestRoot); _project.FolderPath = _pathToTestRoot; _project.IncludePatterns.Add(pathToText); _project.FolderPath = _pathToTestRoot; var revisionListOptions = new RevisionListOptions(); revisionListOptions.RevisionsToShowFilter = ShowRevisionPredicate; _model = new RevisionInRepositoryModel(HgRepository.CreateOrUseExisting(_project.FolderPath, new NullProgress()), null, revisionListOptions); _model.ProgressDisplay = _progress; }
public void SaveSettings_PreexistsAndWeSave_MovesCredentials([Values(true, false)] bool isResumable) { ServerSettingsModel.PasswordForSession = Settings.Default.LanguageForgePass = Settings.Default.LanguageForgeUser = null; using (var folder = new TemporaryFolder("ServerSettingsModel")) { const string user = "******"; const string pass = "******"; var subdomain = isResumable ? "resumable" : "hg-public"; var oldHost = $"{subdomain}.languagedepot.org/tpi"; var oldUrl = $"https://{user}:{pass}@{oldHost}"; const string newDomainAndProj = ".languageforge.org/tpi"; var newUrl = $"https://{subdomain}{newDomainAndProj}"; var newUrlWithCredentials = $"https://{user}:{pass}@{subdomain}{newDomainAndProj}"; // Precondition is some url that is not our default from the ServerSettingsModel var original = HgRepository.CreateOrUseExisting(folder.Path, new NullProgress()); original.SetKnownRepositoryAddresses(new[] { new HttpRepositoryPath("languageForge.org [legacy sync]", oldUrl, false) }); var m = new ServerSettingsModel(); m.InitFromProjectPath(folder.Path); m.SaveSettings(); Assert.AreEqual(user, Settings.Default.LanguageForgeUser); Assert.AreEqual(pass, ServerSettingsModel.DecryptPassword(Settings.Default.LanguageForgePass)); Assert.That(folder.Combine(".hg"), Does.Exist); Assert.That(folder.Combine(".hg", "hgrc"), Does.Exist); var repo = HgRepository.CreateOrUseExisting(folder.Path, new NullProgress()); var address = repo.GetDefaultNetworkAddress <HttpRepositoryPath>(); Assert.AreEqual(newUrl, address.URI); Assert.AreEqual(isResumable ? newUrl : newUrlWithCredentials, address.GetPotentialRepoUri(null, null, null), "The new 'potential' URI should contain credentials only when non-resumable"); } }
public void CreateOrLocate_FolderHasAccentedLetter_FindsIt() { using (var setup = new RepositorySetup("Abé Books")) { Assert.NotNull(HgRepository.CreateOrUseExisting(setup.Repository.PathToRepo, new ConsoleProgress())); } }
public void CanCollaborateOnLift() { ConsoleProgress progress = new ConsoleProgress(); BobSetup bobSetup = new BobSetup(progress, _pathToTestRoot); bobSetup.ChangeTextFile(); //Ok, this is unrealistic, but we just clone Bob onto Sally string sallyMachineRoot = Path.Combine(_pathToTestRoot, "sally"); Directory.CreateDirectory(sallyMachineRoot); string sallyProjectRoot = bobSetup.SetupClone(sallyMachineRoot); ProjectFolderConfiguration sallyProject = BobSetup.CreateFolderConfig(sallyProjectRoot); var repository = HgRepository.CreateOrUseExisting(sallyProject.FolderPath, progress); repository.SetUserNameInIni("sally", progress); // bob makes a change and syncs File.WriteAllText(bobSetup._pathToLift, LiftFileStrings.lift12Dog); var bobOptions = new SyncOptions { CheckinDescription = "added 'dog'", DoMergeWithOthers = false, // just want a fast checkin DoSendToOthers = false, // just want a fast checkin DoPullFromOthers = false // just want a fast checkin }; bobSetup.GetSynchronizer().SyncNow(bobOptions); //now Sally modifies the original file, not having seen Bob's changes yet var sallyPathToLift = Path.Combine(sallyProject.FolderPath, Path.Combine("lexicon", "foo.lift")); File.WriteAllText(sallyPathToLift, LiftFileStrings.lift12Cat); //Sally syncs, pulling in Bob's change, and encountering a need to merge (no conflicts) var sallyOptions = new SyncOptions { CheckinDescription = "adding cat", DoPullFromOthers = true, DoSendToOthers = true, DoMergeWithOthers = true }; sallyOptions.RepositorySourcesToTry.Add(RepositoryAddress.Create("bob's machine", bobSetup.BobProjectPath, false)); var synchronizer = Synchronizer.FromProjectConfiguration(sallyProject, progress); synchronizer.SyncNow(sallyOptions); //Debug.WriteLine("bob's: " + File.ReadAllText(bobSetup._pathToLift)); var contents = File.ReadAllText(sallyPathToLift); //Debug.WriteLine("sally's: " + contents); Assert.That(contents, Does.Contain("cat")); Assert.That(contents, Does.Contain("dog")); }
public void CreateOrLocate_FolderHasAccentedLetter2_FindsIt() { using (var testRoot = new TemporaryFolder("bloom sr test")) { string path = Path.Combine(testRoot.Path, "Abé Books"); Directory.CreateDirectory(path); Assert.NotNull(HgRepository.CreateOrUseExisting(path, new ConsoleProgress())); Assert.NotNull(HgRepository.CreateOrUseExisting(path, new ConsoleProgress())); } }
public void Pull_Test() { //RobustNetworkOperation.ClearCredentialSettings(); using (var f = new TemporaryFolder("pulltest")) { var repo = HgRepository.CreateOrUseExisting(f.Path, _progress); var address = new HttpRepositoryPath("default", _cloneableTestProjectUrl, false); repo.Pull(address, _cloneableTestProjectUrl); Assert.IsTrue(Directory.Exists(f.Combine(f.Path, ".hg"))); } }
/// <summary> /// Initialize system with user's name. /// </summary> /// <param name="userNameForHistoryAndNotes">This is not the same name as that used for any given network /// repository credentials. Rather, it's the name which will show in the history, and besides Notes that this user makes. ///</param> public void Init(string userNameForHistoryAndNotes) { Repository = HgRepository.CreateOrUseExisting(_dataFolderPath, new NullProgress()); var builder = InitContainerBuilder(); if (String.IsNullOrEmpty(userNameForHistoryAndNotes)) { userNameForHistoryAndNotes = Repository.GetUserIdInUse(); } FinishInit(userNameForHistoryAndNotes, builder); }
/// <summary> /// Save the settings in the folder's .hg, creating the folder and settings if necessary. /// This is only available if you previously called InitFromProjectPath(). It isn't used /// in the GetCloneFromInternet scenario. /// </summary> public void SaveSettings() { if (string.IsNullOrEmpty(_pathToRepo)) { throw new ArgumentException("SaveSettings() only works if you InitFromProjectPath()"); } var repo = HgRepository.CreateOrUseExisting(_pathToRepo, new NullProgress()); // Use safer SetTheOnlyAddressOfThisType method, as it won't clobber a shared network setting, if that was the clone source. repo.SetTheOnlyAddressOfThisType(new HttpRepositoryPath(AliasName, URL, false)); }
public void AddingRepositoryWithinAnotherRepositoryWithNullDirectoryThrows() { using (var tempParent = new TemporaryFolder("ChorusParent")) { var parentRepo = new HgRepository(tempParent.Path, new NullProgress()); parentRepo.Init(); var parentFile = tempParent.GetNewTempFile(true); File.WriteAllText(parentFile.Path, "New Content"); parentRepo.AddAndCheckinFile(parentFile.Path); Assert.Throws <ArgumentNullException>(() => HgRepository.CreateOrUseExisting(null, new NullProgress())); } }
public void GetRepostoryNames_TwoItemsInHubFolder_GetOneItemWithProjectFilter() { // only accept folders containing a file with the name "randomName.someExt" const string queryString = "filePattern=*.someExt"; using (var testRoot = new TemporaryFolder("ChorusHubCloneTest_" + Guid.NewGuid())) using (var chorusHubSourceFolder = new TemporaryFolder(testRoot, "ChorusHub")) using (var repo1 = new TemporaryFolder(chorusHubSourceFolder, "repo1")) using (var tempFile = TempFile.WithExtension("someExt")) using (var repo2 = new TemporaryFolder(chorusHubSourceFolder, "repo2")) using (var tempFile2 = TempFile.WithExtension("someOtherExt")) { tempFile.MoveTo(Path.Combine(repo1.Path, Path.GetFileName(tempFile.Path))); using (var writer = new StreamWriter(tempFile.Path)) writer.Write("Some random text."); tempFile2.MoveTo(Path.Combine(repo2.Path, Path.GetFileName(tempFile2.Path))); RepositorySetup.MakeRepositoryForTest(repo1.Path, "bob", new ConsoleProgress()); RepositorySetup.MakeRepositoryForTest(repo2.Path, "bob", new ConsoleProgress()); var r1 = HgRepository.CreateOrUseExisting(repo1.Path, new ConsoleProgress()); r1.AddAndCheckinFile(tempFile.Path); // need this to create store/data/files var r2 = HgRepository.CreateOrUseExisting(repo2.Path, new ConsoleProgress()); r2.AddAndCheckinFile(tempFile2.Path); // need this to create store/data/files ChorusHubOptions.RootDirectory = chorusHubSourceFolder.Path; using (var service = new ChorusHubServer()) { Assert.IsTrue(service.Start(true)); var chorusHubServerInfo = ChorusHubServerInfo.FindServerInformation(); Assert.NotNull(chorusHubServerInfo); // Make sure all repos are there first var client1 = new ChorusHubClient(chorusHubServerInfo); var allRepoInfo = client1.GetRepositoryInformation(string.Empty); Assert.AreEqual(2, allRepoInfo.Count()); Assert.IsTrue(allRepoInfo.Select(ri => ri.RepoName.Contains("repo2")).Any()); // Make sure filter works // In order to have a hope of getting a different result to GetRepositoryInformation // we have to start over with a new client chorusHubServerInfo = ChorusHubServerInfo.FindServerInformation(); Assert.NotNull(ChorusHubServerInfo.FindServerInformation()); var client2 = new ChorusHubClient(chorusHubServerInfo); var repoInfo = client2.GetRepositoryInformation(queryString); Assert.AreEqual(1, repoInfo.Count()); var info = repoInfo.First(); Assert.IsTrue(info.RepoName == "repo1"); } } }
public void DefaultUrlsAreIgnored() { using (var folder = new TemporaryFolder("ServerSettingsModel")) { var original = HgRepository.CreateOrUseExisting(folder.Path, new NullProgress()); original.SetKnownRepositoryAddresses(new[] { new HttpRepositoryPath("default", "c://abc.com", false) }); var m = new ServerSettingsModel(); const string url = "unclickable://hg-private.languageforge.org/tpi"; m.InitFromProjectPath(folder.Path); m.SetUrlToUseIfSettingsAreEmpty(url); Assert.AreEqual(url, m.URL); } }
public void GetRepostoryNames_ThreeItemsInHubFolder_GetTwoItemsWithProjectFilter() { // only accept folders containing a file with the name "randomName.ext1" or "randomName.Ext2" const string queryString = @"filePattern=*.ext1|*.Ext2"; using (var testRoot = new TemporaryFolder("ChorusHubCloneTest_" + Guid.NewGuid())) using (var chorusHubSourceFolder = new TemporaryFolder(testRoot, "ChorusHub")) using (var repo1 = new TemporaryFolder(chorusHubSourceFolder, "repo1")) using (var tempFile1 = TempFile.WithExtension("ext1")) using (var repo2 = new TemporaryFolder(chorusHubSourceFolder, "repo2")) using (var tempFile2 = TempFile.WithExtension("unwanted")) using (var repo3 = new TemporaryFolder(chorusHubSourceFolder, "repo3")) using (var tempFile3 = TempFile.WithExtension("Ext2")) { tempFile1.MoveTo(Path.Combine(repo1.Path, Path.GetFileName(tempFile1.Path))); using (var writer = new StreamWriter(tempFile1.Path)) writer.Write("Some random text."); tempFile2.MoveTo(Path.Combine(repo2.Path, Path.GetFileName(tempFile2.Path))); tempFile3.MoveTo(Path.Combine(repo3.Path, Path.GetFileName(tempFile3.Path))); RepositorySetup.MakeRepositoryForTest(repo1.Path, "bob", new ConsoleProgress()); RepositorySetup.MakeRepositoryForTest(repo2.Path, "bob", new ConsoleProgress()); RepositorySetup.MakeRepositoryForTest(repo3.Path, "bob", new ConsoleProgress()); var r1 = HgRepository.CreateOrUseExisting(repo1.Path, new ConsoleProgress()); r1.AddAndCheckinFile(tempFile1.Path); // need this to create store/data/files var r2 = HgRepository.CreateOrUseExisting(repo2.Path, new ConsoleProgress()); r2.AddAndCheckinFile(tempFile2.Path); // need this to create store/data/files var r3 = HgRepository.CreateOrUseExisting(repo3.Path, new ConsoleProgress()); r3.AddAndCheckinFile(tempFile3.Path); // need this to create store/data/files ChorusHubOptions.RootDirectory = chorusHubSourceFolder.Path; using (var service = new ChorusHubServer()) { Assert.IsTrue(service.Start(true)); // Make sure filter works var chorusHubServerInfo = ChorusHubServerInfo.FindServerInformation(); Assert.NotNull(chorusHubServerInfo); var client = new ChorusHubClient(chorusHubServerInfo); var repoInfo = client.GetRepositoryInformation(queryString); Assert.AreEqual(2, repoInfo.Count()); var info1 = repoInfo.First(); var info2 = repoInfo.Last(); Assert.IsTrue(info1.RepoName == "repo1"); Assert.IsTrue(info2.RepoName == "repo3"); } } }
public void SetUrlToUseIfSettingsAreEmpty_RepoAlreadyExistsWithAServerAddress_IgnoresOfferedUrl() { using (var folder = new TemporaryFolder("ServerSettingsModel")) { var original = HgRepository.CreateOrUseExisting(folder.Path, new NullProgress()); var existing = "https://abc.com"; original.SetKnownRepositoryAddresses(new[] { new HttpRepositoryPath("languageforge.org [Safe Mode]", existing, false) }); var m = new ServerSettingsModel(); var url = "https://*****:*****@hg-public.languageforge.org/tpi"; m.InitFromProjectPath(folder.Path); m.SetUrlToUseIfSettingsAreEmpty(url); Assert.AreEqual(existing, m.URL); } }
public void PullThenPush_Test() { // RobustNetworkOperation.ClearCredentialSettings(); using (var f = new TemporaryFolder("pulltest")) { var repo = HgRepository.CreateOrUseExisting(f.Path, _progress); var address = new HttpRepositoryPath("default", _cloneableTestProjectUrl, false); repo.Pull(address, _cloneableTestProjectUrl); Assert.IsTrue(Directory.Exists(f.Combine(f.Path, ".hg"))); //nb: this is safe to do over an over, because it will just say "no changes found", never actually add a changeset repo.Push(address, _cloneableTestProjectUrl); } }
public void AddingRepositoryWithinAnotherRepositoryWithNonexistantFileThrows() { using (var tempParent = new TemporaryFolder("ChorusParent")) { var parentRepo = new HgRepository(tempParent.Path, new NullProgress()); parentRepo.Init(); var parentFile = tempParent.GetNewTempFile(true); File.WriteAllText(parentFile.Path, "New Content"); parentRepo.AddAndCheckinFile(parentFile.Path); var parentFolder = tempParent.Path; var nonexistantFile = Path.Combine(parentFolder, "bogusfile.txt"); Assert.Throws <InvalidOperationException>(() => HgRepository.CreateOrUseExisting(nonexistantFile, new NullProgress())); } }
public delegate SyncDialog Factory(SyncUIDialogBehaviors behavior, SyncUIFeatures uiFeatureFlags); //autofac uses this public SyncDialog(ProjectFolderConfiguration projectFolderConfiguration, SyncUIDialogBehaviors behavior, SyncUIFeatures uiFeatureFlags) { InitializeComponent(); try { Behavior = behavior; _syncControl.Model = new SyncControlModel(projectFolderConfiguration, uiFeatureFlags, null /*to do*/); AcceptButton = _syncControl._cancelButton; // CancelButton = _syncControl._cancelOrCloseButton; _syncControl.Model.SynchronizeOver += new EventHandler(_syncControl_SynchronizeOver); //we don't want clients digging down this deeply, so we present it as one of our properties FinalStatus = _syncControl.Model.StatusProgress; //set the default based on whether this looks like a backup or local commit operation UseTargetsAsSpecifiedInSyncOptions = (Behavior == SyncUIDialogBehaviors.StartImmediately || Behavior == SyncUIDialogBehaviors.StartImmediatelyAndCloseWhenFinished); //in case the user cancels before the sync and the client doesn't check to see if the result is null if ((uiFeatureFlags & SyncUIFeatures.SimpleRepositoryChooserInsteadOfAdvanced) == SyncUIFeatures.SimpleRepositoryChooserInsteadOfAdvanced) { SyncResult = new SyncResults(); SyncResult.Succeeded = false; _syncStartControl.Init(HgRepository.CreateOrUseExisting(projectFolderConfiguration.FolderPath, new NullProgress())); _syncControl.Dock = DockStyle.Fill; //in designer, we don't want it to cover up everything, but we do at runtime _syncStartControl.Visible = true; _syncControl.Visible = false; Height = _syncStartControl.DesiredHeight; } else { _syncStartControl.Visible = false; _syncControl.Visible = true; Height = _syncControl.DesiredHeight; } ResumeLayout(true); this.Text = string.Format("Send/Receive ({0})", _syncControl.Model.UserName); } catch (Exception) { _syncStartControl.Dispose(); //without this, the usbdetector just goes on and on throw; } }
public void AddingRepositoryWithinAnotherRepositoryFromDirectoryNameIsDifferentRepository() { using (var tempParent = new TemporaryFolder("ChorusParent")) { var parentRepo = new HgRepository(tempParent.Path, new NullProgress()); parentRepo.Init(); var parentFile = tempParent.GetNewTempFile(true); File.WriteAllText(parentFile.Path, "New Content"); parentRepo.AddAndCheckinFile(parentFile.Path); var parentFolder = tempParent.Path; var dirInfo = Directory.CreateDirectory(Path.Combine(parentFolder, "Child")); var childRepo = HgRepository.CreateOrUseExisting(dirInfo.FullName, new NullProgress()); Assert.AreNotEqual(parentFolder, childRepo.PathToRepo); } }
///<summary> /// Show settings for an existing project. The project doesn't need to have any /// previous chorus activity (e.g. no .hg folder is needed). ///</summary> public virtual void InitFromProjectPath(string path) { RequireThat.Directory(path).Exists(); var repo = HgRepository.CreateOrUseExisting(path, new NullProgress()); _pathToRepo = repo.PathToRepo; var address = repo.GetDefaultNetworkAddress <HttpRepositoryPath>(); if (address != null) { InitFromUri(address.URI); } //otherwise, just leave everything in the default state }
public void SaveSettings_NoHgFolderExists_CreatesOneWithCorrectPath() { using (var folder = new TemporaryFolder("ServerSettingsModel")) { var m = new ServerSettingsModel(); var url = "http://*****:*****@hg-public.languagedepot.org/tpi"; m.InitFromProjectPath(folder.Path); m.SetUrlToUseIfSettingsAreEmpty(url); m.SaveSettings(); Assert.IsTrue(Directory.Exists(folder.Combine(".hg"))); Assert.IsTrue(File.Exists(folder.Combine(".hg", "hgrc"))); var repo = HgRepository.CreateOrUseExisting(folder.Path, new NullProgress()); var address = repo.GetDefaultNetworkAddress <HttpRepositoryPath>(); Assert.AreEqual("languageDepot.org[safemode]".ToLower(), address.Name.ToLower()); Assert.AreEqual(url, address.URI); } }
private static bool HasRepo(string dirName, out string jsonRepoInfo) { jsonRepoInfo = null; var hgDir = Path.Combine(dirName, HgFolder); if (!Directory.Exists(hgDir)) { return(false); } var repo = HgRepository.CreateOrUseExisting(dirName, new ConsoleProgress()); var id = repo.Identifier; var name = Path.GetFileName(dirName); if (id == null) { id = RepositoryInformation.NEW_REPO; } jsonRepoInfo = ImitationHubJSONService.MakeJsonString(name, id); return(true); }
public SendReceiveSettings(string repositoryLocation) { InitializeComponent(); RequireThat.Directory(repositoryLocation).Exists(); var repository = HgRepository.CreateOrUseExisting(repositoryLocation, new NullProgress()); _model = new SettingsModel(repository); userNameTextBox.Text = _model.GetUserName(new NullProgress()); _internetModel = new ServerSettingsModel(); _internetModel.InitFromProjectPath(repositoryLocation); _serverSettingsControl.Model = _internetModel; _internetButtonEnabledCheckBox.CheckedChanged += internetCheckChanged; _internetButtonEnabledCheckBox.Checked = Properties.Settings.Default.InternetEnabled; _serverSettingsControl.Enabled = _internetButtonEnabledCheckBox.Checked; _showChorusHubInSendReceive.Checked = Properties.Settings.Default.ShowChorusHubInSendReceive; }
public void SaveSettings_PrexistsButWeChangePasswordAndSave_ChangesPassword() { using (var folder = new TemporaryFolder("ServerSettingsModel")) { // Precondition is some url that is not our default from the ServerSettingsModel var original = HgRepository.CreateOrUseExisting(folder.Path, new NullProgress()); original.SetKnownRepositoryAddresses(new[] { new HttpRepositoryPath("languagedepot.org [legacy sync]", "http://*****:*****@hg-public.languagedepot.org/tpi", false) }); var m = new ServerSettingsModel(); m.InitFromProjectPath(folder.Path); m.Password = "******"; m.SaveSettings(); Assert.IsTrue(Directory.Exists(folder.Combine(".hg"))); Assert.IsTrue(File.Exists(folder.Combine(".hg", "hgrc"))); var repo = HgRepository.CreateOrUseExisting(folder.Path, new NullProgress()); var address = repo.GetDefaultNetworkAddress <HttpRepositoryPath>(); Assert.AreEqual("http://*****:*****@hg-public.languagedepot.org/tpi", address.URI); Assert.AreEqual("newPassword", address.Password); } }
public void SaveSettings_ForgetsPassword() { ServerSettingsModel.PasswordForSession = null; using (var folder = new TemporaryFolder("ServerSettingsModel")) { const string user = "******"; const string pass = "******"; var m = new ServerSettingsModel { Username = user, Password = pass, RememberPassword = false }; m.InitFromProjectPath(folder.Path); m.SaveSettings(); Assert.AreEqual(user, Settings.Default.LanguageForgeUser); Assert.Null(Settings.Default.LanguageForgePass); Assert.AreEqual(pass, ServerSettingsModel.PasswordForSession); var repo = HgRepository.CreateOrUseExisting(folder.Path, new NullProgress()); var address = repo.GetDefaultNetworkAddress <HttpRepositoryPath>(); Assert.That(address.URI, Does.Not.Contain(pass)); } }
public void SaveSettings_NoHgFolderExists_CreatesOneWithCorrectPath() { using (var folder = new TemporaryFolder("ServerSettingsModel")) { const string user = "******"; const string pass = "******"; const string host = "hg-public.languageforge.org/tpi"; const string url = "https://" + user + ":" + pass + "@" + host; var m = new ServerSettingsModel(); m.InitFromProjectPath(folder.Path); m.SetUrlToUseIfSettingsAreEmpty(url); m.SaveSettings(); Assert.That(folder.Combine(".hg"), Does.Exist); Assert.That(folder.Combine(".hg", "hgrc"), Does.Exist); var repo = HgRepository.CreateOrUseExisting(folder.Path, new NullProgress()); var address = repo.GetDefaultNetworkAddress <HttpRepositoryPath>(); Assert.AreEqual(new ServerSettingsModel.BandwidthItem(ServerSettingsModel.BandwidthEnum.High), m.Bandwidth); Assert.AreEqual("https://" + host, address.URI); Assert.AreEqual(user, m.Username); Assert.AreEqual(pass, m.Password); } }
public void GetRepostoryNames_TwoItemsInHubFolder_GetNoneForProjectFilter() { // only accept folders containing a file with the name "randomName.ext1" // but there aren't any. const string queryString = "filePattern=*.ext1"; using (var testRoot = new TemporaryFolder("ChorusHubCloneTest_" + Guid.NewGuid())) using (var chorusHubSourceFolder = new TemporaryFolder(testRoot, "ChorusHub")) using (var repo1 = new TemporaryFolder(chorusHubSourceFolder, "repo1")) using (var tempFile1 = TempFile.WithExtension("other")) using (var repo2 = new TemporaryFolder(chorusHubSourceFolder, "repo2")) using (var tempFile2 = TempFile.WithExtension("unwanted")) { tempFile1.MoveTo(Path.Combine(repo1.Path, Path.GetFileName(tempFile1.Path))); using (var writer = new StreamWriter(tempFile1.Path)) writer.Write("Some random text."); // Does it work if the file is empty? tempFile2.MoveTo(Path.Combine(repo2.Path, Path.GetFileName(tempFile2.Path))); RepositorySetup.MakeRepositoryForTest(repo1.Path, "bob", new ConsoleProgress()); RepositorySetup.MakeRepositoryForTest(repo2.Path, "bob", new ConsoleProgress()); var r1 = HgRepository.CreateOrUseExisting(repo1.Path, new ConsoleProgress()); r1.AddAndCheckinFile(tempFile1.Path); // need this to create store/data/files var r2 = HgRepository.CreateOrUseExisting(repo2.Path, new ConsoleProgress()); r2.AddAndCheckinFile(tempFile2.Path); // need this to create store/data/files ChorusHubOptions.RootDirectory = chorusHubSourceFolder.Path; using (var service = new ChorusHubServer()) { Assert.That(service.Start(true), Is.True); // Make sure filter works var chorusHubServerInfo = ChorusHubServerInfo.FindServerInformation(); Assert.NotNull(chorusHubServerInfo); var client = new ChorusHubClient(chorusHubServerInfo); var repositoryInfo = client.GetRepositoryInformation(queryString); Assert.AreEqual(0, repositoryInfo.Count()); } } }
public static void Inject(ContainerBuilder builder, string projectPath, SyncUIFeatures syncDialogFeatures) { //TODO: shouldn't we have people provide the whole project configuration? Otherwise, we have an empty set of //include/exlcude patterns, so new files aren't going to get added. Maybe if we're going to do that, it //doesn't make sense for this to do the injecting at all... maybe the client should do it. Similar issue //below, with SyncUIFeatures builder.Register <ProjectFolderConfiguration>( c => new ProjectFolderConfiguration(projectPath)).InstancePerLifetimeScope(); builder.RegisterType <NavigateToRecordEvent>().InstancePerLifetimeScope(); builder.RegisterInstance(new NullProgress()).As <IProgress>(); builder.Register <Synchronizer>(c => Chorus.sync.Synchronizer.FromProjectConfiguration( c.Resolve <ProjectFolderConfiguration>(), new NullProgress())); builder.Register <HgRepository>(c => HgRepository.CreateOrUseExisting(projectPath, new NullProgress())).InstancePerLifetimeScope(); //this is a sad hack... I don't know how to simly override the default using the container, //which I'd rather do, and just leave this to pushing in the "normal" builder.Register <SyncUIFeatures>(c => syncDialogFeatures).As <SyncUIFeatures>().SingleInstance(); builder.RegisterInstance(new EmbeddedMessageContentHandlerRepository()); builder.RegisterInstance(ChorusFileTypeHandlerCollection.CreateWithInstalledHandlers()).SingleInstance(); builder.RegisterType <SyncPanel>().InstancePerLifetimeScope(); builder.RegisterType <SyncControlModel>().InstancePerLifetimeScope(); builder.RegisterType <SyncDialog>().InstancePerDependency(); //NB: was FactoryScoped() before switch to autofac 2, which corresponds to this InstancePerDependency builder.RegisterGeneratedFactory <SyncDialog.Factory>().InstancePerLifetimeScope(); builder.RegisterType <Chorus.UI.Misc.TroubleshootingView>().InstancePerLifetimeScope(); RegisterSyncStuff(builder); RegisterReviewStuff(builder); RegisterSettingsStuff(builder); InjectNotesUI(builder); }
public void GetRepostoryNames_TwoItemsInHubFolder_GetTwoItems() { using (var testRoot = new TemporaryFolder("ChorusHubCloneTest_" + Guid.NewGuid())) using (var chorusHubSourceFolder = new TemporaryFolder(testRoot, "ChorusHub")) using (var repo1 = new TemporaryFolder(chorusHubSourceFolder, "repo1")) using (var tempFile1 = TempFile.WithExtension("ext1")) using (var repo2 = new TemporaryFolder(chorusHubSourceFolder, "repo2")) using (var tempFile2 = TempFile.WithExtension("ext2")) { tempFile1.MoveTo(Path.Combine(repo1.Path, Path.GetFileName(tempFile1.Path))); tempFile2.MoveTo(Path.Combine(repo2.Path, Path.GetFileName(tempFile2.Path))); RepositorySetup.MakeRepositoryForTest(repo1.Path, "bob", new ConsoleProgress()); RepositorySetup.MakeRepositoryForTest(repo2.Path, "bob", new ConsoleProgress()); var r1 = HgRepository.CreateOrUseExisting(repo1.Path, new ConsoleProgress()); r1.AddAndCheckinFile(tempFile1.Path); // need this to create store/data/files var r2 = HgRepository.CreateOrUseExisting(repo2.Path, new ConsoleProgress()); r2.AddAndCheckinFile(tempFile2.Path); // need this to create store/data/files ChorusHubOptions.RootDirectory = chorusHubSourceFolder.Path; using (var service = new ChorusHubServer()) { // hg server side is now involved in deciding what repos are available Assert.IsTrue(service.Start(true)); var chorusHubServerInfo = ChorusHubServerInfo.FindServerInformation(); Assert.NotNull(chorusHubServerInfo); var client = new ChorusHubClient(chorusHubServerInfo); var repoInfo = client.GetRepositoryInformation(string.Empty); Assert.AreEqual(2, repoInfo.Count()); var info1 = repoInfo.First(); var info2 = repoInfo.Last(); Assert.IsTrue(info1.RepoName == "repo1"); Assert.IsTrue(info2.RepoName == "repo2"); } } }
public void TipUpdatedPostMerge() { ConsoleProgress progress = new ConsoleProgress(); BobSetup bobSetup = new BobSetup(progress, _pathToTestRoot); var bobSynchronizer = bobSetup.GetSynchronizer(); //set up two branches to trigger issue SetAdjunctModelVersion(bobSynchronizer, "notdefault"); // Bob is on 'default' branch bobSetup.ChangeTextFile(bobSynchronizer); //Ok, this is unrealistic, but we just clone Bob onto Sally var hubRoot = Path.Combine(_pathToTestRoot, "Hub"); var sallyMachineRoot = Path.Combine(_pathToTestRoot, "sally"); Directory.CreateDirectory(sallyMachineRoot); Directory.CreateDirectory(hubRoot); var sallyProjectRoot = bobSetup.SetupClone(sallyMachineRoot); var hubProjectRoot = bobSetup.SetupClone(hubRoot); var sallyProject = BobSetup.CreateFolderConfig(sallyProjectRoot); var hubProject = BobSetup.CreateFolderConfig(hubProjectRoot); var repository = HgRepository.CreateOrUseExisting(sallyProject.FolderPath, progress); repository.SetUserNameInIni("sally", progress); // bob makes a change and syncs File.WriteAllText(bobSetup._pathToLift, LiftFileStrings.lift12Dog); var bobOptions = new SyncOptions { CheckinDescription = "added 'dog'", DoMergeWithOthers = true, DoSendToOthers = true, DoPullFromOthers = true }; bobOptions.RepositorySourcesToTry.Add(RepositoryAddress.Create("Hub", hubProject.FolderPath, false)); //now Sally modifies the original file, not having seen Bob's changes yet var sallyPathToLift = Path.Combine(sallyProject.FolderPath, Path.Combine("lexicon", "foo.lift")); File.WriteAllText(sallyPathToLift, LiftFileStrings.lift12Cat); //Sally syncs, pulling in Bob's change, and encountering a need to merge (no conflicts) var sallyOptions = new SyncOptions { CheckinDescription = "adding cat", DoPullFromOthers = true, DoSendToOthers = true, DoMergeWithOthers = true }; sallyOptions.RepositorySourcesToTry.Add(RepositoryAddress.Create("Hub", hubProject.FolderPath, false)); var sallySyncer = Synchronizer.FromProjectConfiguration(sallyProject, progress); SetAdjunctModelVersion(sallySyncer, "notdefault"); sallySyncer.SyncNow(sallyOptions); bobSynchronizer.SyncNow(bobOptions); // bob makes a change and syncs File.WriteAllText(bobSetup._pathToLift, LiftFileStrings.lift12DogAnt); bobSynchronizer.SyncNow(bobOptions); sallyOptions.DoSendToOthers = false; sallySyncer.SyncNow(sallyOptions); //Debug.WriteLine("bob's: " + File.ReadAllText(bobSetup._pathToLift)); var contents = File.ReadAllText(sallyPathToLift); //Debug.WriteLine("sally's: " + contents); Assert.That(contents, Does.Contain("ant")); Assert.That(contents, Does.Contain("dog")); }
[Category("KnownMonoIssue")] // Actually, it is an unknown mono issue. public void TestNewVersion_SallyUpgradesToBobVersion() { ConsoleProgress progress = new ConsoleProgress(); BobSetup bobSetup = new BobSetup(progress, _pathToTestRoot); bobSetup.ChangeTextFile(); //Ok, this is unrealistic, but we just clone Bob onto Sally string sallyMachineRoot = Path.Combine(_pathToTestRoot, "sally"); Directory.CreateDirectory(sallyMachineRoot); string sallyProjectRoot = bobSetup.SetupClone(sallyMachineRoot); ProjectFolderConfiguration sallyProject = new ProjectFolderConfiguration(sallyProjectRoot); sallyProject.IncludePatterns.Add("**.abc"); sallyProject.IncludePatterns.Add("**.lift"); var repository = HgRepository.CreateOrUseExisting(sallyProject.FolderPath, progress); repository.SetUserNameInIni("sally", progress); // bob makes a change and syncs File.WriteAllText(bobSetup._pathToLift, LiftFileStrings.lift12Dog); var bobOptions = GetFullSyncOptions("added dog"); bobOptions.DoMergeWithOthers = false; // just want a fast checkin bobOptions.DoSendToOthers = false; // just want a fast checkin bobOptions.DoPullFromOthers = false; // just want a fast checkin var bobsyncer = bobSetup.GetSynchronizer(); SetAdjunctModelVersion(bobsyncer, "LIFT0.12"); // Bob is still on an older branch bobsyncer.SyncNow(bobOptions); // bob makes another change and syncs File.WriteAllText(bobSetup._pathToLift, LiftFileStrings.lift13DogHerring); bobOptions.CheckinDescription = "added 'herring'"; // still just want a fast checkin SetAdjunctModelVersion(bobsyncer, "LIFT0.13"); // Bob is now on a new branch bobsyncer.SyncNow(bobOptions); //now Sally modifies the original file, not having seen Bob's changes yet var sallyPathToLift = Path.Combine(sallyProject.FolderPath, "lexicon/foo.lift"); File.WriteAllText(sallyPathToLift, LiftFileStrings.lift12Cat); //Sally syncs, pulling in Bob's 1st change, and encountering a need to merge (no conflicts) var sallyOptions = GetFullSyncOptions("adding cat"); sallyOptions.RepositorySourcesToTry.Add(RepositoryAddress.Create("bob's machine", bobSetup.BobProjectPath, false)); var synchronizer = Synchronizer.FromProjectConfiguration(sallyProject, progress); SetAdjunctModelVersion(synchronizer, "LIFT0.12"); // Sally is still on the initial branch // SUT synchronizer.SyncNow(sallyOptions); // Verification stage 1 var bobContents = File.ReadAllText(bobSetup._pathToLift); Assert.That(bobContents, Does.Not.Contain("cat"), "'cat' should only be on Sally's branch."); Assert.That(bobContents, Does.Contain("dog")); var sallyContents = File.ReadAllText(sallyPathToLift); Assert.That(sallyContents, Does.Contain("cat")); Assert.That(sallyContents, Does.Contain("dog"), "Sally should have merged in older branch to hers."); Assert.That(sallyContents, Does.Not.Contain("herring"), "The red herring is only in Bob's repo; 2nd branch."); // Now Sally upgrades her LIFT-capable program to Bob's version! File.WriteAllText(sallyPathToLift, LiftFileStrings.lift13PigDogCat); //Sally syncs, pulling in Bob's change, and encountering a need to merge (no conflicts) sallyOptions = GetFullSyncOptions("adding pig"); const string lift13version = "LIFT0.13"; SetAdjunctModelVersion(synchronizer, lift13version); // Sally updates to the new version (branch) synchronizer.SyncNow(sallyOptions); bobOptions.DoPullFromOthers = true; bobOptions.RepositorySourcesToTry.Add(RepositoryAddress.Create("sally's machine", sallyProjectRoot, false)); // SUT bobsyncer.SyncNow(bobOptions); // Verification stage 2 bobContents = File.ReadAllText(bobSetup._pathToLift); //Debug.Print("Bob's: " + bobContents); Assert.That(bobContents, Does.Contain("cat"), "'cat' survived the upgrade to Bob's repo."); Assert.That(bobContents, Does.Contain("dog")); Assert.That(bobContents, Does.Contain("pig"), "'pig' survived the upgrade to Bob's repo."); sallyContents = File.ReadAllText(sallyPathToLift); //Debug.Print("Sally's: " + sallyContents); Assert.That(sallyContents, Does.Contain("cat")); Assert.That(sallyContents, Does.Contain("dog"), "'dog' should be from Bob's older repo."); Assert.That(sallyContents, Does.Contain("herring"), "Now we should have everything from Bob's repo."); Assert.That(sallyContents, Does.Contain("pig"), "'pig' should have survived the upgrade."); // Verify Bob is on the latest branch string dummy; var result = bobsyncer.Repository.BranchingHelper.IsLatestBranchDifferent(lift13version, out dummy); Assert.That(result, Is.False, "Bob should be on the latest LIFT0.13 branch."); // Verify Sally is on the right branch result = synchronizer.Repository.BranchingHelper.IsLatestBranchDifferent(lift13version, out dummy); Assert.That(result, Is.False, "Sally should be on the latest LIFT0.13 branch."); }
public void TestNewVersion_SallyAndBobUpgradeButFredDelays() { ConsoleProgress progress = new ConsoleProgress(); BobSetup bobSetup = new BobSetup(progress, _pathToTestRoot); // clone Bob onto Sally string sallyMachineRoot = Path.Combine(_pathToTestRoot, "sally"); Directory.CreateDirectory(sallyMachineRoot); string sallyProjectRoot = bobSetup.SetupClone(sallyMachineRoot); ProjectFolderConfiguration sallyProject = new ProjectFolderConfiguration(sallyProjectRoot); sallyProject.IncludePatterns.Add("**.abc"); sallyProject.IncludePatterns.Add("**.lift"); // clone Bob onto Fred string fredMachineRoot = Path.Combine(_pathToTestRoot, "fred"); Directory.CreateDirectory(fredMachineRoot); string fredProjectRoot = bobSetup.SetupClone(fredMachineRoot); ProjectFolderConfiguration fredProject = new ProjectFolderConfiguration(fredProjectRoot); fredProject.IncludePatterns.Add("**.abc"); fredProject.IncludePatterns.Add("**.lift"); // Setup Sally and Fred repositories var sallyRepository = HgRepository.CreateOrUseExisting(sallyProject.FolderPath, progress); sallyRepository.SetUserNameInIni("sally", progress); var fredRepository = HgRepository.CreateOrUseExisting(fredProject.FolderPath, progress); fredRepository.SetUserNameInIni("fred", progress); var sallyRepoAddress = RepositoryAddress.Create("sally's machine", sallyProjectRoot, false); var fredRepoAddress = RepositoryAddress.Create("fred's machine", fredProjectRoot, false); var bobRepoAddress = RepositoryAddress.Create("bob's machine", bobSetup.BobProjectPath, false); // bob makes a change and syncs to everybody File.WriteAllText(bobSetup._pathToLift, LiftFileStrings.lift12Dog); var bobOptions = GetFullSyncOptions("added 'dog'"); bobOptions.RepositorySourcesToTry.Add(sallyRepoAddress); bobOptions.RepositorySourcesToTry.Add(fredRepoAddress); var bobSyncer = bobSetup.GetSynchronizer(); bobSyncer.SyncNow(bobOptions); // Bob syncs with everybody on 'default' branch // Verification Step 1 var sallyPathToLift = Path.Combine(sallyProject.FolderPath, "lexicon/foo.lift"); var fredPathToLift = Path.Combine(fredProject.FolderPath, "lexicon/foo.lift"); var sallyContents = File.ReadAllText(sallyPathToLift); Assert.That(sallyContents, Does.Contain("dog"), "'dog' should be in Sally repo."); var fredContents = File.ReadAllText(fredPathToLift); Assert.That(fredContents, Does.Contain("dog"), "'dog' should be in Fred repo."); // bob makes another change and syncs to new version File.WriteAllText(bobSetup._pathToLift, LiftFileStrings.lift13DogCat); var newBobOptions = GetFullSyncOptions("added 'cat'"); newBobOptions.DoMergeWithOthers = false; // just want a fast checkin newBobOptions.DoPullFromOthers = false; // just want a fast checkin newBobOptions.DoSendToOthers = false; // just want a fast checkin const string lift13version = "LIFT0.13"; SetAdjunctModelVersion(bobSyncer, lift13version); // Bob is now on the new version of LIFT bobSyncer.SyncNow(newBobOptions); // now Fred modifies default branch to add 'ant' File.WriteAllText(fredPathToLift, LiftFileStrings.lift12DogAnt); var fredOptions = GetFullSyncOptions("added 'ant'"); fredOptions.RepositorySourcesToTry.Add(bobRepoAddress); fredOptions.RepositorySourcesToTry.Add(sallyRepoAddress); var fredSyncer = Synchronizer.FromProjectConfiguration(fredProject, progress); fredSyncer.SyncNow(fredOptions); // Verification Step 2 fredContents = File.ReadAllText(fredPathToLift); Assert.That(fredContents, Does.Not.Contain("cat"), "'cat' should only be on Bob's branch."); Assert.That(fredContents, Does.Contain("ant")); sallyContents = File.ReadAllText(sallyPathToLift); Assert.That(sallyContents, Does.Contain("ant"), "'ant' was propogated to Sally's branch."); Assert.That(sallyContents, Does.Not.Contain("cat"), "'cat' should only be on Bob's branch."); var bobContents = File.ReadAllText(bobSetup._pathToLift); Assert.That(bobContents, Does.Not.Contain("ant"), "'ant' is only on 'default' branch."); // Verify Bob is on the latest branch string dummy; var result = bobSyncer.Repository.BranchingHelper.IsLatestBranchDifferent(lift13version, out dummy); Assert.That(result, Is.False, "Bob should be on the new LIFT0.13 branch."); // And Fred isn't result = fredSyncer.Repository.BranchingHelper.IsLatestBranchDifferent(lift13version, out dummy); Assert.That(result, Is.True, "Fred should still be on the 'default' branch."); // Now Sally modifies the file, not having seen Bob's changes yet, but having seen Fred's changes. // She adds 'herring' and has upgraded to Bob's version of LIFT File.WriteAllText(sallyPathToLift, LiftFileStrings.lift13DogAntHerring); //Sally syncs, pulling in Bob's 1st change, and encountering a need to merge (no conflicts) var sallyOptions = GetFullSyncOptions("adding 'herring'"); sallyOptions.RepositorySourcesToTry.Add(bobRepoAddress); sallyOptions.RepositorySourcesToTry.Add(fredRepoAddress); // Why not? Even though he's still on 'default' branch var sallySyncer = Synchronizer.FromProjectConfiguration(sallyProject, progress); SetAdjunctModelVersion(sallySyncer, lift13version); // Sally is now on the Bob's later version // Below is the line with the hg error sallySyncer.SyncNow(sallyOptions); // Verification Step 3 bobContents = File.ReadAllText(bobSetup._pathToLift); Assert.That(bobContents, Does.Contain("herring"), "'herring' should be pulled in from Sally's branch."); Assert.That(bobContents, Does.Contain("ant"), "'ant' should be pulled in from Sally's branch."); sallyContents = File.ReadAllText(sallyPathToLift); Assert.That(sallyContents, Does.Contain("cat"), "'cat' should be pulled in from Bob's branch."); Assert.That(sallyContents, Does.Contain("dog"), "Everybody should have 'dog' from before."); fredContents = File.ReadAllText(fredPathToLift); Assert.That(fredContents, Does.Not.Contain("herring"), "The red herring is only in the new version for now."); Assert.That(fredContents, Does.Not.Contain("cat"), "'cat' is only in the new version for now."); // Verify Sally is now on the latest branch result = sallySyncer.Repository.BranchingHelper.IsLatestBranchDifferent(lift13version, out dummy); Assert.That(result, Is.False, "Sally should be on the new LIFT0.13 branch."); // And Fred still shouldn't be result = fredSyncer.Repository.BranchingHelper.IsLatestBranchDifferent(lift13version, out dummy); Assert.That(result, Is.True, "Fred should still be on the 'default' branch."); // Now Fred checks in 'pig' to the 'default' branch File.WriteAllText(fredPathToLift, LiftFileStrings.lift12DogAntPig); // Fred syncs, not finding anybody else's changes fredOptions.CheckinDescription = "adding 'pig'"; fredSyncer.SyncNow(fredOptions); // Verification Step 4 bobContents = File.ReadAllText(bobSetup._pathToLift); Assert.That(bobContents, Does.Not.Contain("pig"), "'pig' should only be on 'default' branch."); sallyContents = File.ReadAllText(sallyPathToLift); Assert.That(sallyContents, Does.Not.Contain("pig"), "'pig' should only be on 'default' branch."); fredContents = File.ReadAllText(fredPathToLift); Assert.That(fredContents, Does.Not.Contain("herring"), "'herring' should still only be in the new version."); // Just check Fred hasn't changed branches result = fredSyncer.Repository.BranchingHelper.IsLatestBranchDifferent(lift13version, out dummy); Assert.That(result, Is.True, "Fred should still be on the 'default' branch."); // Now Bob checks in 'deer' in the new version File.WriteAllText(bobSetup._pathToLift, LiftFileStrings.lift13DogCatHerringAntDeer); bobOptions.CheckinDescription = "adding 'deer'"; bobSyncer.SyncNow(bobOptions); // Verification Step 5 // Check that Fred hasn't changed fredContents = File.ReadAllText(fredPathToLift); Assert.That(fredContents, Does.Not.Contain("deer"), "'deer' should only be on new version."); result = fredSyncer.Repository.BranchingHelper.IsLatestBranchDifferent(lift13version, out dummy); Assert.That(result, Is.True, "Fred should still be on the 'default' branch."); // Check that Sally got her 'deer' sallyContents = File.ReadAllText(sallyPathToLift); Assert.That(sallyContents, Does.Contain("deer"), "'deer' should have propagated to Sally."); // Make sure that 'pig' hasn't migrated to the new version Assert.That(sallyContents, Does.Not.Contain("pig"), "'pig' should still only be on 'default' branch."); // Now Fred has finally upgraded and will check in 'fox' -- LAST CHECK-IN FOR THIS TEST! File.WriteAllText(fredPathToLift, LiftFileStrings.lift13DogAntPigFox); fredOptions.CheckinDescription = "adding 'fox'"; SetAdjunctModelVersion(fredSyncer, lift13version); // Fred finally updates to the new version (branch) fredSyncer.SyncNow(fredOptions); // Verification Step 6 (Last) bobContents = File.ReadAllText(bobSetup._pathToLift); Assert.That(bobContents, Does.Contain("cat"), "'cat' should survive the big hairy test in Bob's repo."); Assert.That(bobContents, Does.Contain("dog"), "'dog' should survive the big hairy test in Bob's repo."); Assert.That(bobContents, Does.Contain("pig"), "'pig' should survive the big hairy test in Bob's repo."); Assert.That(bobContents, Does.Contain("herring"), "'herring' should survive the big hairy test in Bob's repo."); Assert.That(bobContents, Does.Contain("deer"), "'deer' should survive the big hairy test in Bob's repo."); Assert.That(bobContents, Does.Contain("ant"), "'ant' should survive the big hairy test in Bob's repo."); Assert.That(bobContents, Does.Contain("fox"), "'fox' should survive the big hairy test in Bob's repo."); sallyContents = File.ReadAllText(sallyPathToLift); Assert.That(sallyContents, Does.Contain("cat"), "'cat' should survive the big hairy test in Sally's repo."); Assert.That(sallyContents, Does.Contain("dog"), "'dog' should survive the big hairy test in Sally's repo."); Assert.That(sallyContents, Does.Contain("herring"), "'herring' should survive the big hairy test in Sally's repo."); Assert.That(sallyContents, Does.Contain("pig"), "'pig' should survive the big hairy test in Sally's repo."); Assert.That(sallyContents, Does.Contain("deer"), "'deer' should survive the big hairy test in Sally's repo."); Assert.That(sallyContents, Does.Contain("ant"), "'ant' should survive the big hairy test in Sally's repo."); Assert.That(sallyContents, Does.Contain("fox"), "'fox' should survive the big hairy test in Sally's repo."); fredContents = File.ReadAllText(fredPathToLift); Assert.That(fredContents, Does.Contain("cat"), "'cat' should survive the big hairy test in Fred's repo."); Assert.That(fredContents, Does.Contain("dog"), "'dog' should survive the big hairy test in Fred's repo."); Assert.That(fredContents, Does.Contain("herring"), "'herring' should survive the big hairy test in Fred's repo."); Assert.That(fredContents, Does.Contain("pig"), "'pig' should survive the big hairy test in Fred's repo."); Assert.That(fredContents, Does.Contain("deer"), "'deer' should survive the big hairy test in Fred's repo."); Assert.That(fredContents, Does.Contain("ant"), "'ant' should survive the big hairy test in Fred's repo."); Assert.That(fredContents, Does.Contain("fox"), "'fox' should survive the big hairy test in Fred's repo."); // Verify Bob is on the latest branch result = bobSyncer.Repository.BranchingHelper.IsLatestBranchDifferent(lift13version, out dummy); Assert.That(result, Is.False, "Bob should be on the new LIFT0.13 branch."); // Verify Sally is on the right branch result = sallySyncer.Repository.BranchingHelper.IsLatestBranchDifferent(lift13version, out dummy); Assert.That(result, Is.False, "Sally should be on the new LIFT0.13 branch."); // Verify Fred is finally on the new branch result = fredSyncer.Repository.BranchingHelper.IsLatestBranchDifferent(lift13version, out dummy); Assert.That(result, Is.False, "Fred should finally be on the new LIFT0.13 branch."); }