ConfigurationMangerTests.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Text.Json;
  7. using Xunit;
  8. using static Terminal.Gui.ConfigurationManager;
  9. namespace Terminal.Gui.ConfigurationTests;
  10. public class ConfigurationManagerTests {
  11. public static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions {
  12. Converters = {
  13. new AttributeJsonConverter (),
  14. new ColorJsonConverter ()
  15. }
  16. };
  17. [Fact ()]
  18. public void DeepMemberwiseCopyTest ()
  19. {
  20. // Value types
  21. string stringDest = "Destination";
  22. string stringSrc = "Source";
  23. object stringCopy = DeepMemberwiseCopy (stringSrc, stringDest);
  24. Assert.Equal (stringSrc, stringCopy);
  25. stringDest = "Destination";
  26. stringSrc = "Destination";
  27. stringCopy = DeepMemberwiseCopy (stringSrc, stringDest);
  28. Assert.Equal (stringSrc, stringCopy);
  29. stringDest = "Destination";
  30. stringSrc = null;
  31. stringCopy = DeepMemberwiseCopy (stringSrc, stringDest);
  32. Assert.Equal (stringSrc, stringCopy);
  33. stringDest = "Destination";
  34. stringSrc = string.Empty;
  35. stringCopy = DeepMemberwiseCopy (stringSrc, stringDest);
  36. Assert.Equal (stringSrc, stringCopy);
  37. bool boolDest = true;
  38. bool boolSrc = false;
  39. object boolCopy = DeepMemberwiseCopy (boolSrc, boolDest);
  40. Assert.Equal (boolSrc, boolCopy);
  41. boolDest = false;
  42. boolSrc = true;
  43. boolCopy = DeepMemberwiseCopy (boolSrc, boolDest);
  44. Assert.Equal (boolSrc, boolCopy);
  45. boolDest = true;
  46. boolSrc = true;
  47. boolCopy = DeepMemberwiseCopy (boolSrc, boolDest);
  48. Assert.Equal (boolSrc, boolCopy);
  49. boolDest = false;
  50. boolSrc = false;
  51. boolCopy = DeepMemberwiseCopy (boolSrc, boolDest);
  52. Assert.Equal (boolSrc, boolCopy);
  53. // Structs
  54. var attrDest = new Attribute (Color.Black);
  55. var attrSrc = new Attribute (Color.White);
  56. object attrCopy = DeepMemberwiseCopy (attrSrc, attrDest);
  57. Assert.Equal (attrSrc, attrCopy);
  58. // Classes
  59. var colorschemeDest = new ColorScheme () { Disabled = new Attribute (Color.Black) };
  60. var colorschemeSrc = new ColorScheme () { Disabled = new Attribute (Color.White) };
  61. object colorschemeCopy = DeepMemberwiseCopy (colorschemeSrc, colorschemeDest);
  62. Assert.Equal (colorschemeSrc, colorschemeCopy);
  63. // Dictionaries
  64. var dictDest = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.Black) } };
  65. var dictSrc = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.White) } };
  66. var dictCopy = (Dictionary<string, Attribute>)DeepMemberwiseCopy (dictSrc, dictDest);
  67. Assert.Equal (dictSrc, dictCopy);
  68. dictDest = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.Black) } };
  69. dictSrc = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.White) }, { "Normal", new Attribute (Color.Blue) } };
  70. dictCopy = (Dictionary<string, Attribute>)DeepMemberwiseCopy (dictSrc, dictDest);
  71. Assert.Equal (dictSrc, dictCopy);
  72. // src adds an item
  73. dictDest = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.Black) } };
  74. dictSrc = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.White) }, { "Normal", new Attribute (Color.Blue) } };
  75. dictCopy = (Dictionary<string, Attribute>)DeepMemberwiseCopy (dictSrc, dictDest);
  76. Assert.Equal (2, dictCopy.Count);
  77. Assert.Equal (dictSrc ["Disabled"], dictCopy ["Disabled"]);
  78. Assert.Equal (dictSrc ["Normal"], dictCopy ["Normal"]);
  79. // src updates only one item
  80. dictDest = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.Black) }, { "Normal", new Attribute (Color.White) } };
  81. dictSrc = new Dictionary<string, Attribute> () { { "Disabled", new Attribute (Color.White) } };
  82. dictCopy = (Dictionary<string, Attribute>)DeepMemberwiseCopy (dictSrc, dictDest);
  83. Assert.Equal (2, dictCopy.Count);
  84. Assert.Equal (dictSrc ["Disabled"], dictCopy ["Disabled"]);
  85. Assert.Equal (dictDest ["Normal"], dictCopy ["Normal"]);
  86. }
  87. //[Fact ()]
  88. //public void LoadFromJsonTest ()
  89. //{
  90. // Assert.True (false, "This test needs an implementation");
  91. //}
  92. //[Fact ()]
  93. //public void ToJsonTest ()
  94. //{
  95. // Assert.True (false, "This test needs an implementation");
  96. //}
  97. //[Fact ()]
  98. //public void UpdateConfigurationTest ()
  99. //{
  100. // Assert.True (false, "This test needs an implementation");
  101. //}
  102. //[Fact ()]
  103. //public void UpdateConfigurationFromFileTest ()
  104. //{
  105. // Assert.True (false, "This test needs an implementation");
  106. //}
  107. //[Fact ()]
  108. //public void SaveHardCodedDefaultsTest ()
  109. //{
  110. // Assert.True (false, "This test needs an implementation");
  111. //}
  112. //[Fact ()]
  113. //public void LoadGlobalFromLibraryResourceTest ()
  114. //{
  115. // Assert.True (false, "This test needs an implementation");
  116. //}
  117. //[Fact ()]
  118. //public void LoadGlobalFromAppDirectoryTest ()
  119. //{
  120. // Assert.True (false, "This test needs an implementation");
  121. //}
  122. //[Fact ()]
  123. //public void LoadGlobalFromHomeDirectoryTest ()
  124. //{
  125. // Assert.True (false, "This test needs an implementation");
  126. //}
  127. //[Fact ()]
  128. //public void LoadAppFromAppResourcesTest ()
  129. //{
  130. // Assert.True (false, "This test needs an implementation");
  131. //}
  132. //[Fact ()]
  133. //public void LoadAppFromAppDirectoryTest ()
  134. //{
  135. // Assert.True (false, "This test needs an implementation");
  136. //}
  137. //[Fact ()]
  138. //public void LoadAppFromHomeDirectoryTest ()
  139. //{
  140. // Assert.True (false, "This test needs an implementation");
  141. //}
  142. //[Fact ()]
  143. //public void LoadTest ()
  144. //{
  145. // Assert.True (false, "This test needs an implementation");
  146. //}
  147. /// <summary>
  148. /// Save the `config.json` file; this can be used to update the file in `Terminal.Gui.Resources.config.json'.
  149. /// </summary>
  150. /// <remarks>
  151. /// IMPORTANT: For the file generated to be valid, this must be the ONLY test run. Config Properties
  152. /// are all static and thus can be overwritten by other tests.</remarks>
  153. [Fact]
  154. public void SaveDefaults ()
  155. {
  156. Initialize ();
  157. Reset ();
  158. // Get the hard coded settings
  159. GetHardCodedDefaults ();
  160. // Serialize to a JSON string
  161. string json = ToJson ();
  162. // Write the JSON string to the file
  163. File.WriteAllText ("config.json", json);
  164. }
  165. [Fact]
  166. public void UseWithoutResetAsserts ()
  167. {
  168. Initialize ();
  169. Assert.Throws<InvalidOperationException> (() => _ = Settings);
  170. }
  171. [Fact]
  172. public void Reset_Resets ()
  173. {
  174. Locations = ConfigLocations.DefaultOnly;
  175. Reset ();
  176. Assert.NotEmpty (Themes);
  177. Assert.Equal ("Default", Themes.Theme);
  178. }
  179. [Fact]
  180. public void Reset_and_ResetLoadWithLibraryResourcesOnly_are_same ()
  181. {
  182. Locations = ConfigLocations.DefaultOnly;
  183. // arrange
  184. Reset ();
  185. Settings ["Application.QuitKey"].PropertyValue = new Key (KeyCode.Q);
  186. Settings ["Application.AlternateForwardKey"].PropertyValue = new Key (KeyCode.F);
  187. Settings ["Application.AlternateBackwardKey"].PropertyValue = new Key (KeyCode.B);
  188. Settings ["Application.IsMouseDisabled"].PropertyValue = true;
  189. Settings.Apply ();
  190. // assert apply worked
  191. Assert.Equal (KeyCode.Q, Application.QuitKey.KeyCode);
  192. Assert.Equal (KeyCode.F, Application.AlternateForwardKey.KeyCode);
  193. Assert.Equal (KeyCode.B, Application.AlternateBackwardKey.KeyCode);
  194. Assert.True (Application.IsMouseDisabled);
  195. //act
  196. Reset ();
  197. // assert
  198. Assert.NotEmpty (Themes);
  199. Assert.Equal ("Default", Themes.Theme);
  200. Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey.KeyCode);
  201. Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, Application.AlternateForwardKey.KeyCode);
  202. Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, Application.AlternateBackwardKey.KeyCode);
  203. Assert.False (Application.IsMouseDisabled);
  204. // arrange
  205. Settings ["Application.QuitKey"].PropertyValue = new Key (KeyCode.Q);
  206. Settings ["Application.AlternateForwardKey"].PropertyValue = new Key (KeyCode.F);
  207. Settings ["Application.AlternateBackwardKey"].PropertyValue = new Key (KeyCode.B);
  208. Settings ["Application.IsMouseDisabled"].PropertyValue = true;
  209. Settings.Apply ();
  210. Locations = ConfigLocations.DefaultOnly;
  211. // act
  212. Reset ();
  213. Load ();
  214. // assert
  215. Assert.NotEmpty (Themes);
  216. Assert.Equal ("Default", Themes.Theme);
  217. Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey.KeyCode);
  218. Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, Application.AlternateForwardKey.KeyCode);
  219. Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, Application.AlternateBackwardKey.KeyCode);
  220. Assert.False (Application.IsMouseDisabled);
  221. }
  222. [Fact]
  223. public void TestConfigProperties ()
  224. {
  225. Locations = ConfigLocations.All;
  226. Reset ();
  227. Assert.NotEmpty (Settings);
  228. // test that all ConfigProperites have our attribute
  229. Assert.All (Settings, item => Assert.NotEmpty (item.Value.PropertyInfo.CustomAttributes.Where (a => a.AttributeType == typeof (SerializableConfigurationProperty))));
  230. Assert.Empty (Settings.Where (cp => cp.Value.PropertyInfo.GetCustomAttribute (typeof (SerializableConfigurationProperty)) == null));
  231. // Application is a static class
  232. var pi = typeof (Application).GetProperty ("QuitKey");
  233. Assert.Equal (pi, Settings ["Application.QuitKey"].PropertyInfo);
  234. // FrameView is not a static class and DefaultBorderStyle is Scope.Scheme
  235. pi = typeof (FrameView).GetProperty ("DefaultBorderStyle");
  236. Assert.False (Settings.ContainsKey ("FrameView.DefaultBorderStyle"));
  237. Assert.True (Themes ["Default"].ContainsKey ("FrameView.DefaultBorderStyle"));
  238. }
  239. [Fact]
  240. public void TestConfigPropertyOmitClassName ()
  241. {
  242. // Color.ColorShemes is serialzied as "ColorSchemes", not "Colors.ColorSchemes"
  243. var pi = typeof (Colors).GetProperty ("ColorSchemes");
  244. var scp = (SerializableConfigurationProperty)pi.GetCustomAttribute (typeof (SerializableConfigurationProperty));
  245. Assert.True (scp.Scope == typeof (ThemeScope));
  246. Assert.True (scp.OmitClassName);
  247. Reset ();
  248. Assert.Equal (pi, Themes ["Default"] ["ColorSchemes"].PropertyInfo);
  249. }
  250. [Fact, AutoInitShutdown]
  251. public void TestConfigurationManagerToJson ()
  252. {
  253. Reset ();
  254. GetHardCodedDefaults ();
  255. var stream = ToStream ();
  256. Settings.Update (stream, "TestConfigurationManagerToJson");
  257. }
  258. [Fact] [AutoInitShutdown (configLocation: ConfigLocations.None)]
  259. public void TestConfigurationManagerInitDriver_NoLocations ()
  260. {
  261. }
  262. [Fact] [AutoInitShutdown (configLocation: ConfigLocations.DefaultOnly)]
  263. public void TestConfigurationManagerInitDriver ()
  264. {
  265. Assert.Equal ("Default", Themes.Theme);
  266. Assert.True (Themes.ContainsKey ("Default"));
  267. Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey.KeyCode);
  268. Assert.Equal (new Color (Color.White), Colors.ColorSchemes ["Base"].Normal.Foreground);
  269. Assert.Equal (new Color (Color.Blue), Colors.ColorSchemes ["Base"].Normal.Background);
  270. // Change Base
  271. var json = ToStream ();
  272. Settings.Update (json, "TestConfigurationManagerInitDriver");
  273. var colorSchemes = (Dictionary<string, ColorScheme>)Themes [Themes.Theme] ["ColorSchemes"].PropertyValue;
  274. Assert.Equal (Colors.Base, colorSchemes ["Base"]);
  275. Assert.Equal (Colors.TopLevel, colorSchemes ["TopLevel"]);
  276. Assert.Equal (Colors.Error, colorSchemes ["Error"]);
  277. Assert.Equal (Colors.Dialog, colorSchemes ["Dialog"]);
  278. Assert.Equal (Colors.Menu, colorSchemes ["Menu"]);
  279. Colors.Base = colorSchemes ["Base"];
  280. Colors.TopLevel = colorSchemes ["TopLevel"];
  281. Colors.Error = colorSchemes ["Error"];
  282. Colors.Dialog = colorSchemes ["Dialog"];
  283. Colors.Menu = colorSchemes ["Menu"];
  284. Assert.Equal (colorSchemes ["Base"], Colors.Base);
  285. Assert.Equal (colorSchemes ["TopLevel"], Colors.TopLevel);
  286. Assert.Equal (colorSchemes ["Error"], Colors.Error);
  287. Assert.Equal (colorSchemes ["Dialog"], Colors.Dialog);
  288. Assert.Equal (colorSchemes ["Menu"], Colors.Menu);
  289. }
  290. [Fact]
  291. public void TestConfigurationManagerUpdateFromJson ()
  292. {
  293. // Arrange
  294. string json = @"
  295. {
  296. ""$schema"": ""https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json"",
  297. ""Application.QuitKey"": ""Alt-Z"",
  298. ""Theme"": ""Default"",
  299. ""Themes"": [
  300. {
  301. ""Default"": {
  302. ""ColorSchemes"": [
  303. {
  304. ""TopLevel"": {
  305. ""Normal"": {
  306. ""Foreground"": ""BrightGreen"",
  307. ""Background"": ""Black""
  308. },
  309. ""Focus"": {
  310. ""Foreground"": ""White"",
  311. ""Background"": ""Cyan""
  312. },
  313. ""HotNormal"": {
  314. ""Foreground"": ""Yellow"",
  315. ""Background"": ""Black""
  316. },
  317. ""HotFocus"": {
  318. ""Foreground"": ""Blue"",
  319. ""Background"": ""Cyan""
  320. },
  321. ""Disabled"": {
  322. ""Foreground"": ""DarkGray"",
  323. ""Background"": ""Black""
  324. }
  325. }
  326. },
  327. {
  328. ""Base"": {
  329. ""Normal"": {
  330. ""Foreground"": ""White"",
  331. ""Background"": ""Blue""
  332. },
  333. ""Focus"": {
  334. ""Foreground"": ""Black"",
  335. ""Background"": ""Gray""
  336. },
  337. ""HotNormal"": {
  338. ""Foreground"": ""BrightCyan"",
  339. ""Background"": ""Blue""
  340. },
  341. ""HotFocus"": {
  342. ""Foreground"": ""BrightBlue"",
  343. ""Background"": ""Gray""
  344. },
  345. ""Disabled"": {
  346. ""Foreground"": ""DarkGray"",
  347. ""Background"": ""Blue""
  348. }
  349. }
  350. },
  351. {
  352. ""Dialog"": {
  353. ""Normal"": {
  354. ""Foreground"": ""Black"",
  355. ""Background"": ""Gray""
  356. },
  357. ""Focus"": {
  358. ""Foreground"": ""White"",
  359. ""Background"": ""DarkGray""
  360. },
  361. ""HotNormal"": {
  362. ""Foreground"": ""Blue"",
  363. ""Background"": ""Gray""
  364. },
  365. ""HotFocus"": {
  366. ""Foreground"": ""BrightYellow"",
  367. ""Background"": ""DarkGray""
  368. },
  369. ""Disabled"": {
  370. ""Foreground"": ""Gray"",
  371. ""Background"": ""DarkGray""
  372. }
  373. }
  374. },
  375. {
  376. ""Menu"": {
  377. ""Normal"": {
  378. ""Foreground"": ""White"",
  379. ""Background"": ""DarkGray""
  380. },
  381. ""Focus"": {
  382. ""Foreground"": ""White"",
  383. ""Background"": ""Black""
  384. },
  385. ""HotNormal"": {
  386. ""Foreground"": ""BrightYellow"",
  387. ""Background"": ""DarkGray""
  388. },
  389. ""HotFocus"": {
  390. ""Foreground"": ""BrightYellow"",
  391. ""Background"": ""Black""
  392. },
  393. ""Disabled"": {
  394. ""Foreground"": ""Gray"",
  395. ""Background"": ""DarkGray""
  396. }
  397. }
  398. },
  399. {
  400. ""Error"": {
  401. ""Normal"": {
  402. ""Foreground"": ""Red"",
  403. ""Background"": ""White""
  404. },
  405. ""Focus"": {
  406. ""Foreground"": ""Black"",
  407. ""Background"": ""BrightRed""
  408. },
  409. ""HotNormal"": {
  410. ""Foreground"": ""Black"",
  411. ""Background"": ""White""
  412. },
  413. ""HotFocus"": {
  414. ""Foreground"": ""White"",
  415. ""Background"": ""BrightRed""
  416. },
  417. ""Disabled"": {
  418. ""Foreground"": ""DarkGray"",
  419. ""Background"": ""White""
  420. }
  421. }
  422. }
  423. ],
  424. ""Dialog.DefaultButtonAlignment"": ""Center""
  425. }
  426. }
  427. ]
  428. }
  429. ";
  430. Reset ();
  431. ThrowOnJsonErrors = true;
  432. Settings.Update (json, "TestConfigurationManagerUpdateFromJson");
  433. Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, Application.QuitKey.KeyCode);
  434. Assert.Equal (KeyCode.Z | KeyCode.AltMask, ((Key)Settings ["Application.QuitKey"].PropertyValue).KeyCode);
  435. Assert.Equal ("Default", Themes.Theme);
  436. Assert.Equal (new Color (Color.White), Colors.ColorSchemes ["Base"].Normal.Foreground);
  437. Assert.Equal (new Color (Color.Blue), Colors.ColorSchemes ["Base"].Normal.Background);
  438. var colorSchemes = (Dictionary<string, ColorScheme>)Themes.First ().Value ["ColorSchemes"].PropertyValue;
  439. Assert.Equal (new Color (Color.White), colorSchemes ["Base"].Normal.Foreground);
  440. Assert.Equal (new Color (Color.Blue), colorSchemes ["Base"].Normal.Background);
  441. // Now re-apply
  442. Apply ();
  443. Assert.Equal (KeyCode.Z | KeyCode.AltMask, Application.QuitKey.KeyCode);
  444. Assert.Equal ("Default", Themes.Theme);
  445. Assert.Equal (new Color (Color.White), Colors.ColorSchemes ["Base"].Normal.Foreground);
  446. Assert.Equal (new Color (Color.Blue), Colors.ColorSchemes ["Base"].Normal.Background);
  447. }
  448. [Fact, AutoInitShutdown]
  449. public void TestConfigurationManagerInvalidJsonThrows ()
  450. {
  451. ThrowOnJsonErrors = true;
  452. // "yellow" is not a color
  453. string json = @"
  454. {
  455. ""Themes"" : [
  456. {
  457. ""Default"" : {
  458. ""ColorSchemes"": [
  459. {
  460. ""UserDefined"": {
  461. ""hotNormal"": {
  462. ""foreground"": ""brown"",
  463. ""background"": ""1234""
  464. }
  465. }
  466. }
  467. ]
  468. }
  469. }
  470. ]
  471. }";
  472. var jsonException = Assert.Throws<JsonException> (() => Settings.Update (json, "test"));
  473. Assert.Equal ("Unexpected color name: brown.", jsonException.Message);
  474. // AbNormal is not a ColorScheme attribute
  475. json = @"
  476. {
  477. ""Themes"" : [
  478. {
  479. ""Default"" : {
  480. ""ColorSchemes"": [
  481. {
  482. ""UserDefined"": {
  483. ""AbNormal"": {
  484. ""foreground"": ""green"",
  485. ""background"": ""black""
  486. }
  487. }
  488. }
  489. ]
  490. }
  491. }
  492. ]
  493. }";
  494. jsonException = Assert.Throws<JsonException> (() => Settings.Update (json, "test"));
  495. Assert.Equal ("Unrecognized ColorScheme Attribute name: AbNormal.", jsonException.Message);
  496. // Modify hotNormal background only
  497. json = @"
  498. {
  499. ""Themes"" : [
  500. {
  501. ""Default"" : {
  502. ""ColorSchemes"": [
  503. {
  504. ""UserDefined"": {
  505. ""hotNormal"": {
  506. ""background"": ""cyan""
  507. }
  508. }
  509. }
  510. ]
  511. }
  512. }
  513. ]
  514. }";
  515. jsonException = Assert.Throws<JsonException> (() => Settings.Update (json, "test"));
  516. Assert.Equal ("Both Foreground and Background colors must be provided.", jsonException.Message);
  517. // Unknown proeprty
  518. json = @"
  519. {
  520. ""Unknown"" : ""Not known""
  521. }";
  522. jsonException = Assert.Throws<JsonException> (() => Settings.Update (json, "test"));
  523. Assert.StartsWith ("Unknown property", jsonException.Message);
  524. Assert.Equal (0, jsonErrors.Length);
  525. ThrowOnJsonErrors = false;
  526. }
  527. [Fact]
  528. public void TestConfigurationManagerInvalidJsonLogs ()
  529. {
  530. Application.Init (new FakeDriver ());
  531. ThrowOnJsonErrors = false;
  532. // "brown" is not a color
  533. string json = @"
  534. {
  535. ""Themes"" : [
  536. {
  537. ""Default"" : {
  538. ""ColorSchemes"": [
  539. {
  540. ""UserDefined"": {
  541. ""hotNormal"": {
  542. ""foreground"": ""brown"",
  543. ""background"": ""1234""
  544. }
  545. }
  546. }
  547. ]
  548. }
  549. }
  550. }
  551. }";
  552. Settings.Update (json, "test");
  553. // AbNormal is not a ColorScheme attribute
  554. json = @"
  555. {
  556. ""Themes"" : [
  557. {
  558. ""Default"" : {
  559. ""ColorSchemes"": [
  560. {
  561. ""UserDefined"": {
  562. ""AbNormal"": {
  563. ""foreground"": ""green"",
  564. ""background"": ""black""
  565. }
  566. }
  567. }
  568. ]
  569. }
  570. }
  571. }
  572. }";
  573. Settings.Update (json, "test");
  574. // Modify hotNormal background only
  575. json = @"
  576. {
  577. ""Themes"" : [
  578. {
  579. ""Default"" : {
  580. ""ColorSchemes"": [
  581. {
  582. ""UserDefined"": {
  583. ""hotNormal"": {
  584. ""background"": ""cyan""
  585. }
  586. }
  587. }
  588. ]
  589. }
  590. }
  591. }
  592. }";
  593. Settings.Update (json, "test");
  594. Settings.Update ("{}}", "test");
  595. Assert.NotEqual (0, jsonErrors.Length);
  596. Application.Shutdown ();
  597. ThrowOnJsonErrors = false;
  598. }
  599. [Fact, AutoInitShutdown]
  600. public void LoadConfigurationFromAllSources_ShouldLoadSettingsFromAllSources ()
  601. {
  602. //var _configFilename = "config.json";
  603. //// Arrange
  604. //// Create a mock of the configuration files in all sources
  605. //// Home directory
  606. //string homeDir = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.UserProfile), ".tui");
  607. //if (!Directory.Exists (homeDir)) {
  608. // Directory.CreateDirectory (homeDir);
  609. //}
  610. //string globalConfigFile = Path.Combine (homeDir, _configFilename);
  611. //string appSpecificConfigFile = Path.Combine (homeDir, "appname.config.json");
  612. //File.WriteAllText (globalConfigFile, "{\"Settings\": {\"TestSetting\":\"Global\"}}");
  613. //File.WriteAllText (appSpecificConfigFile, "{\"Settings\": {\"TestSetting\":\"AppSpecific\"}}");
  614. //// App directory
  615. //string appDir = Directory.GetCurrentDirectory ();
  616. //string appDirGlobalConfigFile = Path.Combine (appDir, _configFilename);
  617. //string appDirAppSpecificConfigFile = Path.Combine (appDir, "appname.config.json");
  618. //File.WriteAllText (appDirGlobalConfigFile, "{\"Settings\": {\"TestSetting\":\"GlobalAppDir\"}}");
  619. //File.WriteAllText (appDirAppSpecificConfigFile, "{\"Settings\": {\"TestSetting\":\"AppSpecificAppDir\"}}");
  620. //// App resources
  621. //// ...
  622. //// Act
  623. //ConfigurationManager.Locations = ConfigurationManager.ConfigLocation.All;
  624. //ConfigurationManager.Load ();
  625. //// Assert
  626. //// Check that the settings from the highest precedence source are loaded
  627. //Assert.Equal ("AppSpecific", ConfigurationManager.Config.Settings.TestSetting);
  628. }
  629. [Fact]
  630. public void Load_FiresUpdated ()
  631. {
  632. Reset ();
  633. Settings ["Application.QuitKey"].PropertyValue = new Key (KeyCode.Q);
  634. Settings ["Application.AlternateForwardKey"].PropertyValue = new Key (KeyCode.F);
  635. Settings ["Application.AlternateBackwardKey"].PropertyValue = new Key (KeyCode.B);
  636. Settings ["Application.IsMouseDisabled"].PropertyValue = true;
  637. Updated += ConfigurationManager_Updated;
  638. bool fired = false;
  639. void ConfigurationManager_Updated (object sender, ConfigurationManagerEventArgs obj)
  640. {
  641. fired = true;
  642. // assert
  643. Assert.Equal (KeyCode.Q | KeyCode.CtrlMask, ((Key)Settings ["Application.QuitKey"].PropertyValue).KeyCode);
  644. Assert.Equal (KeyCode.PageDown | KeyCode.CtrlMask, ((Key)Settings ["Application.AlternateForwardKey"].PropertyValue).KeyCode);
  645. Assert.Equal (KeyCode.PageUp | KeyCode.CtrlMask, ((Key)Settings ["Application.AlternateBackwardKey"].PropertyValue).KeyCode);
  646. Assert.False ((bool)Settings ["Application.IsMouseDisabled"].PropertyValue);
  647. }
  648. Load (true);
  649. // assert
  650. Assert.True (fired);
  651. Updated -= ConfigurationManager_Updated;
  652. }
  653. [Fact]
  654. public void Apply_FiresApplied ()
  655. {
  656. Reset ();
  657. Applied += ConfigurationManager_Applied;
  658. bool fired = false;
  659. void ConfigurationManager_Applied (object sender, ConfigurationManagerEventArgs obj)
  660. {
  661. fired = true;
  662. // assert
  663. Assert.Equal (KeyCode.Q, Application.QuitKey.KeyCode);
  664. Assert.Equal (KeyCode.F, Application.AlternateForwardKey.KeyCode);
  665. Assert.Equal (KeyCode.B, Application.AlternateBackwardKey.KeyCode);
  666. Assert.True (Application.IsMouseDisabled);
  667. }
  668. // act
  669. Settings ["Application.QuitKey"].PropertyValue = new Key (KeyCode.Q);
  670. Settings ["Application.AlternateForwardKey"].PropertyValue = new Key (KeyCode.F);
  671. Settings ["Application.AlternateBackwardKey"].PropertyValue = new Key (KeyCode.B);
  672. Settings ["Application.IsMouseDisabled"].PropertyValue = true;
  673. Apply ();
  674. // assert
  675. Assert.True (fired);
  676. Applied -= ConfigurationManager_Applied;
  677. }
  678. }