WizardTests.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. namespace UnitTests.DialogTests;
  2. public class WizardTests
  3. {
  4. // =========== Wizard Tests
  5. [Fact]
  6. public void DefaultConstructor_SizedProperly ()
  7. {
  8. var wizard = new Wizard ();
  9. Assert.NotEqual (0, wizard.Width);
  10. Assert.NotEqual (0, wizard.Height);
  11. wizard.Dispose ();
  12. }
  13. [Fact]
  14. [AutoInitShutdown]
  15. public void Finish_Button_Closes ()
  16. {
  17. // https://github.com/gui-cs/Terminal.Gui/issues/1833
  18. Wizard wizard = new ();
  19. WizardStep step1 = new () { Title = "step1" };
  20. wizard.AddStep (step1);
  21. var finishedFired = false;
  22. wizard.Finished += (s, args) => { finishedFired = true; };
  23. var closedFired = false;
  24. wizard.Closed += (s, e) => { closedFired = true; };
  25. RunState runstate = Application.Begin (wizard);
  26. AutoInitShutdownAttribute.RunIteration ();
  27. wizard.NextFinishButton.InvokeCommand (Command.Accept);
  28. AutoInitShutdownAttribute.RunIteration ();
  29. Application.End (runstate);
  30. Assert.True (finishedFired);
  31. Assert.True (closedFired);
  32. step1.Dispose ();
  33. wizard.Dispose ();
  34. // Same test, but with two steps
  35. wizard = new ();
  36. step1 = new () { Title = "step1" };
  37. wizard.AddStep (step1);
  38. WizardStep step2 = new () { Title = "step2" };
  39. wizard.AddStep (step2);
  40. finishedFired = false;
  41. wizard.Finished += (s, args) => { finishedFired = true; };
  42. closedFired = false;
  43. wizard.Closed += (s, e) => { closedFired = true; };
  44. runstate = Application.Begin (wizard);
  45. AutoInitShutdownAttribute.RunIteration ();
  46. Assert.Equal (step1.Title, wizard.CurrentStep.Title);
  47. wizard.NextFinishButton.InvokeCommand (Command.Accept);
  48. Assert.False (finishedFired);
  49. Assert.False (closedFired);
  50. Assert.Equal (step2.Title, wizard.CurrentStep.Title);
  51. Assert.Equal (wizard.GetLastStep ().Title, wizard.CurrentStep.Title);
  52. wizard.NextFinishButton.InvokeCommand (Command.Accept);
  53. Application.End (runstate);
  54. Assert.True (finishedFired);
  55. Assert.True (closedFired);
  56. step1.Dispose ();
  57. step2.Dispose ();
  58. wizard.Dispose ();
  59. // Same test, but with two steps but the 1st one disabled
  60. wizard = new ();
  61. step1 = new () { Title = "step1" };
  62. wizard.AddStep (step1);
  63. step2 = new () { Title = "step2" };
  64. wizard.AddStep (step2);
  65. step1.Enabled = false;
  66. finishedFired = false;
  67. wizard.Finished += (s, args) => { finishedFired = true; };
  68. closedFired = false;
  69. wizard.Closed += (s, e) => { closedFired = true; };
  70. runstate = Application.Begin (wizard);
  71. AutoInitShutdownAttribute.RunIteration ();
  72. Assert.Equal (step2.Title, wizard.CurrentStep.Title);
  73. Assert.Equal (wizard.GetLastStep ().Title, wizard.CurrentStep.Title);
  74. wizard.NextFinishButton.InvokeCommand (Command.Accept);
  75. Application.End (runstate);
  76. Assert.True (finishedFired);
  77. Assert.True (closedFired);
  78. wizard.Dispose ();
  79. }
  80. [Fact]
  81. public void Navigate_GetFirstStep_Works ()
  82. {
  83. var wizard = new Wizard ();
  84. Assert.Null (wizard.GetFirstStep ());
  85. var step1 = new WizardStep { Title = "step1" };
  86. wizard.AddStep (step1);
  87. Assert.Equal (step1.Title, wizard.GetFirstStep ().Title);
  88. var step2 = new WizardStep { Title = "step2" };
  89. wizard.AddStep (step2);
  90. Assert.Equal (step1.Title, wizard.GetFirstStep ().Title);
  91. var step3 = new WizardStep { Title = "step3" };
  92. wizard.AddStep (step3);
  93. Assert.Equal (step1.Title, wizard.GetFirstStep ().Title);
  94. step1.Enabled = false;
  95. Assert.Equal (step2.Title, wizard.GetFirstStep ().Title);
  96. step1.Enabled = true;
  97. Assert.Equal (step1.Title, wizard.GetFirstStep ().Title);
  98. step1.Enabled = false;
  99. step2.Enabled = false;
  100. Assert.Equal (step3.Title, wizard.GetFirstStep ().Title);
  101. wizard.Dispose ();
  102. }
  103. [Fact]
  104. public void Navigate_GetLastStep_Works ()
  105. {
  106. var wizard = new Wizard ();
  107. Assert.Null (wizard.GetLastStep ());
  108. var step1 = new WizardStep { Title = "step1" };
  109. wizard.AddStep (step1);
  110. Assert.Equal (step1.Title, wizard.GetLastStep ().Title);
  111. var step2 = new WizardStep { Title = "step2" };
  112. wizard.AddStep (step2);
  113. Assert.Equal (step2.Title, wizard.GetLastStep ().Title);
  114. var step3 = new WizardStep { Title = "step3" };
  115. wizard.AddStep (step3);
  116. Assert.Equal (step3.Title, wizard.GetLastStep ().Title);
  117. step3.Enabled = false;
  118. Assert.Equal (step2.Title, wizard.GetLastStep ().Title);
  119. step3.Enabled = true;
  120. Assert.Equal (step3.Title, wizard.GetLastStep ().Title);
  121. step3.Enabled = false;
  122. step2.Enabled = false;
  123. Assert.Equal (step1.Title, wizard.GetLastStep ().Title);
  124. wizard.Dispose ();
  125. }
  126. [Fact]
  127. [AutoInitShutdown]
  128. public void Navigate_GetNextStep_Correct ()
  129. {
  130. var wizard = new Wizard ();
  131. // If no steps should be null
  132. Assert.Null (wizard.GetNextStep ());
  133. var step1 = new WizardStep { Title = "step1" };
  134. wizard.AddStep (step1);
  135. // If no current step, should be first step
  136. Assert.Equal (step1.Title, wizard.GetNextStep ().Title);
  137. wizard.CurrentStep = step1;
  138. // If there is 1 step it's current step should be null
  139. Assert.Null (wizard.GetNextStep ());
  140. // If one disabled step should be null
  141. step1.Enabled = false;
  142. Assert.Null (wizard.GetNextStep ());
  143. // If two steps and at 1 and step 2 is `Enabled = true`should be step 2
  144. var step2 = new WizardStep { Title = "step2" };
  145. wizard.AddStep (step2);
  146. Assert.Equal (step2.Title, wizard.GetNextStep ().Title);
  147. // If two steps and at 1 and step 2 is `Enabled = false` should be null
  148. step1.Enabled = true;
  149. wizard.CurrentStep = step1;
  150. step2.Enabled = false;
  151. Assert.Null (wizard.GetNextStep ());
  152. // If three steps with Step2.Enabled = true
  153. // At step 1 should be step 2
  154. // At step 2 should be step 3
  155. // At step 3 should be null
  156. var step3 = new WizardStep { Title = "step3" };
  157. wizard.AddStep (step3);
  158. step1.Enabled = true;
  159. wizard.CurrentStep = step1;
  160. step2.Enabled = true;
  161. step3.Enabled = true;
  162. Assert.Equal (step2.Title, wizard.GetNextStep ().Title);
  163. wizard.CurrentStep = step2;
  164. Assert.Equal (step3.Title, wizard.GetNextStep ().Title);
  165. wizard.CurrentStep = step3;
  166. Assert.Null (wizard.GetNextStep ());
  167. // If three steps with Step2.Enabled = false
  168. // At step 1 should be step 3
  169. // At step 3 should be null
  170. step1.Enabled = true;
  171. wizard.CurrentStep = step1;
  172. step2.Enabled = false;
  173. step3.Enabled = true;
  174. Assert.Equal (step3.Title, wizard.GetNextStep ().Title);
  175. wizard.CurrentStep = step3;
  176. Assert.Null (wizard.GetNextStep ());
  177. // If three steps with Step2.Enabled = false & Step3.Enabled = false
  178. // At step 1 should be null
  179. step1.Enabled = true;
  180. wizard.CurrentStep = step1;
  181. step2.Enabled = false;
  182. step3.Enabled = false;
  183. Assert.Null (wizard.GetNextStep ());
  184. // If no current step, GetNextStep provides equivalent to GetFirstStep
  185. wizard.CurrentStep = null;
  186. step1.Enabled = true;
  187. step2.Enabled = true;
  188. step3.Enabled = true;
  189. Assert.Equal (step1.Title, wizard.GetNextStep ().Title);
  190. step1.Enabled = false;
  191. step2.Enabled = true;
  192. step3.Enabled = true;
  193. Assert.Equal (step2.Title, wizard.GetNextStep ().Title);
  194. step1.Enabled = false;
  195. step2.Enabled = false;
  196. step3.Enabled = true;
  197. Assert.Equal (step3.Title, wizard.GetNextStep ().Title);
  198. step1.Enabled = false;
  199. step2.Enabled = true;
  200. step3.Enabled = false;
  201. Assert.Equal (step2.Title, wizard.GetNextStep ().Title);
  202. step1.Enabled = true;
  203. step2.Enabled = false;
  204. step3.Enabled = false;
  205. Assert.Equal (step1.Title, wizard.GetNextStep ().Title);
  206. wizard.Dispose ();
  207. }
  208. [Fact]
  209. [AutoInitShutdown]
  210. public void Navigate_GetPreviousStep_Correct ()
  211. {
  212. var wizard = new Wizard ();
  213. // If no steps should be null
  214. Assert.Null (wizard.GetPreviousStep ());
  215. var step1 = new WizardStep { Title = "step1" };
  216. wizard.AddStep (step1);
  217. // If no current step, should be last step
  218. Assert.Equal (step1.Title, wizard.GetPreviousStep ().Title);
  219. wizard.CurrentStep = step1;
  220. // If there is 1 step it's current step should be null
  221. Assert.Null (wizard.GetPreviousStep ());
  222. // If one disabled step should be null
  223. step1.Enabled = false;
  224. Assert.Null (wizard.GetPreviousStep ());
  225. // If two steps and at 2 and step 1 is `Enabled = true`should be step1
  226. var step2 = new WizardStep { Title = "step2" };
  227. wizard.AddStep (step2);
  228. wizard.CurrentStep = step2;
  229. step1.Enabled = true;
  230. Assert.Equal (step1.Title, wizard.GetPreviousStep ().Title);
  231. // If two steps and at 2 and step 1 is `Enabled = false` should be null
  232. step1.Enabled = false;
  233. Assert.Null (wizard.GetPreviousStep ());
  234. // If three steps with Step2.Enabled = true
  235. // At step 1 should be null
  236. // At step 2 should be step 1
  237. // At step 3 should be step 2
  238. var step3 = new WizardStep { Title = "step3" };
  239. wizard.AddStep (step3);
  240. step1.Enabled = true;
  241. wizard.CurrentStep = step1;
  242. step2.Enabled = true;
  243. step3.Enabled = true;
  244. Assert.Null (wizard.GetPreviousStep ());
  245. wizard.CurrentStep = step2;
  246. Assert.Equal (step1.Title, wizard.GetPreviousStep ().Title);
  247. wizard.CurrentStep = step3;
  248. Assert.Equal (step2.Title, wizard.GetPreviousStep ().Title);
  249. // If three steps with Step2.Enabled = false
  250. // At step 1 should be null
  251. // At step 3 should be step1
  252. step1.Enabled = true;
  253. step2.Enabled = false;
  254. step3.Enabled = true;
  255. wizard.CurrentStep = step1;
  256. Assert.Null (wizard.GetPreviousStep ());
  257. wizard.CurrentStep = step3;
  258. Assert.Equal (step1.Title, wizard.GetPreviousStep ().Title);
  259. // If three steps with Step1.Enabled = false & Step2.Enabled = false
  260. // At step 3 should be null
  261. // If no current step, GetPreviousStep provides equivalent to GetLastStep
  262. wizard.CurrentStep = null;
  263. step1.Enabled = true;
  264. step2.Enabled = true;
  265. step3.Enabled = true;
  266. Assert.Equal (step3.Title, wizard.GetPreviousStep ().Title);
  267. step1.Enabled = false;
  268. step2.Enabled = true;
  269. step3.Enabled = true;
  270. Assert.Equal (step3.Title, wizard.GetPreviousStep ().Title);
  271. step1.Enabled = false;
  272. step2.Enabled = false;
  273. step3.Enabled = true;
  274. Assert.Equal (step3.Title, wizard.GetPreviousStep ().Title);
  275. step1.Enabled = false;
  276. step2.Enabled = true;
  277. step3.Enabled = false;
  278. Assert.Equal (step2.Title, wizard.GetPreviousStep ().Title);
  279. step1.Enabled = true;
  280. step2.Enabled = false;
  281. step3.Enabled = false;
  282. Assert.Equal (step1.Title, wizard.GetPreviousStep ().Title);
  283. wizard.Dispose ();
  284. }
  285. [Fact]
  286. public void Navigate_GoBack_Works ()
  287. {
  288. // If zero steps do nothing
  289. // If one step do nothing (enabled or disabled)
  290. // If two steps
  291. // If current is 1 does nothing
  292. // If current is 2 does nothing
  293. // If 1 is enabled 2 becomes current
  294. // If 1 is disabled 1 stays current
  295. }
  296. [Fact]
  297. public void Navigate_GoNext_Works ()
  298. {
  299. // If zero steps do nothing
  300. // If one step do nothing (enabled or disabled)
  301. // If two steps
  302. // If current is 1
  303. // If 2 is enabled 2 becomes current
  304. // If 2 is disabled 1 stays current
  305. // If current is 2 does nothing
  306. }
  307. [Fact]
  308. [AutoInitShutdown]
  309. // This test verifies that a single step wizard shows the correct buttons
  310. // and that the title is correct
  311. public void OneStepWizard_Shows ()
  312. {
  313. var title = "1234";
  314. var stepTitle = "ABCD";
  315. var width = 30;
  316. var height = 7;
  317. Application.Driver?.SetScreenSize (width, height);
  318. // var btnBackText = "Back";
  319. var btnBack = string.Empty; // $"{Glyphs.LeftBracket} {btnBackText} {Glyphs.RightBracket}";
  320. var btnNextText = "Finish"; // "Next";
  321. var btnNext =
  322. $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} {btnNextText} {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}";
  323. var topRow =
  324. $"{Glyphs.ULCornerDbl}╡{title} - {stepTitle}╞{new (Glyphs.HLineDbl.ToString () [0], width - title.Length - stepTitle.Length - 7)}{Glyphs.URCornerDbl}";
  325. var row2 = $"{Glyphs.VLineDbl}{new (' ', width - 2)}{Glyphs.VLineDbl}";
  326. string row3 = row2;
  327. string row4 = row3;
  328. var separatorRow =
  329. $"{Glyphs.VLineDbl}{new (Glyphs.HLine.ToString () [0], width - 2)}{Glyphs.VLineDbl}";
  330. var buttonRow =
  331. $"{Glyphs.VLineDbl}{btnBack}{new (' ', width - btnBack.Length - btnNext.Length - 2)}{btnNext}{Glyphs.VLineDbl}";
  332. var bottomRow =
  333. $"{Glyphs.LLCornerDbl}{new (Glyphs.HLineDbl.ToString () [0], width - 2)}{Glyphs.LRCornerDbl}";
  334. Wizard wizard = new () { Title = title, Width = width, Height = height };
  335. wizard.AddStep (new () { Title = stepTitle });
  336. //wizard.LayoutSubViews ();
  337. RunState runstate = Application.Begin (wizard);
  338. AutoInitShutdownAttribute.RunIteration ();
  339. // TODO: Disabled until Dim.Auto is used in Dialog
  340. //DriverAsserts.AssertDriverContentsWithFrameAre (
  341. // $"{topRow}\n{row2}\n{row3}\n{row4}\n{separatorRow}\n{buttonRow}\n{bottomRow}",
  342. // _output
  343. // );
  344. Application.End (runstate);
  345. wizard.Dispose ();
  346. }
  347. [Fact]
  348. [AutoInitShutdown]
  349. // this test is needed because Wizard overrides Dialog's title behavior ("Title - StepTitle")
  350. public void Setting_Title_Works ()
  351. {
  352. var d = Application.Driver;
  353. var title = "1234";
  354. var stepTitle = " - ABCD";
  355. var width = 40;
  356. var height = 4;
  357. d.SetScreenSize (width, height);
  358. var btnNextText = "Finish";
  359. var btnNext =
  360. $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} {btnNextText} {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}";
  361. var topRow =
  362. $"{Glyphs.ULCornerDbl}╡{title}{stepTitle}╞{new (Glyphs.HLineDbl.ToString () [0], width - title.Length - stepTitle.Length - 4)}{Glyphs.URCornerDbl}";
  363. var separatorRow =
  364. $"{Glyphs.VLineDbl}{new (Glyphs.HLine.ToString () [0], width - 2)}{Glyphs.VLineDbl}";
  365. // Once this is fixed, revert to commented out line: https://github.com/gui-cs/Terminal.Gui/issues/1791
  366. var buttonRow =
  367. $"{Glyphs.VLineDbl}{new (' ', width - btnNext.Length - 2)}{btnNext}{Glyphs.VLineDbl}";
  368. //var buttonRow = $"{Glyphs.VDLine}{new String (' ', width - btnNext.Length - 2)}{btnNext}{Glyphs.VDLine}";
  369. var bottomRow =
  370. $"{Glyphs.LLCornerDbl}{new (Glyphs.HLineDbl.ToString () [0], width - 2)}{Glyphs.LRCornerDbl}";
  371. var wizard = new Wizard { Title = title, Width = width, Height = height };
  372. wizard.AddStep (new () { Title = "ABCD" });
  373. Application.End (Application.Begin (wizard));
  374. wizard.Dispose ();
  375. }
  376. [Fact]
  377. // This test verifies that the 2nd step in a wizard with more than 2 steps
  378. // shows the correct buttons on all steps
  379. // and that the title is correct
  380. public void ThreeStepWizard_Next_Shows_Steps ()
  381. {
  382. // verify step one
  383. // Next
  384. // verify step two
  385. // Back
  386. // verify step one again
  387. }
  388. [Fact]
  389. // This test verifies that the 2nd step in a wizard with 2 steps
  390. // shows the correct buttons on both steps
  391. // and that the title is correct
  392. public void TwoStepWizard_Next_Shows_SecondStep ()
  393. {
  394. // verify step one
  395. // Next
  396. // verify step two
  397. // Back
  398. // verify step one again
  399. }
  400. // =========== WizardStep Tests
  401. [Fact]
  402. public void WizardStep_ButtonText ()
  403. {
  404. // Verify default button text
  405. // Verify set actually changes property
  406. // Verify set actually changes buttons for the current step
  407. }
  408. [Fact]
  409. public void WizardStep_Set_Title_Fires_TitleChanged ()
  410. {
  411. var r = new Window ();
  412. Assert.Equal (string.Empty, r.Title);
  413. var expected = string.Empty;
  414. r.TitleChanged += (s, args) => { Assert.Equal (r.Title, args.Value); };
  415. expected = "title";
  416. r.Title = expected;
  417. Assert.Equal (expected, r.Title);
  418. expected = "another title";
  419. r.Title = expected;
  420. Assert.Equal (expected, r.Title);
  421. r.Dispose ();
  422. }
  423. [Fact]
  424. public void WizardStep_Set_Title_Fires_TitleChanging ()
  425. {
  426. var r = new Window ();
  427. Assert.Equal (string.Empty, r.Title);
  428. var expectedAfter = string.Empty;
  429. var expectedDuring = string.Empty;
  430. var cancel = false;
  431. r.TitleChanging += (s, args) =>
  432. {
  433. Assert.Equal (expectedDuring, args.NewValue);
  434. args.Cancel = cancel;
  435. };
  436. r.Title = expectedDuring = expectedAfter = "title";
  437. Assert.Equal (expectedAfter, r.Title);
  438. r.Title = expectedDuring = expectedAfter = "a different title";
  439. Assert.Equal (expectedAfter, r.Title);
  440. // Now setup cancelling the change and change it back to "title"
  441. cancel = true;
  442. r.Title = expectedDuring = "title";
  443. Assert.Equal (expectedAfter, r.Title);
  444. r.Dispose ();
  445. }
  446. [Fact]
  447. [AutoInitShutdown]
  448. // Verify a zero-step wizard doesn't crash and shows a blank wizard
  449. // and that the title is correct
  450. public void ZeroStepWizard_Shows ()
  451. {
  452. var title = "1234";
  453. var stepTitle = "";
  454. var width = 30;
  455. var height = 6;
  456. Application.Driver?.SetScreenSize (width, height);
  457. var btnBackText = "Back";
  458. var btnBack = $"{Glyphs.LeftBracket} {btnBackText} {Glyphs.RightBracket}";
  459. var btnNextText = "Finish";
  460. var btnNext =
  461. $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} {btnNextText} {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}";
  462. var topRow =
  463. $"{Glyphs.ULCornerDbl}╡{title}{stepTitle}╞{new (Glyphs.HLineDbl.ToString () [0], width - title.Length - stepTitle.Length - 4)}{Glyphs.URCornerDbl}";
  464. var row2 = $"{Glyphs.VLineDbl}{new (' ', width - 2)}{Glyphs.VLineDbl}";
  465. string row3 = row2;
  466. var separatorRow =
  467. $"{Glyphs.VLineDbl}{new (Glyphs.HLine.ToString () [0], width - 2)}{Glyphs.VLineDbl}";
  468. var buttonRow =
  469. $"{Glyphs.VLineDbl}{btnBack}{new (' ', width - btnBack.Length - btnNext.Length - 2)}{btnNext}{Glyphs.VLineDbl}";
  470. var bottomRow =
  471. $"{Glyphs.LLCornerDbl}{new (Glyphs.HLineDbl.ToString () [0], width - 2)}{Glyphs.LRCornerDbl}";
  472. var wizard = new Wizard { Title = title, Width = width, Height = height };
  473. RunState runstate = Application.Begin (wizard);
  474. // TODO: Disabled until Dim.Auto is used in Dialog
  475. //DriverAsserts.AssertDriverContentsWithFrameAre (
  476. // $"{topRow}\n{row2}\n{row3}\n{separatorRow}\n{buttonRow}\n{bottomRow}",
  477. // _output
  478. // );
  479. Application.End (runstate);
  480. wizard.Dispose ();
  481. }
  482. }