DialogTests.cs 59 KB

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