Files
Terminal.Gui/UnitTests/Configuration/ConfigurationMangerTests.cs
Tig dcb3b359ad Fixes #2926 - Refactor KeyEvent and KeyEventEventArgs to simplify (#2927)
* Adds basic MainLoop unit tests

* Remove WinChange action from Curses

* Remove WinChange action from Curses

* Remove ProcessInput action from Windows MainLoop

* Simplified MainLoop/ConsoleDriver by making MainLoop internal and moving impt fns to Application

* Modernized Terminal resize events

* Modernized Terminal resize events

* Removed un used property

* for _isWindowsTerminal devenv->wininit; not sure what changed

* Modernized mouse/keyboard events (Action->EventHandler)

* Updated OnMouseEvent API docs

* Using WT_SESSION to detect WT

* removes hacky GetParentProcess

* Updates to fix #2634 (clear last line)

* removes hacky GetParentProcess2

* Addressed mac resize issue

* Addressed mac resize issue

* Removes ConsoleDriver.PrepareToRun, has Init return MainLoop

* Removes unneeded Attribute methods

* Removed GetProcesssName

* Removed GetProcesssName

* Refactored KeyEvent and KeyEventEventArgs into a single class

* Revert "Refactored KeyEvent and KeyEventEventArgs into a single class"

This reverts commit 88a00658db.

* Fixed key repeat issue; reverted stupidity on 1049/1047 confusion

* Updated CSI API Docs

* merge

* Rearranged Event.cs to Keyboard.cs and Mouse.cs

* Renamed KeyEventEventArgs KeyEventArgs

* temp renamed KeyEvent OldKeyEvent

* Merged KeyEvent into KeyEventArgs

* Renamed Application.ProcessKey members

* Renamed Application.ProcessKey members

* Renamed Application.ProcessKey members

* Added Responder.KeyPressed

* Removed unused references

* Fixed arg naming

* InvokeKeybindings->InvokeKeyBindings

* InvokeKeybindings->InvokeKeyBindings

* Fixed unit tests fail

* More progress on refactoring key input; still broken and probably wrong

* Moved OnKeyPressed out of Responder and made ProcessKeyPrssed non-virtual

* Updated API docs

* Moved key handling from Responder to View

* Updated API docs

* Updated HotKey API docs

* Updated shortcut API docs

* Fixed responder unit tests

* Removed Shortcut from View as it is not used

* Removed unneeded OnHotKey override from Button

* Fixed BackTab logic

* Button now uses Key Bindings exclusively

* Button now uses Key Bindings exclusively

* Updated keyboard.md docs

* Fixed unit tests to account for Toplevel handling default button

* Added View.InvokeCommand API

* Modernized RadioGroup

* Removed ColdKey

* Modernized (partially) StatusBar

* Worked around FileDialog issue with Ctrl-F

* Fixed driver unit test; view must be focused to reciev key pressed

* Application code cleanup

* Start on updaing menu

* Menu now mostly works

* Menu Select refinement

* Fixed known menu bugs!

* Enabled HotKey to cause focus- experimental

* Fixes #3022 & adds unit test to prove it

* Actually Fixes #3022 & adds unit test to prove it

* Working through hotkey issues

* Misc fixes

* removed hot/cold key stuff from Keys scenario

* Fixed scenarios

* Simplified shortcut string handling

* Modernized Checkbox

* Modernized TileView

* Updated API docs

* Updated API docs

* attempting to publish v2 docs

* Revert "attempting to publish v2 docs"

This reverts commit 59dcec111b.

* Playing with api docs

* Removed Key.BackTab

* Removed Caps/Scroll/Numlock

* Partial removal of keymodifiers - unit tests pass

* Partial removal of keymodifiers - broke netdriver somewhere

* WindowsDriver & added KeyEventArgsTests

* Fixing menu shortcut/hotkeys - broke Menu.cs into separate files

* Fixed MenuBar!

* Finished modernizing Menu/MenuBar

* Removed Key.a-z. Broke lots of stuff

* checkout@v4

* progress on key mapping and formatting

* VK tests are still failing

* Fixed some unit tests

* Added Hotkey and Keybinding unit tests

* fixed unit test

* All unit tests pass again...

