public void ContextDoesNotLeak() { // Note: this test will fail if you set regular event handlers // for PropertyChanged/CollectionChanged events in dirty profiles (use WeakEventManager instead) var project = CreateTestProject(); project.Options.Profiles["kana"].Actions.Add(new ActionProfileOptions { Name = "kana-action" }); var refs = new List <WeakReference>(); new Action(() => { var context = new ProfileOptionsWindowContext(project, null, null); refs.Add(new WeakReference(context, true)); refs.Add(new WeakReference(context.Pages.First(p => p is ProfileOptionsActionsPage), true)); GetDirtyProfile(context, "kana").Actions[0].Name = "renamed-kana-action"; context.SaveChanges(); })(); GC.Collect(); GC.WaitForPendingFinalizers(); foreach (var r in refs) { Assert.Null(r.Target); } }
public void SaveChangesNameConflictIgnoredTest() { var project = CreateTestProject(); // Add a third profile at the end project.Options.SetProfiles(project.Options.Profiles.Append(new KeyValuePair <string, ProfileOptions>("miz", new ProfileOptions())).ToDictionary(p => p.Key, p => p.Value), project.Options.ActiveProfile); var nameResolver = new Mock <ProfileOptionsWindowContext.AskProfileNameDelegate>(MockBehavior.Strict); var context = new ProfileOptionsWindowContext(project, null, nameResolver.Object); context.SelectedProfile = GetDirtyProfile(context, "kana"); var asa = GetDirtyProfile(context, "asa"); asa.General.ProfileName = "kana"; asa.General.RemoteWorkDir = "~asa-edited/code"; nameResolver.Setup(n => n("Rename", It.IsAny <string>(), It.IsAny <IEnumerable <string> >(), "kana")).Returns("kana"); Assert.Null(context.SaveChanges()); // no error // Selected profile is transparently switched to the replacement Assert.Equal(asa, context.SelectedProfile); Assert.Equal(2, context.DirtyProfiles.Count); Assert.Equal(asa, context.DirtyProfiles[0]); Assert.Equal(2, project.Options.Profiles.Count); Assert.True(project.Options.Profiles.TryGetValue("kana", out var renamed)); Assert.Equal("~asa-edited/code", renamed.General.RemoteWorkDir); Assert.True(project.Options.Profiles.ContainsKey("miz")); }
public void SaveChangesNameConflictResolvedTest() { var project = CreateTestProject(); var nameResolver = new Mock <ProfileOptionsWindowContext.AskProfileNameDelegate>(MockBehavior.Strict); var context = new ProfileOptionsWindowContext(project, null, nameResolver.Object); var kana = GetDirtyProfile(context, "kana"); kana.General.RemoteWorkDir = "~kana-edited/code"; var asa = GetDirtyProfile(context, "asa"); asa.General.ProfileName = "kana"; asa.General.RemoteWorkDir = "~asa-edited/code"; nameResolver.Setup(n => n("Rename", "Profile kana already exists. Enter a new name or leave it as is to overwrite the profile:", It.IsAny <IEnumerable <string> >(), "kana")) .Returns("asa-renamed").Verifiable(); Assert.Null(context.SaveChanges()); // no error nameResolver.Verify(); Assert.Equal(2, project.Options.Profiles.Count); Assert.True(project.Options.Profiles.TryGetValue("kana", out var kanaSaved)); Assert.Equal("~kana-edited/code", kanaSaved.General.RemoteWorkDir); Assert.True(project.Options.Profiles.TryGetValue("asa-renamed", out var asaSaved)); Assert.Equal("~asa-edited/code", asaSaved.General.RemoteWorkDir); // Don't forget to synchronize dirty profiles! Assert.Equal("~kana-edited/code", GetDirtyProfile(context, "kana").General.RemoteWorkDir); Assert.Equal("~asa-edited/code", GetDirtyProfile(context, "asa-renamed").General.RemoteWorkDir); }
public void RenamingActionsSynchronizesNameUsagesSteps() { var project = CreateTestProject(); project.Options.Profiles["kana"].Actions.Add(new ActionProfileOptions { Name = "kana-action" }); project.Options.Profiles["kana"].Actions[1].Steps.Add(new RunActionStep { Name = "Debug" }); project.Options.Profiles["kana"].MenuCommands.DebugAction = "Debug"; project.Options.Profiles["kana"].MenuCommands.ProfileAction = "Debug"; project.Options.Profiles["kana"].MenuCommands.DisassembleAction = "Debug"; project.Options.Profiles["kana"].MenuCommands.DisassembleAction = "Debug"; var context = new ProfileOptionsWindowContext(project, null, null); GetDirtyProfile(context, "kana").Actions[0].Name = "renamed-debug"; Assert.Equal("renamed-debug", ((RunActionStep)GetDirtyProfile(context, "kana").Actions[1].Steps[0]).Name); Assert.Equal("renamed-debug", GetDirtyProfile(context, "kana").MenuCommands.DebugAction); Assert.Equal("renamed-debug", GetDirtyProfile(context, "kana").MenuCommands.ProfileAction); Assert.Equal("renamed-debug", GetDirtyProfile(context, "kana").MenuCommands.DisassembleAction); Assert.Equal("renamed-debug", GetDirtyProfile(context, "kana").MenuCommands.DisassembleAction); /* Syncs actions added to dirty profile */ GetDirtyProfile(context, "kana").Actions.Add(new ActionProfileOptions { Name = "h" }); ((RunActionStep)GetDirtyProfile(context, "kana").Actions[1].Steps[0]).Name = "h"; GetDirtyProfile(context, "kana").Actions.Last().Name = "hh"; Assert.Equal("hh", ((RunActionStep)GetDirtyProfile(context, "kana").Actions[1].Steps[0]).Name); }
public void AddProfileInsertsMacrosTest() { var project = CreateTestProject(); var nameResolver = new Mock <ProfileOptionsWindowContext.AskProfileNameDelegate>(MockBehavior.Strict); var context = new ProfileOptionsWindowContext(project, null, nameResolver.Object); nameResolver.Setup(n => n("Creating a new profile", It.IsAny <string>(), It.IsAny <IEnumerable <string> >(), "")).Returns("dou"); context.CreateNewProfile(); var newProfile = GetDirtyProfile(context, "dou"); var expectedMacros = CleanProfileMacros.Macros.Select(m => new MacroItem(m.Item1, m.Item2, userDefined: true)); Assert.Equal(expectedMacros.ToArray(), newProfile.Macros.ToArray()); }
public void RemoveProfileTest() { var project = CreateTestProject(); var context = new ProfileOptionsWindowContext(project, null, null); // a crude emulation of WPF control behavior when removing selected profile context.DirtyProfiles.CollectionChanged += (s, e) => { if (e.Action == NotifyCollectionChangedAction.Remove && e.OldItems[0] == context.SelectedProfile) { context.SelectedProfile = null; } }; context.SelectedProfile = GetDirtyProfile(context, "kana"); context.RemoveSelectedProfile(); Assert.Single(context.DirtyProfiles); Assert.Null(context.SelectedProfile); Assert.Null(context.SelectedPage); Assert.Empty(context.Pages); context.SaveChanges(); Assert.Equal(1, project.Options.Profiles.Count); // Switches to the first existing profile Assert.Equal("asa", project.Options.ActiveProfile); context.SelectedProfile = GetDirtyProfile(context, "asa"); context.RemoveSelectedProfile(); Assert.Empty(context.DirtyProfiles); Assert.Null(context.SelectedProfile); Assert.Null(context.SelectedPage); Assert.Empty(context.Pages); context.SaveChanges(); Assert.Null(project.Options.Profile); Assert.False(project.Options.HasProfiles); // Does not fail when there are no profiles context.RemoveSelectedProfile(); }
public void AddRemoveActionsTest() { var project = CreateTestProject(); var context = new ProfileOptionsWindowContext(project, null, null); var actionsPage = context.ActionsPage; Assert.Single(actionsPage.Pages, GetAction(context, "Debug")); context.AddAction(); Assert.Collection(actionsPage.Pages, (page1) => Assert.Equal("Debug", page1.Name), (page2) => Assert.Equal("New Action", page2.Name)); var action = context.ActionsPage.Pages[1]; context.RemoveAction(action); Assert.Single(actionsPage.Pages, GetAction(context, "Debug")); }
public void ImportExportTest() { var project = CreateTestProject(); var context = new ProfileOptionsWindowContext(project, null, null); var tmpFile = Path.GetTempFileName(); context.ExportProfiles(tmpFile); context.SelectedProfile = GetDirtyProfile(context, "kana"); context.RemoveSelectedProfile(); context.SelectedProfile = GetDirtyProfile(context, "asa"); context.RemoveSelectedProfile(); Assert.Empty(context.ProfileNames); context.ImportProfiles(tmpFile); File.Delete(tmpFile); Assert.Collection(context.ProfileNames, fst => Assert.Equal("kana", fst), snd => Assert.Equal("asa", snd)); }
public void NormalizesToolbarActionNames() { var project = CreateTestProject(); project.Options.Profiles["kana"].Actions.Add(new ActionProfileOptions { Name = "valid-action" }); project.Options.Profiles["kana"].MenuCommands.ProfileAction = "unknown action"; project.Options.Profiles["kana"].MenuCommands.DisassembleAction = null; project.Options.Profiles["kana"].MenuCommands.PreprocessAction = "valid-action"; var context = new ProfileOptionsWindowContext(project, null, null); Assert.Equal("", GetDirtyProfile(context, "kana").MenuCommands.ProfileAction); Assert.Equal("", GetDirtyProfile(context, "kana").MenuCommands.DisassembleAction); Assert.Equal("valid-action", GetDirtyProfile(context, "kana").MenuCommands.PreprocessAction); GetDirtyProfile(context, "kana").Actions.RemoveAt(1); Assert.Equal("", GetDirtyProfile(context, "kana").MenuCommands.PreprocessAction); }
public void SaveChangesNameConflictResolutionCancelledTest() { var project = CreateTestProject(); var nameResolver = new Mock <ProfileOptionsWindowContext.AskProfileNameDelegate>(MockBehavior.Strict); var context = new ProfileOptionsWindowContext(project, null, nameResolver.Object); context.SelectedProfile = GetDirtyProfile(context, "kana"); var asa = GetDirtyProfile(context, "asa"); asa.General.ProfileName = "kana"; nameResolver.Setup(n => n("Rename", It.IsAny <string>(), It.IsAny <IEnumerable <string> >(), "kana")).Returns((string)null); Assert.Equal("Profile options were not saved.", ((Error)context.SaveChanges()).Message); // Profiles are unchanged Assert.Equal(2, project.Options.Profiles.Count); Assert.True(project.Options.Profiles.ContainsKey("kana")); Assert.True(project.Options.Profiles.ContainsKey("asa")); }
public void AddProfileNameConflictTest() { var project = CreateTestProject(); var nameResolver = new Mock <ProfileOptionsWindowContext.AskProfileNameDelegate>(MockBehavior.Strict); var context = new ProfileOptionsWindowContext(project, null, nameResolver.Object); nameResolver.Setup(n => n("Creating a new profile", "Enter the name for the new profile:", It.IsAny <IEnumerable <string> >(), "")) .Returns("kana").Verifiable(); Assert.Equal(2, context.DirtyProfiles.Count); var oldRemoteDir = GetDirtyProfile(context, "kana").General.RemoteWorkDir; context.CreateNewProfile(); nameResolver.Verify(); Assert.Equal(2, context.DirtyProfiles.Count); var newRemoteDir = GetDirtyProfile(context, "kana").General.RemoteWorkDir; Assert.NotEqual(oldRemoteDir, newRemoteDir); }
public void DirtyTrackingTest() { var project = CreateTestProject(); project.Options.ActiveProfile = "kana"; var context = new ProfileOptionsWindowContext(project, null, null); GetAction(context, "Debug").Steps.Add(new ExecuteStep { Executable = "bun" }); Assert.Empty(project.Options.Profile.Actions[0].Steps); context.SaveChanges(); Assert.Equal(project.Options.Profile.Actions[0].Steps[0], new ExecuteStep { Executable = "bun" }); ((ExecuteStep)GetAction(context, "Debug").Steps[0]).Arguments = "--stuffed"; Assert.Equal("", ((ExecuteStep)project.Options.Profile.Actions[0].Steps[0]).Arguments); context.SaveChanges(); Assert.Equal("--stuffed", ((ExecuteStep)project.Options.Profile.Actions[0].Steps[0]).Arguments); }
public void ImportNameConflictTest() { var project = CreateTestProject(); var nameResolver = new Mock <ProfileOptionsWindowContext.AskProfileNameDelegate>(MockBehavior.Strict); var context = new ProfileOptionsWindowContext(project, null, nameResolver.Object); var tmpFile = Path.GetTempFileName(); context.ExportProfiles(tmpFile); context.SelectedProfile = GetDirtyProfile(context, "kana"); context.RemoveSelectedProfile(); Assert.Single(context.ProfileNames, "asa"); nameResolver.Setup(n => n("Import", "Profile asa already exists. Enter a new name or leave it as is to overwrite the profile:", It.IsAny <IEnumerable <string> >(), "asa")) .Returns("mizu").Verifiable(); context.ImportProfiles(tmpFile); File.Delete(tmpFile); nameResolver.Verify(); Assert.Collection(context.ProfileNames, fst => Assert.Equal("asa", fst), snd => Assert.Equal("kana", snd), trd => Assert.Equal("mizu", trd)); }
public void SaveChangesPreservesSelectedPageTest() { var project = CreateTestProject(); project.Options.Profiles["kana"].Actions.Add(new ActionProfileOptions { Name = "kana-action" }); var context = new ProfileOptionsWindowContext(project, null, null); // a crude emulation of WPF control behavior when resetting dirty profiles on save context.DirtyProfiles.CollectionChanged += (s, e) => { if (e.Action == NotifyCollectionChangedAction.Reset) { context.SelectedPage = null; } }; context.SelectedPage = GetAction(context, "kana-action"); context.SaveChanges(); Assert.IsType <ActionProfileOptions>(context.SelectedPage); Assert.Equal("kana-action", ((ActionProfileOptions)context.SelectedPage).Name); }
private static ProfileOptions GetDirtyProfile(ProfileOptionsWindowContext context, string profileName) => context.DirtyProfiles.First(p => p.General.ProfileName == profileName);
private static ActionProfileOptions GetAction(ProfileOptionsWindowContext context, string name) => context.ActionsPage.Pages.First(a => a.Name == name);
private static T GetPage <T>(ProfileOptionsWindowContext context) => (T)context.Pages.FirstOrDefault(p => p is T);
public void SwitchingProfilePreservesSelectedPageTypeTest() { var project = CreateTestProject(); project.Options.Profiles["kana"].Macros.Add(new MacroItem("kana-profile-macro", "h", userDefined: true)); project.Options.Profiles["kana"].Actions[0].Steps.Add(new OpenInEditorStep { Path = "kana-open-path" }); project.Options.Profiles["kana"].Actions.Add(new ActionProfileOptions { Name = "kana-action" }); project.Options.Profiles["asa"].Macros.Add(new MacroItem("asa-profile-macro", "h", userDefined: true)); project.Options.Profiles["asa"].Actions[0].Steps.Add(new OpenInEditorStep { Path = "asa-open-path" }); var context = new ProfileOptionsWindowContext(project, null, null) { SelectedPage = null }; // a crude emulation of WPF control behavior when clearing the collection context.Pages.CollectionChanged += (s, e) => { if (e.Action == NotifyCollectionChangedAction.Reset) { context.SelectedPage = null; } }; // No page selected context.SelectedProfile = GetDirtyProfile(context, "asa"); Assert.Null(context.SelectedPage); // does not throw a null pointer exception // General, Macros context.SelectedProfile = GetDirtyProfile(context, "kana"); context.SelectedPage = GetPage <ProfileOptionsMacrosPage>(context); var lastMacro = ((ProfileOptionsMacrosPage)context.SelectedPage).Macros.Last(); Assert.Equal("kana-profile-macro", lastMacro.Name); context.SelectedProfile = GetDirtyProfile(context, "asa"); Assert.IsType <ProfileOptionsMacrosPage>(context.SelectedPage); lastMacro = ((ProfileOptionsMacrosPage)context.SelectedPage).Macros.Last(); Assert.Equal("asa-profile-macro", lastMacro.Name); // Debug (shared action) context.SelectedProfile = GetDirtyProfile(context, "kana"); context.SelectedPage = GetAction(context, "Debug"); Assert.Equal("kana-open-path", (((ActionProfileOptions)context.SelectedPage).Steps[0] as OpenInEditorStep).Path); context.SelectedProfile = GetDirtyProfile(context, "asa"); Assert.IsType <ActionProfileOptions>(context.SelectedPage); Assert.Equal("asa-open-path", (((ActionProfileOptions)context.SelectedPage).Steps[0] as OpenInEditorStep).Path); // Non-shared action context.SelectedProfile = GetDirtyProfile(context, "kana"); context.SelectedPage = GetPage <ProfileOptionsActionsPage>(context).Pages.First(a => a is ActionProfileOptions ao && ao.Name == "kana-action"); Assert.Equal("kana-action", ((ActionProfileOptions)context.SelectedPage).Name); context.SelectedProfile = GetDirtyProfile(context, "asa"); Assert.Null(context.SelectedPage); }