DialogTests.cs 57 KB

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