* Fixed broken unit tests

* KeyEventArgs.KeyValue -> AsRune

* Fixed bugs. Still some broken

* Added KeyEventArgs.IsAlpha. Added KeyEventArgs.cast ops. Fixed bugs. Unit tests pass

* Fixed WindowsDriver

* Oops.

* Refactoring based on bdisp's help. Not complete!

* removed calling into subviews from OnKeyBindings

* removed calling into subviews from OnKeyBindings

* Improved View KeyEvent unit tests

* More hotkey unit tests

* BIg change - Got rid of KeyPress w/in Application/Drivers

* Unit tests now pass again

* Refreshed API docs

* Better HotKey logic. More progress. Getting close.

* Fixed handling of shifted chars like ö

* Minor code cleanup

* Minor code cleanup2

* Why is build Action failing?

* Why is build Action failing??

* upgraded to .net8 to try to fix weird CI/CD build errors

* upgraded to .net8 to try to fix weird CI/CD build errors2

* Disabling TextViewTests to diagnose build errors

* reenable TextViewTests to diagnose build errors

* Arrrrrrg

* Merged v2_develop

* Fixed uppercase accented keys in WindowsDriver

* Fixed key binding api docs

* Experimental impl of CommandScope.SubViews for MenuBar

* Removed dead code from application.cs

* Removed dead code from application.cs

* Removed dead code from ConsoleDriver.cs

* Cleaned up some key binding stuff

* Disabled Alt to activate menu for now

* Updated label commands

* Fixed menu bugs. Upgraded menu unit tests

* Fixed unit tests

* Working on NetDriver

* fixed netdriver

* Fixed issues called out by @bdisp CR

* fixed CursesDriver

* added todo to netdriver

* Cherry picked treeview test fix 1b415e5

* Fix NetDriver.

* CommandScope->KeyBindingScope

* Address some tznind feedback

* Refactored KeyBindings big time!

* Added key consts to KeyEventArgs and renamed Key to ConsoleDriverKey

* Fixed some API docs

* Moved ConsoleDriverKey to ConsoleDriver.cs

* Renamed Key->ConsoleDriverKey

* Renamed Key->ConsoleDriverKey

* Renamed Key->ConsoleDriverKey

* renamed file I forgot to rename before

* Updated name and API docs of KeyEventArgs.isAlpha

* Fixed issues with OnKeyUp not doing the right thing.

* Fixed MainLoop.Running never being used

* Fixed MainLoop.Running never being used - unit tests

* Claned up BUGBUG comments

* Disabled a unit test to see why ci/cd tests are failing

* Removed defunct commented code

* Removed more defunct commented code

* Re-eanbled unit test; jsut removing one test case...

* Disabled more...

* Renambed Global->Applicaton and updated scope API docs

* Disabled more unit tests...

* Removed dead code

* Disabled more unit tests...2

* Disabled more unit tests...3

* Renambed Global->Applicaton and updated scope API docs 2

* Added more KeyBinding scope tests

* Added more KeyBinding scope tests2

* ConsoleDriverKey too long. Key too ambiguous. Settled on KeyCode. (Partialy because eventually I want to intro a class named Key).

* KeyEventArgs improvements. cast to Rune must be explicit as it's lossy

* Fixed warnings

* Renamed KeyEventArgs to Key... progress on fixing broken stuff that resulted

* Fix ConsoleKeyMapping bugs.

* Fix NetDriver issue from converting a lower case to a upper case.

* Started migration to Key from KeyCode - e.g. made HotKeys all consistent.

* Fixed build warnings

* Added key defns to Key

* KeyBindings now uses Key vs. KeyCode

* Verified by tweaking UICatalog

* Fixed treeview test ... again

* Renamed ProcessKeyDown/Up to NewKeyDown/Up and OnKeyPressed to OnProcessKeyDown to make things more clear

* Added test AllViews_KeyDown_All_EventsFire unit tests and fixed a few Views that were wrong

* fixed stupid KeyUp event bug

* If key not handled, return false for datefield

* dotnet test --no-restore --verbosity diag

* dotnet test --blame

* run tests on windows

* Fix TestVKPacket unit test and move it to ConsoleKeyMappingTests.cs file.

