| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- #nullable enable
- using System.Collections.Concurrent;
- using System.Collections.Frozen;
- using System.Collections.Immutable;
- using System.Text.Json;
- using static Terminal.Gui.Configuration.ConfigurationManager;
- namespace Terminal.Gui.ConfigurationTests;
- public class SettingsScopeTests
- {
- [Fact]
- public void Load_Overrides_Defaults ()
- {
- // arrange
- Enable (ConfigLocations.HardCoded);
- Assert.Equal (Key.Esc, (Key)Settings! ["Application.QuitKey"].PropertyValue!);
- ThrowOnJsonErrors = true;
- // act
- RuntimeConfig = """
- {
- "Application.QuitKey": "Ctrl-Q"
- }
- """;
- Load (ConfigLocations.Runtime);
- // assert
- Assert.Equal (Key.Q.WithCtrl, (Key)Settings ["Application.QuitKey"].PropertyValue!);
- // clean up
- Disable (true);
- }
- [Fact]
- public void Load_Dictionary_Property_Overrides_Defaults ()
- {
- // arrange
- Enable (ConfigLocations.HardCoded);
- ThrowOnJsonErrors = true;
- ConfigProperty themesConfigProperty = Settings! ["Themes"];
- ConcurrentDictionary<string, ThemeScope> dict = (themesConfigProperty.PropertyValue as ConcurrentDictionary<string, ThemeScope>)!;
- Assert.NotNull (dict);
- Assert.Single (dict);
- Assert.NotEmpty (((ConcurrentDictionary<string, ThemeScope>)themesConfigProperty.PropertyValue!)!);
- ThemeScope scope = dict [ThemeManager.DEFAULT_THEME_NAME];
- Assert.NotNull (scope);
- Assert.Equal (MouseState.In | MouseState.Pressed | MouseState.PressedOutside, scope ["Button.DefaultHighlightStates"].PropertyValue);
- RuntimeConfig = """
- {
- "Themes": [
- {
- "Default":
- {
- "Button.DefaultHighlightStates": "None"
- }
- },
- {
- "NewTheme":
- {
- "Button.DefaultHighlightStates": "In"
- }
- }
- ]
- }
- """;
- Load (ConfigLocations.Runtime);
- // assert
- Assert.Equal (2, ThemeManager.Themes!.Count);
- Assert.Equal (MouseState.None, (MouseState)ThemeManager.GetCurrentTheme () ["Button.DefaultHighlightStates"].PropertyValue!);
- Assert.Equal (MouseState.In, (MouseState)ThemeManager.Themes ["NewTheme"] ["Button.DefaultHighlightStates"].PropertyValue!);
- RuntimeConfig = """
- {
- "Themes": [
- {
- "Default":
- {
- "Button.DefaultHighlightStates": "Pressed"
- }
- }
- ]
- }
- """;
- Load (ConfigLocations.Runtime);
- // assert
- Assert.Equal (2, ThemeManager.Themes.Count);
- Assert.Equal (MouseState.Pressed, (MouseState)ThemeManager.Themes! [ThemeManager.DEFAULT_THEME_NAME] ["Button.DefaultHighlightStates"].PropertyValue!);
- Assert.Equal (MouseState.In, (MouseState)ThemeManager.Themes! ["NewTheme"] ["Button.DefaultHighlightStates"].PropertyValue!);
- // clean up
- Disable (true);
- }
- [Fact]
- public void Apply_ShouldApplyProperties ()
- {
- Enable (ConfigLocations.HardCoded);
- Load (ConfigLocations.LibraryResources);
- // arrange
- Assert.Equal (Key.Esc, (Key)Settings! ["Application.QuitKey"].PropertyValue!);
- Assert.Equal (
- Key.F6,
- (Key)Settings ["Application.NextTabGroupKey"].PropertyValue!
- );
- Assert.Equal (
- Key.F6.WithShift,
- (Key)Settings ["Application.PrevTabGroupKey"].PropertyValue!
- );
- // act
- Settings ["Application.QuitKey"].PropertyValue = Key.Q;
- Settings ["Application.NextTabGroupKey"].PropertyValue = Key.F;
- Settings ["Application.PrevTabGroupKey"].PropertyValue = Key.B;
- Settings.Apply ();
- // assert
- Assert.Equal (Key.Q, Application.QuitKey);
- Assert.Equal (Key.F, Application.NextTabGroupKey);
- Assert.Equal (Key.B, Application.PrevTabGroupKey);
- Disable (true);
- }
- [Fact]
- public void CopyUpdatedPropertiesFrom_ShouldCopyChangedPropertiesOnly ()
- {
- Enable (ConfigLocations.HardCoded);
- Settings! ["Application.QuitKey"].PropertyValue = Key.End;
- var updatedSettings = new SettingsScope ();
- updatedSettings.LoadHardCodedDefaults ();
- // Don't set Quitkey
- updatedSettings ["Application.QuitKey"].HasValue = false;
- updatedSettings ["Application.QuitKey"].PropertyValue = null;
- updatedSettings ["Application.NextTabGroupKey"].PropertyValue = Key.F;
- updatedSettings ["Application.PrevTabGroupKey"].PropertyValue = Key.B;
- Settings.UpdateFrom (updatedSettings);
- Assert.Equal (KeyCode.End, ((Key)Settings ["Application.QuitKey"].PropertyValue!).KeyCode);
- Assert.Equal (KeyCode.F, ((Key)updatedSettings ["Application.NextTabGroupKey"].PropertyValue!).KeyCode);
- Assert.Equal (KeyCode.B, ((Key)updatedSettings ["Application.PrevTabGroupKey"].PropertyValue!).KeyCode);
- Disable (true);
- }
- [Fact]
- public void ResetToHardCodedDefaults_Resets_Config_And_Applies ()
- {
- try
- {
- Enable (ConfigLocations.HardCoded);
- Load (ConfigLocations.LibraryResources);
- Assert.True (Settings! ["Application.QuitKey"].PropertyValue is Key);
- Assert.Equal (Key.Esc, Settings ["Application.QuitKey"].PropertyValue as Key);
- Settings ["Application.QuitKey"].PropertyValue = Key.Q;
- Apply ();
- Assert.Equal (Key.Q, Application.QuitKey);
- // Act
- ResetToHardCodedDefaults ();
- Assert.Equal (Key.Esc, Settings ["Application.QuitKey"].PropertyValue as Key);
- Assert.Equal (Key.Esc, Application.QuitKey);
- }
- finally
- {
- Disable (true);
- }
- }
- [Fact]
- public void Themes_Property_Exists ()
- {
- var settingsScope = new SettingsScope ();
- Assert.NotEmpty (settingsScope);
- // Themes exists, but is not initialized
- Assert.Null (settingsScope ["Themes"].PropertyValue);
- //settingsScope.UpdateToCurrentValues ();
- //Assert.NotEmpty (settingsScope);
- }
- [Fact]
- public void LoadHardCodedDefaults_Resets ()
- {
- // Arrange
- Assert.Equal (Key.Esc, Application.QuitKey);
- var settingsScope = new SettingsScope ();
- settingsScope.LoadHardCodedDefaults ();
- // Act
- settingsScope ["Application.QuitKey"].PropertyValue = Key.Q;
- settingsScope.Apply ();
- Assert.Equal (Key.Q, Application.QuitKey);
- settingsScope.LoadHardCodedDefaults ();
- settingsScope.Apply ();
- // Assert
- Assert.Equal (Key.Esc, Application.QuitKey);
- Disable (true);
- }
- private class ConfigPropertyMock
- {
- public object? PropertyValue { get; init; }
- public bool Immutable { get; init; }
- }
- private class SettingsScopeMock : Dictionary<string, ConfigPropertyMock>
- {
- public string? Theme { get; set; }
- }
- [Fact]
- public void SettingsScopeMockWithKey_CreatesDeepCopy ()
- {
- SettingsScopeMock? source = new ()
- {
- Theme = "Dark",
- ["KeyBinding"] = new () { PropertyValue = new Key (KeyCode.A) { Handled = true } },
- ["Counts"] = new () { PropertyValue = new Dictionary<string, int> { { "X", 1 } } }
- };
- SettingsScopeMock? result = DeepCloner.DeepClone (source);
- Assert.NotNull (result);
- Assert.NotSame (source, result);
- Assert.Equal (source.Theme, result!.Theme);
- Assert.NotSame (source ["KeyBinding"], result ["KeyBinding"]);
- Assert.NotSame (source ["Counts"], result ["Counts"]);
- ConfigPropertyMock clonedKeyProp = result ["KeyBinding"];
- var clonedKey = (Key)clonedKeyProp.PropertyValue!;
- Assert.NotSame (source ["KeyBinding"].PropertyValue, clonedKey);
- Assert.Equal (((Key)source ["KeyBinding"].PropertyValue!).KeyCode, clonedKey.KeyCode);
- Assert.Equal (((Key)source ["KeyBinding"].PropertyValue!).Handled, clonedKey.Handled);
- Assert.Equal ((Dictionary<string, int>)source ["Counts"].PropertyValue!, (Dictionary<string, int>)result ["Counts"].PropertyValue!);
- // Modify result, ensure source unchanged
- result.Theme = "Light";
- clonedKey.Handled = false;
- ((Dictionary<string, int>)result ["Counts"].PropertyValue!).Add ("Y", 2);
- Assert.Equal ("Dark", source.Theme);
- Assert.True (((Key)source ["KeyBinding"].PropertyValue!).Handled);
- Assert.Single ((Dictionary<string, int>)source ["Counts"].PropertyValue!);
- Disable (true);
- }
- [Fact /*(Skip = "This test randomly fails due to a concurrent change to something. Needs to be moved to non-parallel tests.")*/]
- public void ThemeScopeList_WithThemes_ClonesSuccessfully ()
- {
- // Arrange: Create a ThemeScope and verify a property exists
- var defaultThemeScope = new ThemeScope ();
- defaultThemeScope.LoadHardCodedDefaults ();
- Assert.True (defaultThemeScope.ContainsKey ("Button.DefaultHighlightStates"));
- var darkThemeScope = new ThemeScope ();
- darkThemeScope.LoadHardCodedDefaults ();
- Assert.True (darkThemeScope.ContainsKey ("Button.DefaultHighlightStates"));
- // Create a Themes list with two themes
- List<Dictionary<string, ThemeScope>> themesList =
- [
- new () { { "Default", defaultThemeScope } },
- new () { { "Dark", darkThemeScope } }
- ];
- // Create a SettingsScope and set the Themes property
- var settingsScope = new SettingsScope ();
- settingsScope.LoadHardCodedDefaults ();
- Assert.True (settingsScope.ContainsKey ("Themes"));
- settingsScope ["Themes"].PropertyValue = themesList;
- // Act
- SettingsScope? result = DeepCloner.DeepClone (settingsScope);
- // Assert
- Assert.NotNull (result);
- Assert.IsType<SettingsScope> (result);
- var resultScope = result;
- Assert.True (resultScope.ContainsKey ("Themes"));
- Assert.NotNull (resultScope ["Themes"].PropertyValue);
- List<Dictionary<string, ThemeScope>> clonedThemes = (List<Dictionary<string, ThemeScope>>)resultScope ["Themes"].PropertyValue!;
- Assert.Equal (2, clonedThemes.Count);
- Disable (true);
- }
- [Fact]
- public void Empty_SettingsScope_ClonesSuccessfully ()
- {
- // Arrange: Create a SettingsScope
- var settingsScope = new SettingsScope ();
- Assert.True (settingsScope.ContainsKey ("Themes"));
- // Act
- SettingsScope? result = DeepCloner.DeepClone (settingsScope);
- // Assert
- Assert.NotNull (result);
- Assert.IsType<SettingsScope> (result);
- Assert.True (result.ContainsKey ("Themes"));
- Disable (true);
- }
- [Fact]
- public void SettingsScope_With_Themes_Set_ClonesSuccessfully ()
- {
- // Arrange: Create a SettingsScope
- var settingsScope = new SettingsScope ();
- Assert.True (settingsScope.ContainsKey ("Themes"));
- settingsScope ["Themes"].PropertyValue = new List<Dictionary<string, ThemeScope>>
- {
- new () { { "Default", new () } },
- new () { { "Dark", new () } }
- };
- // Act
- SettingsScope? result = DeepCloner.DeepClone (settingsScope);
- // Assert
- Assert.NotNull (result);
- Assert.IsType<SettingsScope> (result);
- Assert.True (result.ContainsKey ("Themes"));
- Assert.NotNull (result ["Themes"].PropertyValue);
- Disable (true);
- }
- }
|