DialogTests.cs 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505
  1. #nullable enable
  2. using Xunit.Abstractions;
  3. namespace UnitTests.DialogTests;
  4. public class DialogTests (ITestOutputHelper output)
  5. {
  6. [Fact]
  7. [AutoInitShutdown]
  8. public void Add_Button_Works ()
  9. {
  10. SessionToken? sessionToken = null;
  11. var title = "1234";
  12. var btn1Text = "yes";
  13. var btn1 = $"{Glyphs.LeftBracket} {btn1Text} {Glyphs.RightBracket}";
  14. var btn2Text = "no";
  15. var btn2 = $"{Glyphs.LeftBracket} {btn2Text} {Glyphs.RightBracket}";
  16. // We test with one button first, but do this to get the width right for 2
  17. int width = $@"{Glyphs.VLine} {btn1} {btn2} {Glyphs.VLine}".Length;
  18. Application.Driver?.SetScreenSize (width, 1);
  19. // Override CM
  20. Dialog.DefaultButtonAlignment = Alignment.Center;
  21. Dialog.DefaultBorderStyle = LineStyle.Single;
  22. Dialog.DefaultShadow = ShadowStyle.None;
  23. Button.DefaultShadow = ShadowStyle.None;
  24. // Default (center)
  25. var dlg = new Dialog
  26. {
  27. Title = title,
  28. Width = width,
  29. Height = 1,
  30. ButtonAlignment = Alignment.Center,
  31. Buttons = [new () { Text = btn1Text }]
  32. };
  33. // Create with no top or bottom border to simplify testing button layout (no need to account for title etc..)
  34. dlg.Border!.Thickness = new (1, 0, 1, 0);
  35. sessionToken = Application.Begin (dlg);
  36. var buttonRow = $"{Glyphs.VLine} {btn1} {Glyphs.VLine}";
  37. AutoInitShutdownAttribute.RunIteration ();
  38. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  39. // Now add a second button
  40. buttonRow = $"{Glyphs.VLine} {btn1} {btn2} {Glyphs.VLine}";
  41. dlg.AddButton (new () { Text = btn2Text });
  42. AutoInitShutdownAttribute.RunIteration ();
  43. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  44. Application.End (sessionToken);
  45. dlg.Dispose ();
  46. // Justify
  47. dlg = new ()
  48. {
  49. Title = title,
  50. Width = width,
  51. Height = 1,
  52. ButtonAlignment = Alignment.Fill,
  53. Buttons = [new () { Text = btn1Text }]
  54. };
  55. // Create with no top or bottom border to simplify testing button layout (no need to account for title etc..)
  56. dlg.Border!.Thickness = new (1, 0, 1, 0);
  57. sessionToken = Application.Begin (dlg);
  58. AutoInitShutdownAttribute.RunIteration ();
  59. buttonRow = $"{Glyphs.VLine}{btn1} {Glyphs.VLine}";
  60. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  61. // Now add a second button
  62. buttonRow = $"{Glyphs.VLine}{btn1} {btn2}{Glyphs.VLine}";
  63. dlg.AddButton (new () { Text = btn2Text });
  64. AutoInitShutdownAttribute.RunIteration ();
  65. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  66. Application.End (sessionToken);
  67. dlg.Dispose ();
  68. // Right
  69. dlg = new ()
  70. {
  71. Title = title,
  72. Width = width,
  73. Height = 1,
  74. ButtonAlignment = Alignment.End,
  75. Buttons = [new () { Text = btn1Text }]
  76. };
  77. // Create with no top or bottom border to simplify testing button layout (no need to account for title etc..)
  78. dlg.Border!.Thickness = new (1, 0, 1, 0);
  79. sessionToken = Application.Begin (dlg);
  80. AutoInitShutdownAttribute.RunIteration ();
  81. buttonRow = $"{Glyphs.VLine}{new (' ', width - btn1.Length - 2)}{btn1}{Glyphs.VLine}";
  82. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  83. // Now add a second button
  84. buttonRow = $"{Glyphs.VLine} {btn1} {btn2}{Glyphs.VLine}";
  85. dlg.AddButton (new () { Text = btn2Text });
  86. AutoInitShutdownAttribute.RunIteration ();
  87. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  88. Application.End (sessionToken);
  89. dlg.Dispose ();
  90. // Left
  91. dlg = new ()
  92. {
  93. Title = title,
  94. Width = width,
  95. Height = 1,
  96. ButtonAlignment = Alignment.Start,
  97. Buttons = [new () { Text = btn1Text }]
  98. };
  99. // Create with no top or bottom border to simplify testing button layout (no need to account for title etc..)
  100. dlg.Border!.Thickness = new (1, 0, 1, 0);
  101. sessionToken = Application.Begin (dlg);
  102. AutoInitShutdownAttribute.RunIteration ();
  103. buttonRow = $"{Glyphs.VLine}{btn1}{new (' ', width - btn1.Length - 2)}{Glyphs.VLine}";
  104. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  105. // Now add a second button
  106. buttonRow = $"{Glyphs.VLine}{btn1} {btn2} {Glyphs.VLine}";
  107. dlg.AddButton (new () { Text = btn2Text });
  108. AutoInitShutdownAttribute.RunIteration ();
  109. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  110. Application.End (sessionToken);
  111. dlg.Dispose ();
  112. }
  113. [Fact]
  114. [AutoInitShutdown]
  115. public void ButtonAlignment_Four ()
  116. {
  117. SessionToken? sessionToken = null;
  118. Dialog.DefaultShadow = ShadowStyle.None;
  119. Button.DefaultShadow = ShadowStyle.None;
  120. var title = "1234";
  121. // E.g "|[ yes ][ no ][ maybe ]|"
  122. var btn1Text = "yes";
  123. var btn1 = $"{Glyphs.LeftBracket} {btn1Text} {Glyphs.RightBracket}";
  124. var btn2Text = "no";
  125. var btn2 = $"{Glyphs.LeftBracket} {btn2Text} {Glyphs.RightBracket}";
  126. var btn3Text = "maybe";
  127. var btn3 = $"{Glyphs.LeftBracket} {btn3Text} {Glyphs.RightBracket}";
  128. var btn4Text = "never";
  129. var btn4 = $"{Glyphs.LeftBracket} {btn4Text} {Glyphs.RightBracket}";
  130. var buttonRow = $"{Glyphs.VLine} {btn1} {btn2} {btn3} {btn4} {Glyphs.VLine}";
  131. int width = buttonRow.Length;
  132. Application.Driver?.SetScreenSize (buttonRow.Length, 3);
  133. // Default - Center
  134. (sessionToken, Dialog dlg) = BeginButtonTestDialog (
  135. title,
  136. width,
  137. Alignment.Center,
  138. new Button { Text = btn1Text },
  139. new Button { Text = btn2Text },
  140. new Button { Text = btn3Text },
  141. new Button { Text = btn4Text }
  142. );
  143. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  144. Application.End (sessionToken);
  145. dlg.Dispose ();
  146. // Justify
  147. buttonRow = $"{Glyphs.VLine}{btn1} {btn2} {btn3} {btn4}{Glyphs.VLine}";
  148. Assert.Equal (width, buttonRow.Length);
  149. (sessionToken, dlg) = BeginButtonTestDialog (
  150. title,
  151. width,
  152. Alignment.Fill,
  153. new Button { Text = btn1Text },
  154. new Button { Text = btn2Text },
  155. new Button { Text = btn3Text },
  156. new Button { Text = btn4Text }
  157. );
  158. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  159. Application.End (sessionToken);
  160. dlg.Dispose ();
  161. // Right
  162. buttonRow = $"{Glyphs.VLine} {btn1} {btn2} {btn3} {btn4}{Glyphs.VLine}";
  163. Assert.Equal (width, buttonRow.Length);
  164. (sessionToken, dlg) = BeginButtonTestDialog (
  165. title,
  166. width,
  167. Alignment.End,
  168. new Button { Text = btn1Text },
  169. new Button { Text = btn2Text },
  170. new Button { Text = btn3Text },
  171. new Button { Text = btn4Text }
  172. );
  173. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  174. Application.End (sessionToken);
  175. dlg.Dispose ();
  176. // Left
  177. buttonRow = $"{Glyphs.VLine}{btn1} {btn2} {btn3} {btn4} {Glyphs.VLine}";
  178. Assert.Equal (width, buttonRow.Length);
  179. (sessionToken, dlg) = BeginButtonTestDialog (
  180. title,
  181. width,
  182. Alignment.Start,
  183. new Button { Text = btn1Text },
  184. new Button { Text = btn2Text },
  185. new Button { Text = btn3Text },
  186. new Button { Text = btn4Text }
  187. );
  188. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  189. Application.End (sessionToken);
  190. dlg.Dispose ();
  191. }
  192. [Fact]
  193. [AutoInitShutdown]
  194. public void ButtonAlignment_Four_On_Too_Small_Width ()
  195. {
  196. SessionToken? sessionToken = null;
  197. Dialog.DefaultShadow = ShadowStyle.None;
  198. Button.DefaultShadow = ShadowStyle.None;
  199. var title = "1234";
  200. // E.g "|[ yes ][ no ][ maybe ][ never ]|"
  201. var btn1Text = "yes";
  202. var btn1 = $"{Glyphs.LeftBracket} {btn1Text} {Glyphs.RightBracket}";
  203. var btn2Text = "no";
  204. var btn2 = $"{Glyphs.LeftBracket} {btn2Text} {Glyphs.RightBracket}";
  205. var btn3Text = "maybe";
  206. var btn3 = $"{Glyphs.LeftBracket} {btn3Text} {Glyphs.RightBracket}";
  207. var btn4Text = "never";
  208. var btn4 = $"{Glyphs.LeftBracket} {btn4Text} {Glyphs.RightBracket}";
  209. var buttonRow = string.Empty;
  210. var width = 30;
  211. Application.Driver?.SetScreenSize (width, 1);
  212. // Default - Center
  213. buttonRow =
  214. $"{Glyphs.VLine} yes {Glyphs.RightBracket}{btn2}{btn3}{Glyphs.LeftBracket} never{Glyphs.VLine}";
  215. (sessionToken, Dialog dlg) = BeginButtonTestDialog (
  216. title,
  217. width,
  218. Alignment.Center,
  219. new Button { Text = btn1Text },
  220. new Button { Text = btn2Text },
  221. new Button { Text = btn3Text },
  222. new Button { Text = btn4Text }
  223. );
  224. Assert.Equal (new (width, 1), dlg.Frame.Size);
  225. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  226. Application.End (sessionToken);
  227. dlg.Dispose ();
  228. // Justify
  229. buttonRow =
  230. $"{Glyphs.VLine}{Glyphs.LeftBracket} yes {Glyphs.LeftBracket} no {Glyphs.LeftBracket} maybe {Glyphs.LeftBracket} never {Glyphs.RightBracket}{Glyphs.VLine}";
  231. (sessionToken, dlg) = BeginButtonTestDialog (
  232. title,
  233. width,
  234. Alignment.Fill,
  235. new Button { Text = btn1Text },
  236. new Button { Text = btn2Text },
  237. new Button { Text = btn3Text },
  238. new Button { Text = btn4Text }
  239. );
  240. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  241. Application.End (sessionToken);
  242. dlg.Dispose ();
  243. // Right
  244. buttonRow = $"{Glyphs.VLine}es {Glyphs.RightBracket}{btn2}{btn3}{btn4}{Glyphs.VLine}";
  245. Assert.Equal (width, buttonRow.Length);
  246. (sessionToken, dlg) = BeginButtonTestDialog (
  247. title,
  248. width,
  249. Alignment.End,
  250. new Button { Text = btn1Text },
  251. new Button { Text = btn2Text },
  252. new Button { Text = btn3Text },
  253. new Button { Text = btn4Text }
  254. );
  255. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  256. Application.End (sessionToken);
  257. dlg.Dispose ();
  258. // Left
  259. buttonRow = $"{Glyphs.VLine}{btn1}{btn2}{btn3}{Glyphs.LeftBracket} neve{Glyphs.VLine}";
  260. (sessionToken, dlg) = BeginButtonTestDialog (
  261. title,
  262. width,
  263. Alignment.Start,
  264. new Button { Text = btn1Text },
  265. new Button { Text = btn2Text },
  266. new Button { Text = btn3Text },
  267. new Button { Text = btn4Text }
  268. );
  269. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  270. Application.End (sessionToken);
  271. dlg.Dispose ();
  272. }
  273. [Fact]
  274. [AutoInitShutdown]
  275. public void ButtonAlignment_Four_WideOdd ()
  276. {
  277. SessionToken? sessionToken = null;
  278. Dialog.DefaultShadow = ShadowStyle.None;
  279. Button.DefaultShadow = ShadowStyle.None;
  280. var title = "1234";
  281. // E.g "|[ yes ][ no ][ maybe ]|"
  282. var btn1Text = "really long button 1";
  283. var btn1 = $"{Glyphs.LeftBracket} {btn1Text} {Glyphs.RightBracket}";
  284. var btn2Text = "really long button 2";
  285. var btn2 = $"{Glyphs.LeftBracket} {btn2Text} {Glyphs.RightBracket}";
  286. var btn3Text = "really long button 3";
  287. var btn3 = $"{Glyphs.LeftBracket} {btn3Text} {Glyphs.RightBracket}";
  288. var btn4Text = "really long button 44"; // 44 is intentional to make length different than rest
  289. var btn4 = $"{Glyphs.LeftBracket} {btn4Text} {Glyphs.RightBracket}";
  290. // Note extra spaces to make dialog even wider
  291. // 123456 1234567
  292. var buttonRow = $"{Glyphs.VLine} {btn1} {btn2} {btn3} {btn4} {Glyphs.VLine}";
  293. int width = buttonRow.Length;
  294. Application.Driver?.SetScreenSize (buttonRow.Length, 1);
  295. // Default - Center
  296. (sessionToken, Dialog dlg) = BeginButtonTestDialog (
  297. title,
  298. width,
  299. Alignment.Center,
  300. new Button { Text = btn1Text },
  301. new Button { Text = btn2Text },
  302. new Button { Text = btn3Text },
  303. new Button { Text = btn4Text }
  304. );
  305. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  306. Application.End (sessionToken);
  307. dlg.Dispose ();
  308. // Justify
  309. buttonRow = $"{Glyphs.VLine}{btn1} {btn2} {btn3} {btn4}{Glyphs.VLine}";
  310. Assert.Equal (width, buttonRow.Length);
  311. (sessionToken, dlg) = BeginButtonTestDialog (
  312. title,
  313. width,
  314. Alignment.Fill,
  315. new Button { Text = btn1Text },
  316. new Button { Text = btn2Text },
  317. new Button { Text = btn3Text },
  318. new Button { Text = btn4Text }
  319. );
  320. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  321. Application.End (sessionToken);
  322. dlg.Dispose ();
  323. // Right
  324. buttonRow = $"{Glyphs.VLine} {btn1} {btn2} {btn3} {btn4}{Glyphs.VLine}";
  325. Assert.Equal (width, buttonRow.Length);
  326. (sessionToken, dlg) = BeginButtonTestDialog (
  327. title,
  328. width,
  329. Alignment.End,
  330. new Button { Text = btn1Text },
  331. new Button { Text = btn2Text },
  332. new Button { Text = btn3Text },
  333. new Button { Text = btn4Text }
  334. );
  335. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  336. Application.End (sessionToken);
  337. dlg.Dispose ();
  338. // Left
  339. buttonRow = $"{Glyphs.VLine}{btn1} {btn2} {btn3} {btn4} {Glyphs.VLine}";
  340. Assert.Equal (width, buttonRow.Length);
  341. (sessionToken, dlg) = BeginButtonTestDialog (
  342. title,
  343. width,
  344. Alignment.Start,
  345. new Button { Text = btn1Text },
  346. new Button { Text = btn2Text },
  347. new Button { Text = btn3Text },
  348. new Button { Text = btn4Text }
  349. );
  350. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  351. Application.End (sessionToken);
  352. dlg.Dispose ();
  353. }
  354. [Fact]
  355. [AutoInitShutdown]
  356. public void ButtonAlignment_Four_Wider ()
  357. {
  358. SessionToken? sessionToken = null;
  359. Dialog.DefaultShadow = ShadowStyle.None;
  360. Button.DefaultShadow = ShadowStyle.None;
  361. var title = "1234";
  362. // E.g "|[ yes ][ no ][ maybe ]|"
  363. var btn1Text = "yes";
  364. var btn1 = $"{Glyphs.LeftBracket} {btn1Text} {Glyphs.RightBracket}";
  365. var btn2Text = "no";
  366. var btn2 = $"{Glyphs.LeftBracket} {btn2Text} {Glyphs.RightBracket}";
  367. var btn3Text = "你你你你你"; // This is a wide char
  368. var btn3 = $"{Glyphs.LeftBracket} {btn3Text} {Glyphs.RightBracket}";
  369. // Requires a Nerd Font
  370. var btn4Text = "\uE36E\uE36F\uE370\uE371\uE372\uE373";
  371. var btn4 = $"{Glyphs.LeftBracket} {btn4Text} {Glyphs.RightBracket}";
  372. // Note extra spaces to make dialog even wider
  373. // 123456 123456
  374. var buttonRow = $"{Glyphs.VLine} {btn1} {btn2} {btn3} {btn4} {Glyphs.VLine}";
  375. int width = buttonRow.GetColumns ();
  376. Application.Driver?.SetScreenSize (width, 3);
  377. // Default - Center
  378. (sessionToken, Dialog dlg) = BeginButtonTestDialog (
  379. title,
  380. width,
  381. Alignment.Center,
  382. new Button { Text = btn1Text },
  383. new Button { Text = btn2Text },
  384. new Button { Text = btn3Text },
  385. new Button { Text = btn4Text }
  386. );
  387. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  388. Application.End (sessionToken);
  389. dlg.Dispose ();
  390. // Justify
  391. buttonRow = $"{Glyphs.VLine}{btn1} {btn2} {btn3} {btn4}{Glyphs.VLine}";
  392. Assert.Equal (width, buttonRow.GetColumns ());
  393. (sessionToken, dlg) = BeginButtonTestDialog (
  394. title,
  395. width,
  396. Alignment.Fill,
  397. new Button { Text = btn1Text },
  398. new Button { Text = btn2Text },
  399. new Button { Text = btn3Text },
  400. new Button { Text = btn4Text }
  401. );
  402. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  403. Application.End (sessionToken);
  404. dlg.Dispose ();
  405. // Right
  406. buttonRow = $"{Glyphs.VLine} {btn1} {btn2} {btn3} {btn4}{Glyphs.VLine}";
  407. Assert.Equal (width, buttonRow.GetColumns ());
  408. (sessionToken, dlg) = BeginButtonTestDialog (
  409. title,
  410. width,
  411. Alignment.End,
  412. new Button { Text = btn1Text },
  413. new Button { Text = btn2Text },
  414. new Button { Text = btn3Text },
  415. new Button { Text = btn4Text }
  416. );
  417. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  418. Application.End (sessionToken);
  419. dlg.Dispose ();
  420. // Left
  421. buttonRow = $"{Glyphs.VLine}{btn1} {btn2} {btn3} {btn4} {Glyphs.VLine}";
  422. Assert.Equal (width, buttonRow.GetColumns ());
  423. (sessionToken, dlg) = BeginButtonTestDialog (
  424. title,
  425. width,
  426. Alignment.Start,
  427. new Button { Text = btn1Text },
  428. new Button { Text = btn2Text },
  429. new Button { Text = btn3Text },
  430. new Button { Text = btn4Text }
  431. );
  432. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  433. Application.End (sessionToken);
  434. dlg.Dispose ();
  435. }
  436. [Fact]
  437. [AutoInitShutdown]
  438. public void ButtonAlignment_One ()
  439. {
  440. SessionToken? sessionToken = null;
  441. Dialog.DefaultShadow = ShadowStyle.None;
  442. Button.DefaultShadow = ShadowStyle.None;
  443. var title = "1234";
  444. // E.g "|[ ok ]|"
  445. var btnText = "ok";
  446. var buttonRow =
  447. $"{Glyphs.VLine} {Glyphs.LeftBracket} {btnText} {Glyphs.RightBracket} {Glyphs.VLine}";
  448. int width = buttonRow.Length;
  449. Application.Driver?.SetScreenSize (width, 1);
  450. (sessionToken, Dialog dlg) = BeginButtonTestDialog (
  451. title,
  452. width,
  453. Alignment.Center,
  454. new Button { Text = btnText }
  455. );
  456. // Center
  457. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  458. Application.End (sessionToken);
  459. dlg.Dispose ();
  460. // Justify
  461. buttonRow =
  462. $"{Glyphs.VLine}{Glyphs.LeftBracket} {btnText} {Glyphs.RightBracket} {Glyphs.VLine}";
  463. Assert.Equal (width, buttonRow.Length);
  464. (sessionToken, dlg) = BeginButtonTestDialog (
  465. title,
  466. width,
  467. Alignment.Fill,
  468. new Button { Text = btnText }
  469. );
  470. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  471. Application.End (sessionToken);
  472. dlg.Dispose ();
  473. // Right
  474. buttonRow =
  475. $"{Glyphs.VLine} {Glyphs.LeftBracket} {btnText} {Glyphs.RightBracket}{Glyphs.VLine}";
  476. Assert.Equal (width, buttonRow.Length);
  477. (sessionToken, dlg) = BeginButtonTestDialog (
  478. title,
  479. width,
  480. Alignment.End,
  481. new Button { Text = btnText }
  482. );
  483. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  484. Application.End (sessionToken);
  485. dlg.Dispose ();
  486. // Left
  487. buttonRow =
  488. $"{Glyphs.VLine}{Glyphs.LeftBracket} {btnText} {Glyphs.RightBracket} {Glyphs.VLine}";
  489. Assert.Equal (width, buttonRow.Length);
  490. (sessionToken, dlg) = BeginButtonTestDialog (
  491. title,
  492. width,
  493. Alignment.Start,
  494. new Button { Text = btnText }
  495. );
  496. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  497. Application.End (sessionToken);
  498. dlg.Dispose ();
  499. // Wider
  500. buttonRow =
  501. $"{Glyphs.VLine} {Glyphs.LeftBracket} {btnText} {Glyphs.RightBracket} {Glyphs.VLine}";
  502. width = buttonRow.Length;
  503. Application.Driver?.SetScreenSize (width, 1);
  504. (sessionToken, dlg) = BeginButtonTestDialog (
  505. title,
  506. width,
  507. Alignment.Center,
  508. new Button { Text = btnText }
  509. );
  510. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  511. Application.End (sessionToken);
  512. dlg.Dispose ();
  513. // Justify
  514. buttonRow =
  515. $"{Glyphs.VLine}{Glyphs.LeftBracket} {btnText} {Glyphs.RightBracket} {Glyphs.VLine}";
  516. Assert.Equal (width, buttonRow.Length);
  517. (sessionToken, dlg) = BeginButtonTestDialog (
  518. title,
  519. width,
  520. Alignment.Fill,
  521. new Button { Text = btnText }
  522. );
  523. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  524. Application.End (sessionToken);
  525. dlg.Dispose ();
  526. // Right
  527. buttonRow =
  528. $"{Glyphs.VLine} {Glyphs.LeftBracket} {btnText} {Glyphs.RightBracket}{Glyphs.VLine}";
  529. Assert.Equal (width, buttonRow.Length);
  530. (sessionToken, dlg) = BeginButtonTestDialog (
  531. title,
  532. width,
  533. Alignment.End,
  534. new Button { Text = btnText }
  535. );
  536. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  537. Application.End (sessionToken);
  538. dlg.Dispose ();
  539. // Left
  540. buttonRow =
  541. $"{Glyphs.VLine}{Glyphs.LeftBracket} {btnText} {Glyphs.RightBracket} {Glyphs.VLine}";
  542. Assert.Equal (width, buttonRow.Length);
  543. (sessionToken, dlg) = BeginButtonTestDialog (
  544. title,
  545. width,
  546. Alignment.Start,
  547. new Button { Text = btnText }
  548. );
  549. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  550. Application.End (sessionToken);
  551. dlg.Dispose ();
  552. }
  553. [Fact]
  554. [AutoInitShutdown]
  555. public void ButtonAlignment_Three ()
  556. {
  557. SessionToken? sessionToken = null;
  558. Dialog.DefaultShadow = ShadowStyle.None;
  559. Button.DefaultShadow = ShadowStyle.None;
  560. var title = "1234";
  561. // E.g "|[ yes ][ no ][ maybe ]|"
  562. var btn1Text = "yes";
  563. var btn1 = $"{Glyphs.LeftBracket} {btn1Text} {Glyphs.RightBracket}";
  564. var btn2Text = "no";
  565. var btn2 = $"{Glyphs.LeftBracket} {btn2Text} {Glyphs.RightBracket}";
  566. var btn3Text = "maybe";
  567. var btn3 = $"{Glyphs.LeftBracket} {btn3Text} {Glyphs.RightBracket}";
  568. var buttonRow = $@"{Glyphs.VLine} {btn1} {btn2} {btn3} {Glyphs.VLine}";
  569. int width = buttonRow.Length;
  570. Application.Driver?.SetScreenSize (buttonRow.Length, 3);
  571. (sessionToken, Dialog dlg) = BeginButtonTestDialog (
  572. title,
  573. width,
  574. Alignment.Center,
  575. new Button { Text = btn1Text },
  576. new Button { Text = btn2Text },
  577. new Button { Text = btn3Text }
  578. );
  579. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  580. Application.End (sessionToken);
  581. dlg.Dispose ();
  582. // Justify
  583. buttonRow = $@"{Glyphs.VLine}{btn1} {btn2} {btn3}{Glyphs.VLine}";
  584. Assert.Equal (width, buttonRow.Length);
  585. (sessionToken, dlg) = BeginButtonTestDialog (
  586. title,
  587. width,
  588. Alignment.Fill,
  589. new Button { Text = btn1Text },
  590. new Button { Text = btn2Text },
  591. new Button { Text = btn3Text }
  592. );
  593. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  594. Application.End (sessionToken);
  595. dlg.Dispose ();
  596. // Right
  597. buttonRow = $@"{Glyphs.VLine} {btn1} {btn2} {btn3}{Glyphs.VLine}";
  598. Assert.Equal (width, buttonRow.Length);
  599. (sessionToken, dlg) = BeginButtonTestDialog (
  600. title,
  601. width,
  602. Alignment.End,
  603. new Button { Text = btn1Text },
  604. new Button { Text = btn2Text },
  605. new Button { Text = btn3Text }
  606. );
  607. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  608. Application.End (sessionToken);
  609. dlg.Dispose ();
  610. // Left
  611. buttonRow = $@"{Glyphs.VLine}{btn1} {btn2} {btn3} {Glyphs.VLine}";
  612. Assert.Equal (width, buttonRow.Length);
  613. (sessionToken, dlg) = BeginButtonTestDialog (
  614. title,
  615. width,
  616. Alignment.Start,
  617. new Button { Text = btn1Text },
  618. new Button { Text = btn2Text },
  619. new Button { Text = btn3Text }
  620. );
  621. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  622. Application.End (sessionToken);
  623. dlg.Dispose ();
  624. }
  625. [Fact]
  626. [AutoInitShutdown]
  627. public void ButtonAlignment_Two ()
  628. {
  629. SessionToken? sessionToken = null;
  630. Dialog.DefaultShadow = ShadowStyle.None;
  631. Button.DefaultShadow = ShadowStyle.None;
  632. var title = "1234";
  633. // E.g "|[ yes ][ no ]|"
  634. var btn1Text = "yes";
  635. var btn1 = $"{Glyphs.LeftBracket} {btn1Text} {Glyphs.RightBracket}";
  636. var btn2Text = "no";
  637. var btn2 = $"{Glyphs.LeftBracket} {btn2Text} {Glyphs.RightBracket}";
  638. var buttonRow = $@"{Glyphs.VLine} {btn1} {btn2} {Glyphs.VLine}";
  639. int width = buttonRow.Length;
  640. Application.Driver?.SetScreenSize (buttonRow.Length, 3);
  641. (sessionToken, Dialog dlg) = BeginButtonTestDialog (
  642. title,
  643. width,
  644. Alignment.Center,
  645. new Button { Text = btn1Text },
  646. new Button { Text = btn2Text }
  647. );
  648. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  649. Application.End (sessionToken);
  650. dlg.Dispose ();
  651. // Justify
  652. buttonRow = $@"{Glyphs.VLine}{btn1} {btn2}{Glyphs.VLine}";
  653. Assert.Equal (width, buttonRow.Length);
  654. (sessionToken, dlg) = BeginButtonTestDialog (
  655. title,
  656. width,
  657. Alignment.Fill,
  658. new Button { Text = btn1Text },
  659. new Button { Text = btn2Text }
  660. );
  661. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  662. Application.End (sessionToken);
  663. dlg.Dispose ();
  664. // Right
  665. buttonRow = $@"{Glyphs.VLine} {btn1} {btn2}{Glyphs.VLine}";
  666. Assert.Equal (width, buttonRow.Length);
  667. (sessionToken, dlg) = BeginButtonTestDialog (
  668. title,
  669. width,
  670. Alignment.End,
  671. new Button { Text = btn1Text },
  672. new Button { Text = btn2Text }
  673. );
  674. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  675. Application.End (sessionToken);
  676. dlg.Dispose ();
  677. // Left
  678. buttonRow = $@"{Glyphs.VLine}{btn1} {btn2} {Glyphs.VLine}";
  679. Assert.Equal (width, buttonRow.Length);
  680. (sessionToken, dlg) = BeginButtonTestDialog (
  681. title,
  682. width,
  683. Alignment.Start,
  684. new Button { Text = btn1Text },
  685. new Button { Text = btn2Text }
  686. );
  687. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  688. Application.End (sessionToken);
  689. dlg.Dispose ();
  690. }
  691. [Fact]
  692. [AutoInitShutdown]
  693. public void ButtonAlignment_Two_Hidden ()
  694. {
  695. SessionToken? sessionToken = null;
  696. Dialog.DefaultShadow = ShadowStyle.None;
  697. Button.DefaultShadow = ShadowStyle.None;
  698. var title = "1234";
  699. // E.g "|[ yes ][ no ]|"
  700. var btn1Text = "yes";
  701. var btn1 = $"{Glyphs.LeftBracket} {btn1Text} {Glyphs.RightBracket}";
  702. var btn2Text = "no";
  703. var btn2 = $"{Glyphs.LeftBracket} {btn2Text} {Glyphs.RightBracket}";
  704. var buttonRow = $@"{Glyphs.VLine} {btn1} {btn2} {Glyphs.VLine}";
  705. int width = buttonRow.Length;
  706. Application.Driver?.SetScreenSize (buttonRow.Length, 3);
  707. // Default (Center)
  708. Button button1 = new () { Text = btn1Text };
  709. Button button2 = new () { Text = btn2Text };
  710. (sessionToken, Dialog dlg) = BeginButtonTestDialog (title, width, Alignment.Center, button1, button2);
  711. button1.Visible = false;
  712. AutoInitShutdownAttribute.RunIteration ();
  713. buttonRow = $@"{Glyphs.VLine} {btn2} {Glyphs.VLine}";
  714. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  715. Application.End (sessionToken);
  716. dlg.Dispose ();
  717. // Justify
  718. Assert.Equal (width, buttonRow.Length);
  719. button1 = new () { Text = btn1Text };
  720. button2 = new () { Text = btn2Text };
  721. (sessionToken, dlg) = BeginButtonTestDialog (title, width, Alignment.Fill, button1, button2);
  722. button1.Visible = false;
  723. AutoInitShutdownAttribute.RunIteration ();
  724. buttonRow = $@"{Glyphs.VLine} {btn2}{Glyphs.VLine}";
  725. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  726. Application.End (sessionToken);
  727. dlg.Dispose ();
  728. // Right
  729. Assert.Equal (width, buttonRow.Length);
  730. button1 = new () { Text = btn1Text };
  731. button2 = new () { Text = btn2Text };
  732. (sessionToken, dlg) = BeginButtonTestDialog (title, width, Alignment.End, button1, button2);
  733. button1.Visible = false;
  734. AutoInitShutdownAttribute.RunIteration ();
  735. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  736. Application.End (sessionToken);
  737. dlg.Dispose ();
  738. // Left
  739. Assert.Equal (width, buttonRow.Length);
  740. button1 = new () { Text = btn1Text };
  741. button2 = new () { Text = btn2Text };
  742. (sessionToken, dlg) = BeginButtonTestDialog (title, width, Alignment.Start, button1, button2);
  743. button1.Visible = false;
  744. AutoInitShutdownAttribute.RunIteration ();
  745. buttonRow = $@"{Glyphs.VLine} {btn2} {Glyphs.VLine}";
  746. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  747. Application.End (sessionToken);
  748. dlg.Dispose ();
  749. }
  750. [Fact]
  751. [AutoInitShutdown]
  752. public void Can_Access_Cancel_Property_After_Run ()
  753. {
  754. Dialog dlg = new ();
  755. ApplicationImpl.Instance.StopAfterFirstIteration = true;
  756. Application.Run (dlg);
  757. #if DEBUG_IDISPOSABLE
  758. Assert.False (dlg.WasDisposed);
  759. #endif
  760. Assert.False (dlg.Canceled);
  761. // Run it again is possible because it isn't disposed yet
  762. Application.Run (dlg);
  763. // Run another view without dispose the prior will throw an assertion
  764. #if DEBUG_IDISPOSABLE
  765. Dialog dlg2 = new ();
  766. // Exception exception = Record.Exception (() => Application.Run (dlg2));
  767. // Assert.NotNull (exception);
  768. dlg.Dispose ();
  769. // Now it's possible to tun dlg2 without throw
  770. Application.Run (dlg2);
  771. Assert.True (dlg.WasDisposed);
  772. Assert.False (dlg2.WasDisposed);
  773. dlg2.Dispose ();
  774. Application.Shutdown ();
  775. Assert.True (dlg2.WasDisposed);
  776. #endif
  777. }
  778. [Fact (Skip = "Convoluted test that needs to be rewritten")]
  779. [AutoInitShutdown]
  780. public void Dialog_In_Window_With_Size_One_Button_Aligns ()
  781. {
  782. Application.Driver?.SetScreenSize (20, 5);
  783. // Override CM
  784. Window.DefaultBorderStyle = LineStyle.Single;
  785. Dialog.DefaultButtonAlignment = Alignment.Center;
  786. Dialog.DefaultBorderStyle = LineStyle.Single;
  787. Dialog.DefaultShadow = ShadowStyle.None;
  788. Button.DefaultShadow = ShadowStyle.None;
  789. var win = new Window ();
  790. var iterations = 0;
  791. Application.Iteration += OnApplicationOnIteration;
  792. var btn = $"{Glyphs.LeftBracket} Ok {Glyphs.RightBracket}";
  793. win.IsModalChanged += (s, a) =>
  794. {
  795. if (!a.Value)
  796. {
  797. return;
  798. }
  799. var dlg = new Dialog { Width = 18, Height = 3, Buttons = [new () { Text = "Ok" }] };
  800. dlg.IsModalChanged += (s, a) =>
  801. {
  802. AutoInitShutdownAttribute.RunIteration ();
  803. var expected = @$"
  804. ┌──────────────────┐
  805. │┌────────────────┐│
  806. ││ {btn} ││
  807. │└────────────────┘│
  808. └──────────────────┘";
  809. _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output);
  810. };
  811. Application.Run (dlg);
  812. dlg.Dispose ();
  813. };
  814. Application.Run (win);
  815. Application.Iteration -= OnApplicationOnIteration;
  816. win.Dispose ();
  817. return;
  818. void OnApplicationOnIteration (object? s, EventArgs<IApplication?> a)
  819. {
  820. if (++iterations > 2)
  821. {
  822. Application.RequestStop ();
  823. }
  824. }
  825. }
  826. [Theory]
  827. [AutoInitShutdown]
  828. [InlineData (
  829. 5,
  830. @"
  831. ┌┌───────────────┐─┐
  832. ││ │ │
  833. ││ ⟦ Ok ⟧ │ │
  834. │└───────────────┘ │
  835. └──────────────────┘"
  836. )]
  837. [InlineData (
  838. 6,
  839. @"
  840. ┌┌───────────────┐─┐
  841. ││ │ │
  842. ││ │ │
  843. ││ ⟦ Ok ⟧ │ │
  844. │└───────────────┘ │
  845. └──────────────────┘"
  846. )]
  847. [InlineData (
  848. 7,
  849. @"
  850. ┌──────────────────┐
  851. │┌───────────────┐ │
  852. ││ │ │
  853. ││ │ │
  854. ││ ⟦ Ok ⟧ │ │
  855. │└───────────────┘ │
  856. └──────────────────┘"
  857. )]
  858. [InlineData (
  859. 8,
  860. @"
  861. ┌──────────────────┐
  862. │┌───────────────┐ │
  863. ││ │ │
  864. ││ │ │
  865. ││ │ │
  866. ││ ⟦ Ok ⟧ │ │
  867. │└───────────────┘ │
  868. └──────────────────┘"
  869. )]
  870. [InlineData (
  871. 9,
  872. @"
  873. ┌──────────────────┐
  874. │┌───────────────┐ │
  875. ││ │ │
  876. ││ │ │
  877. ││ │ │
  878. ││ │ │
  879. ││ ⟦ Ok ⟧ │ │
  880. │└───────────────┘ │
  881. └──────────────────┘"
  882. )]
  883. public void Dialog_In_Window_Without_Size_One_Button_Aligns (int height, string expected)
  884. {
  885. Application.Driver?.SetScreenSize (20, height);
  886. var win = new Window ();
  887. int iterations = -1;
  888. // Override CM
  889. Dialog.DefaultButtonAlignment = Alignment.Center;
  890. Dialog.DefaultBorderStyle = LineStyle.Single;
  891. Dialog.DefaultShadow = ShadowStyle.None;
  892. Button.DefaultShadow = ShadowStyle.None;
  893. Application.Iteration += OnApplicationOnIteration;
  894. Application.Run (win);
  895. Application.Iteration -= OnApplicationOnIteration;
  896. win.Dispose ();
  897. return;
  898. void OnApplicationOnIteration (object? s, EventArgs<IApplication?> a)
  899. {
  900. iterations++;
  901. if (iterations == 0)
  902. {
  903. var dlg = new Dialog { Buttons = [new () { Text = "Ok" }], Width = Dim.Percent (85), Height = Dim.Percent (85) };
  904. Application.Run (dlg);
  905. dlg.Dispose ();
  906. }
  907. else if (iterations == 1)
  908. {
  909. AutoInitShutdownAttribute.RunIteration ();
  910. // BUGBUG: This seems wrong; is it a bug in Dim.Percent(85)?? No
  911. _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output);
  912. }
  913. else
  914. {
  915. Application.RequestStop ();
  916. }
  917. }
  918. }
  919. [Fact (Skip = "Convoluted test that needs to be rewritten")]
  920. [AutoInitShutdown]
  921. public void Dialog_Opened_From_Another_Dialog ()
  922. {
  923. Application.Driver?.SetScreenSize (30, 10);
  924. // Override CM
  925. Dialog.DefaultButtonAlignment = Alignment.Center;
  926. Dialog.DefaultBorderStyle = LineStyle.Single;
  927. Dialog.DefaultShadow = ShadowStyle.None;
  928. Button.DefaultShadow = ShadowStyle.None;
  929. var btn1 = new Button { Text = "press me 1" };
  930. Button? btn2 = null;
  931. Button? btn3 = null;
  932. string? expected = null;
  933. btn1.Accepting += (s, e) =>
  934. {
  935. btn2 = new () { Text = "Show Sub" };
  936. btn3 = new () { Text = "Close" };
  937. btn3.Accepting += (s, e) => Application.RequestStop ();
  938. btn2.Accepting += (s, e) =>
  939. {
  940. // Don't test MessageBox in Dialog unit tests!
  941. var subBtn = new Button { Text = "Ok", IsDefault = true };
  942. var subDlg = new Dialog { Text = "ya", Width = 20, Height = 5, Buttons = [subBtn] };
  943. subBtn.Accepting += (s, e) => Application.RequestStop (subDlg);
  944. Application.Run (subDlg);
  945. };
  946. var dlg = new Dialog
  947. {
  948. Buttons = [btn2, btn3],
  949. Width = Dim.Percent (85),
  950. Height = Dim.Percent (85)
  951. };
  952. Application.Run (dlg);
  953. dlg.Dispose ();
  954. };
  955. var btn =
  956. $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} Ok {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}";
  957. int iterations = -1;
  958. Application.Iteration += OnApplicationOnIteration;
  959. Application.Run<Runnable> ();
  960. Application.Iteration -= OnApplicationOnIteration;
  961. Application.Shutdown ();
  962. Assert.Equal (9, iterations);
  963. return;
  964. void OnApplicationOnIteration (object? s, EventArgs<IApplication?> a)
  965. {
  966. iterations++;
  967. switch (iterations)
  968. {
  969. case 0:
  970. Application.TopRunnableView!.SetNeedsLayout ();
  971. Application.TopRunnableView.SetNeedsDraw ();
  972. break;
  973. case 1:
  974. Assert.False (btn1.NewKeyDownEvent (Key.Space));
  975. break;
  976. // Now this happens on iteration 3 because Space triggers Run on the new dialog which itself causes another iteration
  977. // as it starts. Meaning we haven't exited case 1 when we enter case 2 from next Run stack frame.
  978. case 3:
  979. expected = @$"
  980. ┌───────────────────────┐
  981. │ │
  982. │ │
  983. │ │
  984. │ │
  985. │ │
  986. │{Glyphs.LeftBracket} Show Sub {Glyphs.RightBracket} {Glyphs.LeftBracket} Close {Glyphs.RightBracket} │
  987. └───────────────────────┘";
  988. DriverAssert.AssertDriverContentsWithFrameAre (expected, output);
  989. Assert.False (btn2!.NewKeyDownEvent (Key.Space));
  990. break;
  991. case 5:
  992. DriverAssert.AssertDriverContentsWithFrameAre (
  993. @$"
  994. ┌───────────────────────┐
  995. │ ┌──────────────────┐ │
  996. │ │ya │ │
  997. │ │ │ │
  998. │ │ {btn} │ │
  999. │ └──────────────────┘ │
  1000. │{Glyphs.LeftBracket} Show Sub {Glyphs.RightBracket} {Glyphs.LeftBracket} Close {Glyphs.RightBracket} │
  1001. └───────────────────────┘",
  1002. output);
  1003. Assert.False (Application.TopRunnableView!.NewKeyDownEvent (Key.Enter));
  1004. break;
  1005. case 7:
  1006. DriverAssert.AssertDriverContentsWithFrameAre (expected!, output);
  1007. Assert.False (btn3!.NewKeyDownEvent (Key.Space));
  1008. break;
  1009. case 9:
  1010. DriverAssert.AssertDriverContentsWithFrameAre ("", output);
  1011. Application.RequestStop ();
  1012. break;
  1013. }
  1014. }
  1015. }
  1016. [Fact]
  1017. [AutoInitShutdown]
  1018. public void FileDialog_FileSystemWatcher ()
  1019. {
  1020. for (var i = 0; i < 8; i++)
  1021. {
  1022. ApplicationImpl.Instance.StopAfterFirstIteration = true;
  1023. var fd = new FileDialog ();
  1024. Application.Run (fd);
  1025. fd.Dispose ();
  1026. }
  1027. }
  1028. [Fact]
  1029. [AutoInitShutdown]
  1030. public void Location_Default ()
  1031. {
  1032. var d = new Dialog
  1033. {
  1034. Width = Dim.Percent (85),
  1035. Height = Dim.Percent (85)
  1036. };
  1037. Application.Begin (d);
  1038. Application.Driver?.SetScreenSize (100, 100);
  1039. Application.LayoutAndDraw ();
  1040. // Default location is centered, so 100 / 2 - 85 / 2 = 7
  1041. var expected = 7;
  1042. Assert.Equal (new (expected, expected), d.Frame.Location);
  1043. d.Dispose ();
  1044. }
  1045. [Fact]
  1046. [AutoInitShutdown]
  1047. public void Location_Not_Default ()
  1048. {
  1049. var d = new Dialog { X = 1, Y = 1 };
  1050. Application.Begin (d);
  1051. Application.Driver?.SetScreenSize (100, 100);
  1052. // Default location is centered, so 100 / 2 - 85 / 2 = 7
  1053. var expected = 1;
  1054. Assert.Equal (new (expected, expected), d.Frame.Location);
  1055. d.Dispose ();
  1056. }
  1057. [Fact]
  1058. [AutoInitShutdown]
  1059. public void Location_When_Application_Top_Not_Default ()
  1060. {
  1061. // Override CM
  1062. Window.DefaultBorderStyle = LineStyle.Single;
  1063. Dialog.DefaultButtonAlignment = Alignment.Center;
  1064. Dialog.DefaultBorderStyle = LineStyle.Single;
  1065. Dialog.DefaultShadow = ShadowStyle.None;
  1066. Button.DefaultShadow = ShadowStyle.None;
  1067. var expected = 5;
  1068. var d = new Dialog { X = expected, Y = expected, Height = 5, Width = 5 };
  1069. Application.Begin (d);
  1070. Application.Driver?.SetScreenSize (20, 10);
  1071. Application.LayoutAndDraw ();
  1072. // Default location is centered, so 100 / 2 - 85 / 2 = 7
  1073. Assert.Equal (new (expected, expected), d.Frame.Location);
  1074. DriverAssert.AssertDriverContentsWithFrameAre (
  1075. @"
  1076. ┌───┐
  1077. │ │
  1078. │ │
  1079. │ │
  1080. └───┘",
  1081. output
  1082. );
  1083. d.Dispose ();
  1084. }
  1085. [Fact]
  1086. [AutoInitShutdown]
  1087. public void Modal_Captures_All_Mouse ()
  1088. {
  1089. var top = new Runnable
  1090. {
  1091. Id = "top"
  1092. };
  1093. var d = new Dialog
  1094. {
  1095. Width = 10,
  1096. Height = 10,
  1097. X = 1,
  1098. Y = 1
  1099. };
  1100. Application.Driver?.SetScreenSize (20, 20);
  1101. var iterations = 0;
  1102. Application.Iteration += OnApplicationOnIteration;
  1103. top.MouseEvent += (s, e) =>
  1104. {
  1105. // This should not be called because the dialog is modal
  1106. Assert.Fail ("Mouse event should not be captured by the top level when a dialog is modal.");
  1107. };
  1108. Application.Run (top);
  1109. top.Dispose ();
  1110. Application.Iteration -= OnApplicationOnIteration;
  1111. Application.Shutdown ();
  1112. return;
  1113. void OnApplicationOnIteration (object? s, EventArgs<IApplication?> a)
  1114. {
  1115. if (++iterations > 2)
  1116. {
  1117. Application.RequestStop ();
  1118. }
  1119. if (iterations == 1)
  1120. {
  1121. Application.Run (d);
  1122. d.Dispose ();
  1123. }
  1124. else if (iterations == 2)
  1125. {
  1126. // Mouse click outside of dialog
  1127. Application.Mouse.RaiseMouseEvent (new () { Flags = MouseFlags.Button1Clicked, ScreenPosition = new (0, 0) });
  1128. }
  1129. }
  1130. }
  1131. [Fact]
  1132. [AutoInitShutdown]
  1133. public void One_Button_Works ()
  1134. {
  1135. SessionToken? sessionToken = null;
  1136. Button.DefaultShadow = ShadowStyle.None;
  1137. var title = "";
  1138. var btnText = "ok";
  1139. var buttonRow =
  1140. $"{Glyphs.VLine} {Glyphs.LeftBracket} {btnText} {Glyphs.RightBracket} {Glyphs.VLine}";
  1141. int width = buttonRow.Length;
  1142. Application.Driver?.SetScreenSize (buttonRow.Length, 10);
  1143. (sessionToken, Dialog dlg) = BeginButtonTestDialog (
  1144. title,
  1145. width,
  1146. Alignment.Center,
  1147. new Button { Text = btnText }
  1148. );
  1149. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  1150. Application.End (sessionToken);
  1151. dlg.Dispose ();
  1152. }
  1153. [Fact]
  1154. [AutoInitShutdown]
  1155. public void Run_Does_Not_Dispose_Dialog ()
  1156. {
  1157. var top = new Runnable ();
  1158. Dialog dlg = new () { };
  1159. ApplicationImpl.Instance.StopAfterFirstIteration = true;
  1160. Application.Run (dlg);
  1161. #if DEBUG_IDISPOSABLE
  1162. Assert.False (dlg.WasDisposed);
  1163. #endif
  1164. // dlg wasn't disposed yet and it's possible to access to his properties
  1165. Assert.False (dlg.Canceled);
  1166. Assert.NotNull (dlg);
  1167. dlg.Canceled = true;
  1168. Assert.True (dlg.Canceled);
  1169. dlg.Dispose ();
  1170. top.Dispose ();
  1171. #if DEBUG_IDISPOSABLE
  1172. Assert.True (dlg.WasDisposed);
  1173. #endif
  1174. Application.Shutdown ();
  1175. }
  1176. [Fact]
  1177. [AutoInitShutdown]
  1178. public void Size_Default ()
  1179. {
  1180. var d = new Dialog
  1181. {
  1182. Width = Dim.Percent (85),
  1183. Height = Dim.Percent (85)
  1184. };
  1185. Application.Begin (d);
  1186. Application.Driver?.SetScreenSize (100, 100);
  1187. Application.LayoutAndDraw ();
  1188. // Default size is Percent(85)
  1189. Assert.Equal (new ((int)(100 * .85), (int)(100 * .85)), d.Frame.Size);
  1190. d.Dispose ();
  1191. }
  1192. [Fact]
  1193. [AutoInitShutdown]
  1194. public void Size_Not_Default ()
  1195. {
  1196. Dialog.DefaultShadow = ShadowStyle.None;
  1197. Button.DefaultShadow = ShadowStyle.None;
  1198. var d = new Dialog { Width = 50, Height = 50 };
  1199. Application.Begin (d);
  1200. Application.Driver?.SetScreenSize (100, 100);
  1201. // Default size is Percent(85)
  1202. Assert.Equal (new (50, 50), d.Frame.Size);
  1203. d.Dispose ();
  1204. }
  1205. [Fact]
  1206. [AutoInitShutdown]
  1207. public void Zero_Buttons_Works ()
  1208. {
  1209. SessionToken? sessionToken = null;
  1210. var title = "1234";
  1211. var buttonRow = $"{Glyphs.VLine} {Glyphs.VLine}";
  1212. int width = buttonRow.Length;
  1213. Application.Driver?.SetScreenSize (buttonRow.Length, 3);
  1214. (sessionToken, Dialog dlg) = BeginButtonTestDialog (title, width, Alignment.Center);
  1215. DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", output);
  1216. Application.End (sessionToken);
  1217. dlg.Dispose ();
  1218. }
  1219. private (SessionToken, Dialog) BeginButtonTestDialog (
  1220. string title,
  1221. int width,
  1222. Alignment align,
  1223. params Button [] btns
  1224. )
  1225. {
  1226. // Override CM
  1227. Dialog.DefaultButtonAlignment = Alignment.Center;
  1228. Dialog.DefaultBorderStyle = LineStyle.Single;
  1229. Dialog.DefaultShadow = ShadowStyle.None;
  1230. Button.DefaultShadow = ShadowStyle.None;
  1231. var dlg = new Dialog
  1232. {
  1233. Title = title,
  1234. X = 0,
  1235. Y = 0,
  1236. Width = width,
  1237. Height = 1,
  1238. ButtonAlignment = align,
  1239. Buttons = btns
  1240. };
  1241. // Create with no top or bottom border to simplify testing button layout (no need to account for title etc..)
  1242. dlg.Border!.Thickness = new (1, 0, 1, 0);
  1243. SessionToken sessionToken = Application.Begin (dlg);
  1244. dlg.SetNeedsDraw ();
  1245. dlg.SetNeedsLayout ();
  1246. AutoInitShutdownAttribute.RunIteration ();
  1247. return (sessionToken, dlg);
  1248. }
  1249. }