* Remove unnecessary commented code.

* Tweaked unit tests and removed Key.BareKey

* Fixed little details and updated api docs

* updated api docs

* AddKeyBindingsForHotKey: KeyCode->Key

* Cleaned up more old KeyCode usages. Added TODOs

---------

Co-authored-by: BDisp <bd.bdisp@gmail.com>
2023-12-16 12:04:23 -07:00

792 lines
26 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using Xunit;
using static Terminal.Gui.ConfigurationManager;
namespace Terminal.Gui.ConfigurationTests {
public class ConfigurationManagerTests {
public static readonly JsonSerializerOptions _jsonOptions = new () {
Converters = {
new AttributeJsonConverter (),
new ColorJsonConverter (),
}
};
[Fact ()]
public void DeepMemberwiseCopyTest ()
{
// Value types
var stringDest = "Destination";
var stringSrc = "Source";
var stringCopy = DeepMemberwiseCopy (stringSrc, stringDest);
Assert.Equal (stringSrc, stringCopy);
stringDest = "Destination";
stringSrc = "Destination";
stringCopy = DeepMemberwiseCopy (stringSrc, stringDest);
Assert.Equal (stringSrc, stringCopy);
stringDest = "Destination";
stringSrc = null;
stringCopy = DeepMemberwiseCopy (stringSrc, stringDest);
Assert.Equal (stringSrc, stringCopy);
stringDest = "Destination";
stringSrc = string.Empty;
stringCopy = DeepMemberwiseCopy (stringSrc, stringDest);
Assert.Equal (stringSrc, stringCopy);
var boolDest = true;
var boolSrc = false;
var boolCopy = DeepMemberwiseCopy (boolSrc, boolDest);
Assert.Equal (boolSrc, boolCopy);
boolDest = false;
boolSrc = true;
boolCopy = DeepMemberwiseCopy (boolSrc, boolDest);
Assert.Equal (boolSrc, boolCopy);
boolDest = true;
boolSrc = true;
boolCopy = DeepMemberwiseCopy (boolSrc, boolDest);
Assert.Equal (boolSrc, boolCopy);
boolDest = false;
boolSrc = false;
boolCopy = DeepMemberwiseCopy (boolSrc, boolDest);
Assert.Equal (boolSrc, boolCopy);
// Structs
var attrDest = new Attribute (Color.Black);
var attrSrc = new Attribute (Color.White);
var attrCopy = DeepMemberwiseCopy (attrSrc, attrDest);
Assert.Equal (attrSrc, attrCopy);
// Classes
var colorschemeDest = new ColorScheme () { Disabled = new Attribute (Color.Black) };
var colorschemeSrc = new ColorScheme () { Disabled = new Attribute (Color.White) };
var colorschemeCopy = DeepMemberwiseCopy (colorschemeSrc, colorschemeDest);
Assert.Equal (colorschemeSrc, colorschemeCopy);
// Dictionaries
var dictDest = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.Black) } };
var dictSrc = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.White) } };
var dictCopy = (Dictionary<string, Attribute>)DeepMemberwiseCopy (dictSrc, dictDest);
Assert.Equal (dictSrc, dictCopy);
dictDest = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.Black) } };
dictSrc = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.White) }, { "Normal", new Attribute (Color.Blue) } };
dictCopy = (Dictionary<string, Attribute>)DeepMemberwiseCopy (dictSrc, dictDest);
Assert.Equal (dictSrc, dictCopy);
// src adds an item
dictDest = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.Black) } };
dictSrc = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.White) }, { "Normal", new Attribute (Color.Blue) } };
dictCopy = (Dictionary<string, Attribute>)DeepMemberwiseCopy (dictSrc, dictDest);
Assert.Equal (2, dictCopy.Count);
Assert.Equal (dictSrc ["Disabled"], dictCopy ["Disabled"]);
Assert.Equal (dictSrc ["Normal"], dictCopy ["Normal"]);
// src updates only one item
dictDest = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.Black) }, { "Normal", new Attribute (Color.White) } };
dictSrc = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.White) } };
dictCopy = (Dictionary<string, Attribute>)DeepMemberwiseCopy (dictSrc, dictDest);
Assert.Equal (2, dictCopy.Count);
Assert.Equal (dictSrc ["Disabled"], dictCopy ["Disabled"]);
Assert.Equal (dictDest ["Normal"], dictCopy ["Normal"]);
}
//[Fact ()]
//public void LoadFromJsonTest ()
//{
// Assert.True (false, "This test needs an implementation");
//}
//[Fact ()]
//public void ToJsonTest ()
//{
// Assert.True (false, "This test needs an implementation");
//}
//[Fact ()]
//public void UpdateConfigurationTest ()
//{
// Assert.True (false, "This test needs an implementation");
//}
//[Fact ()]
//public void UpdateConfigurationFromFileTest ()
//{
// Assert.True (false, "This test needs an implementation");
//}
//[Fact ()]
//public void SaveHardCodedDefaultsTest ()
//{
// Assert.True (false, "This test needs an implementation");
//}
//[Fact ()]
//public void LoadGlobalFromLibraryResourceTest ()
//{
// Assert.True (false, "This test needs an implementation");
//}
//[Fact ()]
//public void LoadGlobalFromAppDirectoryTest ()
//{
// Assert.True (false, "This test needs an implementation");
//}
//[Fact ()]
//public void LoadGlobalFromHomeDirectoryTest ()
//{
// Assert.True (false, "This test needs an implementation");
//}
//[Fact ()]
//public void LoadAppFromAppResourcesTest ()
//{
// Assert.True (false, "This test needs an implementation");
//}
//[Fact ()]
//public void LoadAppFromAppDirectoryTest ()
//{
// Assert.True (false, "This test needs an implementation");
//}
//[Fact ()]
//public void LoadAppFromHomeDirectoryTest ()
//{
// Assert.True (false, "This test needs an implementation");
//}
//[Fact ()]
//public void LoadTest ()
//{
// Assert.True (false, "This test needs an implementation");
//}
/// <summary>
/// Save the `config.json` file; this can be used to update the file in `Terminal.Gui.Resources.config.json'.
/// </summary>
/// <remarks>
/// IMPORTANT: For the file generated to be valid, this must be the ONLY test run. Config Properties
/// are all static and thus can be overwritten by other tests.</remarks>
[Fact]
public void SaveDefaults ()
{
ConfigurationManager.Initialize ();
ConfigurationManager.Reset ();
// Get the hard coded settings
ConfigurationManager.GetHardCodedDefaults ();
// Serialize to a JSON string
string json = ConfigurationManager.ToJson ();
// Write the JSON string to the file
File.WriteAllText ("config.json", json);
}
[Fact]
public void UseWithoutResetAsserts ()
{
ConfigurationManager.Initialize ();
Assert.Throws<InvalidOperationException> (() => _ = ConfigurationManager.Settings);
}
[Fact]
public void Reset_Resets ()
{
ConfigurationManager.Locations = ConfigLocations.DefaultOnly;
ConfigurationManager.Reset ();
Assert.NotEmpty (ConfigurationManager.Themes);
Assert.Equal ("Default", ConfigurationManager.Themes.Theme);
}
[Fact]
public void Reset_and_ResetLoadWithLibraryResourcesOnly_are_same ()
{
ConfigurationManager.Locations = ConfigLocations.DefaultOnly;
// arrange
ConfigurationManager.Reset ();
ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue = new Key (KeyCode.Q);
ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue = new Key (KeyCode.F);
ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue = new Key (KeyCode.B);
ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue = true;
ConfigurationManager.Settings.Apply ();
// assert apply worked
Assert.Equal (KeyCode.Q, Application.QuitKey.KeyCode);
Assert.Equal (KeyCode.F, Application.AlternateForwardKey.KeyCode);
Assert.Equal (KeyCode.B, Application.AlternateBackwardKey.KeyCode);
Assert.True (Application.IsMouseDisabled);
//act
ConfigurationManager.Reset ();
// assert
Assert.NotEmpty (ConfigurationManager.Themes);
Assert.Equal ("Default", ConfigurationManager.Themes.Theme);
Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey.KeyCode);
Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, Application.AlternateForwardKey.KeyCode);
Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, Application.AlternateBackwardKey.KeyCode);
Assert.False (Application.IsMouseDisabled);
// arrange
ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue = new Key (KeyCode.Q);
ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue = new Key (KeyCode.F);
ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue = new Key (KeyCode.B);
ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue = true;
ConfigurationManager.Settings.Apply ();
ConfigurationManager.Locations = ConfigLocations.DefaultOnly;
// act
ConfigurationManager.Reset ();
ConfigurationManager.Load ();
// assert
Assert.NotEmpty (ConfigurationManager.Themes);
Assert.Equal ("Default", ConfigurationManager.Themes.Theme);
Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey.KeyCode);
Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, Application.AlternateForwardKey.KeyCode);
Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, Application.AlternateBackwardKey.KeyCode);
Assert.False (Application.IsMouseDisabled);
}
[Fact]
public void TestConfigProperties ()
{
ConfigurationManager.Locations = ConfigLocations.All;
ConfigurationManager.Reset ();
Assert.NotEmpty (ConfigurationManager.Settings);
// test that all ConfigProperites have our attribute
Assert.All (ConfigurationManager.Settings, item => Assert.NotEmpty (item.Value.PropertyInfo.CustomAttributes.Where (a => a.AttributeType == typeof (SerializableConfigurationProperty))));
Assert.Empty (ConfigurationManager.Settings.Where (cp => cp.Value.PropertyInfo.GetCustomAttribute (typeof (SerializableConfigurationProperty)) == null));
// Application is a static class
PropertyInfo pi = typeof (Application).GetProperty ("QuitKey");
Assert.Equal (pi, ConfigurationManager.Settings ["Application.QuitKey"].PropertyInfo);
// FrameView is not a static class and DefaultBorderStyle is Scope.Scheme
pi = typeof (FrameView).GetProperty ("DefaultBorderStyle");
Assert.False (ConfigurationManager.Settings.ContainsKey ("FrameView.DefaultBorderStyle"));
Assert.True (ConfigurationManager.Themes ["Default"].ContainsKey ("FrameView.DefaultBorderStyle"));
}
[Fact]
public void TestConfigPropertyOmitClassName ()
{
// Color.ColorShemes is serialzied as "ColorSchemes", not "Colors.ColorSchemes"
PropertyInfo pi = typeof (Colors).GetProperty ("ColorSchemes");
var scp = ((SerializableConfigurationProperty)pi.GetCustomAttribute (typeof (SerializableConfigurationProperty)));
Assert.True (scp.Scope == typeof (ThemeScope));
Assert.True (scp.OmitClassName);
ConfigurationManager.Reset ();
Assert.Equal (pi, ConfigurationManager.Themes ["Default"] ["ColorSchemes"].PropertyInfo);
}
[Fact, AutoInitShutdown]
public void TestConfigurationManagerToJson ()
{
ConfigurationManager.Reset ();
ConfigurationManager.GetHardCodedDefaults ();
var stream = ConfigurationManager.ToStream ();
ConfigurationManager.Settings.Update (stream, "TestConfigurationManagerToJson");
}
[Fact, AutoInitShutdown (configLocation: ConfigLocations.None)]
public void TestConfigurationManagerInitDriver_NoLocations ()
{
}
[Fact, AutoInitShutdown (configLocation: ConfigLocations.DefaultOnly)]
public void TestConfigurationManagerInitDriver ()
{
Assert.Equal ("Default", ConfigurationManager.Themes.Theme);
Assert.True (ConfigurationManager.Themes.ContainsKey ("Default"));
Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey.KeyCode);
Assert.Equal (new Color (Color.White), Colors.ColorSchemes ["Base"].Normal.Foreground);
Assert.Equal (new Color (Color.Blue), Colors.ColorSchemes ["Base"].Normal.Background);
// Change Base
var json = ConfigurationManager.ToStream ();
ConfigurationManager.Settings.Update (json, "TestConfigurationManagerInitDriver");
var colorSchemes = ((Dictionary<string, ColorScheme>)ConfigurationManager.Themes [ConfigurationManager.Themes.Theme] ["ColorSchemes"].PropertyValue);
Assert.Equal (Colors.Base, colorSchemes ["Base"]);
Assert.Equal (Colors.TopLevel, colorSchemes ["TopLevel"]);
Assert.Equal (Colors.Error, colorSchemes ["Error"]);
Assert.Equal (Colors.Dialog, colorSchemes ["Dialog"]);
Assert.Equal (Colors.Menu, colorSchemes ["Menu"]);
Colors.Base = colorSchemes ["Base"];
Colors.TopLevel = colorSchemes ["TopLevel"];
Colors.Error = colorSchemes ["Error"];
Colors.Dialog = colorSchemes ["Dialog"];
Colors.Menu = colorSchemes ["Menu"];
Assert.Equal (colorSchemes ["Base"], Colors.Base);
Assert.Equal (colorSchemes ["TopLevel"], Colors.TopLevel);
Assert.Equal (colorSchemes ["Error"], Colors.Error);
Assert.Equal (colorSchemes ["Dialog"], Colors.Dialog);
Assert.Equal (colorSchemes ["Menu"], Colors.Menu);
}
[Fact]
public void TestConfigurationManagerUpdateFromJson ()
{
// Arrange
string json = @"
{
""$schema"": ""https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json"",
""Application.QuitKey"": {
""Key"": ""Alt-Z""
},
""Theme"": ""Default"",
""Themes"": [
{
""Default"": {
""ColorSchemes"": [
{
""TopLevel"": {
""Normal"": {
""Foreground"": ""BrightGreen"",
""Background"": ""Black""
},
""Focus"": {
""Foreground"": ""White"",
""Background"": ""Cyan""
},
""HotNormal"": {
""Foreground"": ""Yellow"",
""Background"": ""Black""
},
""HotFocus"": {
""Foreground"": ""Blue"",
""Background"": ""Cyan""
},
""Disabled"": {
""Foreground"": ""DarkGray"",
""Background"": ""Black""
}
}
},
{
""Base"": {
""Normal"": {
""Foreground"": ""White"",
""Background"": ""Blue""
},
""Focus"": {
""Foreground"": ""Black"",
""Background"": ""Gray""
},
""HotNormal"": {
""Foreground"": ""BrightCyan"",
""Background"": ""Blue""
},
""HotFocus"": {
""Foreground"": ""BrightBlue"",
""Background"": ""Gray""
},
""Disabled"": {
""Foreground"": ""DarkGray"",
""Background"": ""Blue""
}
}
},
{
""Dialog"": {
""Normal"": {
""Foreground"": ""Black"",
""Background"": ""Gray""
},
""Focus"": {
""Foreground"": ""White"",
""Background"": ""DarkGray""
},
""HotNormal"": {
""Foreground"": ""Blue"",
""Background"": ""Gray""
},
""HotFocus"": {
""Foreground"": ""BrightYellow"",
""Background"": ""DarkGray""
},
""Disabled"": {
""Foreground"": ""Gray"",
""Background"": ""DarkGray""
}
}
},
{
""Menu"": {
""Normal"": {
""Foreground"": ""White"",
""Background"": ""DarkGray""
},
""Focus"": {
""Foreground"": ""White"",
""Background"": ""Black""
},
""HotNormal"": {
""Foreground"": ""BrightYellow"",
""Background"": ""DarkGray""
},
""HotFocus"": {
""Foreground"": ""BrightYellow"",
""Background"": ""Black""
},
""Disabled"": {
""Foreground"": ""Gray"",
""Background"": ""DarkGray""
}
}
},
{
""Error"": {
""Normal"": {
""Foreground"": ""Red"",
""Background"": ""White""
},
""Focus"": {
""Foreground"": ""Black"",
""Background"": ""BrightRed""
},
""HotNormal"": {
""Foreground"": ""Black"",
""Background"": ""White""
},
""HotFocus"": {
""Foreground"": ""White"",
""Background"": ""BrightRed""
},
""Disabled"": {
""Foreground"": ""DarkGray"",
""Background"": ""White""
}
}
}
],
""Dialog.DefaultButtonAlignment"": ""Center""
}
}
]
}
";
ConfigurationManager.Reset ();
ConfigurationManager.ThrowOnJsonErrors = true;
ConfigurationManager.Settings.Update (json, "TestConfigurationManagerUpdateFromJson");
Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey.KeyCode);
Assert.Equal (KeyCode.Z | KeyCode.AltMask, ((Key)ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue).KeyCode);
Assert.Equal ("Default", ConfigurationManager.Themes.Theme);
Assert.Equal (new Color (Color.White), Colors.ColorSchemes ["Base"].Normal.Foreground);
Assert.Equal (new Color (Color.Blue), Colors.ColorSchemes ["Base"].Normal.Background);
var colorSchemes = (Dictionary<string, ColorScheme>)Themes.First ().Value ["ColorSchemes"].PropertyValue;
Assert.Equal (new Color (Color.White), colorSchemes ["Base"].Normal.Foreground);
Assert.Equal (new Color (Color.Blue), colorSchemes ["Base"].Normal.Background);
// Now re-apply
ConfigurationManager.Apply ();
Assert.Equal (KeyCode.Z | KeyCode.AltMask, Application.QuitKey.KeyCode);
Assert.Equal ("Default", ConfigurationManager.Themes.Theme);
Assert.Equal (new Color (Color.White), Colors.ColorSchemes ["Base"].Normal.Foreground);
Assert.Equal (new Color (Color.Blue), Colors.ColorSchemes ["Base"].Normal.Background);
}
[Fact, AutoInitShutdown]
public void TestConfigurationManagerInvalidJsonThrows ()
{
ConfigurationManager.ThrowOnJsonErrors = true;
// "yellow" is not a color
string json = @"
{
""Themes"" : [
{
""Default"" : {
""ColorSchemes"": [
{
""UserDefined"": {
""hotNormal"": {
""foreground"": ""brown"",
""background"": ""1234""
}
}
}
]
}
}
]
}";
JsonException jsonException = Assert.Throws<JsonException> (() => ConfigurationManager.Settings.Update (json, "test"));
Assert.Equal ("Unexpected color name: brown.", jsonException.Message);
// AbNormal is not a ColorScheme attribute
json = @"
{
""Themes"" : [
{
""Default"" : {
""ColorSchemes"": [
{
""UserDefined"": {
""AbNormal"": {
""foreground"": ""green"",
""background"": ""black""
}
}
}
]
}
}
]
}";
jsonException = Assert.Throws<JsonException> (() => ConfigurationManager.Settings.Update (json, "test"));
Assert.Equal ("Unrecognized ColorScheme Attribute name: AbNormal.", jsonException.Message);
// Modify hotNormal background only
json = @"
{
""Themes"" : [
{
""Default"" : {
""ColorSchemes"": [
{
""UserDefined"": {
""hotNormal"": {
""background"": ""cyan""
}
}
}
]
}
}
]
}";
jsonException = Assert.Throws<JsonException> (() => ConfigurationManager.Settings.Update (json, "test"));
Assert.Equal ("Both Foreground and Background colors must be provided.", jsonException.Message);
// Unknown proeprty
json = @"
{
""Unknown"" : ""Not known""
}";
jsonException = Assert.Throws<JsonException> (() => ConfigurationManager.Settings.Update (json, "test"));
Assert.StartsWith ("Unknown property", jsonException.Message);
Assert.Equal (0, ConfigurationManager.jsonErrors.Length);
ConfigurationManager.ThrowOnJsonErrors = false;
}
[Fact]
public void TestConfigurationManagerInvalidJsonLogs ()
{
Application.Init (new FakeDriver ());
ConfigurationManager.ThrowOnJsonErrors = false;
// "brown" is not a color
string json = @"
{
""Themes"" : [
{
""Default"" : {
""ColorSchemes"": [
{
""UserDefined"": {
""hotNormal"": {
""foreground"": ""brown"",
""background"": ""1234""
}
}
}
]
}
}
}
}";
ConfigurationManager.Settings.Update (json, "test");
// AbNormal is not a ColorScheme attribute
json = @"
{
""Themes"" : [
{
""Default"" : {
""ColorSchemes"": [
{
""UserDefined"": {
""AbNormal"": {
""foreground"": ""green"",
""background"": ""black""
}
}
}
]
}
}
}
}";
ConfigurationManager.Settings.Update (json, "test");
// Modify hotNormal background only
json = @"
{
""Themes"" : [
{
""Default"" : {
""ColorSchemes"": [
{
""UserDefined"": {
""hotNormal"": {
""background"": ""cyan""
}
}
}
]
}
}
}
}";
ConfigurationManager.Settings.Update (json, "test");
ConfigurationManager.Settings.Update ("{}}", "test");
Assert.NotEqual (0, ConfigurationManager.jsonErrors.Length);
Application.Shutdown ();
ConfigurationManager.ThrowOnJsonErrors = false;
}
[Fact, AutoInitShutdown]
public void LoadConfigurationFromAllSources_ShouldLoadSettingsFromAllSources ()
{
//var _configFilename = "config.json";
//// Arrange
//// Create a mock of the configuration files in all sources
//// Home directory
//string homeDir = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.UserProfile), ".tui");
//if (!Directory.Exists (homeDir)) {
// Directory.CreateDirectory (homeDir);
//}
//string globalConfigFile = Path.Combine (homeDir, _configFilename);
//string appSpecificConfigFile = Path.Combine (homeDir, "appname.config.json");
//File.WriteAllText (globalConfigFile, "{\"Settings\": {\"TestSetting\":\"Global\"}}");
//File.WriteAllText (appSpecificConfigFile, "{\"Settings\": {\"TestSetting\":\"AppSpecific\"}}");
//// App directory
//string appDir = Directory.GetCurrentDirectory ();
//string appDirGlobalConfigFile = Path.Combine (appDir, _configFilename);
//string appDirAppSpecificConfigFile = Path.Combine (appDir, "appname.config.json");
//File.WriteAllText (appDirGlobalConfigFile, "{\"Settings\": {\"TestSetting\":\"GlobalAppDir\"}}");
//File.WriteAllText (appDirAppSpecificConfigFile, "{\"Settings\": {\"TestSetting\":\"AppSpecificAppDir\"}}");
//// App resources
//// ...
//// Act
//ConfigurationManager.Locations = ConfigurationManager.ConfigLocation.All;
//ConfigurationManager.Load ();
//// Assert
//// Check that the settings from the highest precedence source are loaded
//Assert.Equal ("AppSpecific", ConfigurationManager.Config.Settings.TestSetting);
}
[Fact]
public void Load_FiresUpdated ()
{
ConfigurationManager.Reset ();
ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue = new Key (KeyCode.Q);
ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue = new Key (KeyCode.F);
ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue = new Key (KeyCode.B);
ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue = true;
ConfigurationManager.Updated += ConfigurationManager_Updated;
bool fired = false;
void ConfigurationManager_Updated (object sender, ConfigurationManagerEventArgs obj)
{
fired = true;
// assert
Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, ((Key)ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue).KeyCode);
Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, ((Key)ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue).KeyCode);
Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, ((Key)ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue).KeyCode);
Assert.False ((bool)ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue);
}
ConfigurationManager.Load (true);
// assert
Assert.True (fired);
ConfigurationManager.Updated -= ConfigurationManager_Updated;
}
[Fact]
public void Apply_FiresApplied ()
{
ConfigurationManager.Reset ();
ConfigurationManager.Applied += ConfigurationManager_Applied;
bool fired = false;
void ConfigurationManager_Applied (object sender, ConfigurationManagerEventArgs obj)
{
fired = true;
// assert
Assert.Equal (KeyCode.Q, Application.QuitKey.KeyCode);
Assert.Equal (KeyCode.F, Application.AlternateForwardKey.KeyCode);
Assert.Equal (KeyCode.B, Application.AlternateBackwardKey.KeyCode);
Assert.True (Application.IsMouseDisabled);
}
// act
ConfigurationManager.Settings ["Application.QuitKey"].PropertyValue = new Key (KeyCode.Q);
ConfigurationManager.Settings ["Application.AlternateForwardKey"].PropertyValue = new Key (KeyCode.F);
ConfigurationManager.Settings ["Application.AlternateBackwardKey"].PropertyValue = new Key (KeyCode.B);
ConfigurationManager.Settings ["Application.IsMouseDisabled"].PropertyValue = true;
ConfigurationManager.Apply ();
// assert
Assert.True (fired);
ConfigurationManager.Applied -= ConfigurationManager_Applied;
}
}
}