TextTests.cs 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238
  1. using System.Runtime.CompilerServices;
  2. using System.Text;
  3. using Xunit.Abstractions;
  4. namespace Terminal.Gui.ViewTests;
  5. /// <summary>
  6. /// Tests of the <see cref="View.Text"/> and <see cref="View.TextFormatter"/> properties (independent of
  7. /// AutoSize).
  8. /// </summary>
  9. public class TextTests (ITestOutputHelper output)
  10. {
  11. private readonly ITestOutputHelper _output = output;
  12. [Fact]
  13. [SetupFakeDriver]
  14. public void Setting_With_Height_Horizontal ()
  15. {
  16. var top = new View { Width = 25, Height = 25 };
  17. var label = new Label { Text = "Hello", /* Width = 10, Height = 2, */ ValidatePosDim = true };
  18. var viewX = new View { Text = "X", X = Pos.Right (label), Width = 1, Height = 1 };
  19. var viewY = new View { Text = "Y", Y = Pos.Bottom (label), Width = 1, Height = 1 };
  20. top.Add (label, viewX, viewY);
  21. top.BeginInit ();
  22. top.EndInit ();
  23. Assert.Equal (new (0, 0, 5, 1), label.Frame);
  24. top.LayoutSubviews ();
  25. top.Draw ();
  26. var expected = @"
  27. HelloX
  28. Y
  29. ";
  30. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  31. label.Width = 10;
  32. label.Height = 2;
  33. Assert.Equal (new (0, 0, 10, 2), label.Frame);
  34. top.LayoutSubviews ();
  35. top.Draw ();
  36. expected = @"
  37. Hello X
  38. Y
  39. ";
  40. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  41. }
  42. [Fact]
  43. [AutoInitShutdown]
  44. public void Setting_With_Height_Vertical ()
  45. {
  46. // BUGBUG: Label is Width = Dim.Auto (), Height = Dim.Auto (), so Width & Height are ignored
  47. var label = new Label
  48. { /*Width = 2, Height = 10, */
  49. TextDirection = TextDirection.TopBottom_LeftRight, ValidatePosDim = true
  50. };
  51. var viewX = new View { Text = "X", X = Pos.Right (label), Width = 1, Height = 1 };
  52. var viewY = new View { Text = "Y", Y = Pos.Bottom (label), Width = 1, Height = 1 };
  53. var top = new Toplevel ();
  54. top.Add (label, viewX, viewY);
  55. RunState rs = Application.Begin (top);
  56. label.Text = "Hello";
  57. Application.Refresh ();
  58. Assert.Equal (new (0, 0, 1, 5), label.Frame);
  59. var expected = @"
  60. HX
  61. e
  62. l
  63. l
  64. o
  65. Y
  66. ";
  67. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  68. label.Width = 2;
  69. label.Height = 10;
  70. Application.Refresh ();
  71. Assert.Equal (new (0, 0, 2, 10), label.Frame);
  72. expected = @"
  73. H X
  74. e
  75. l
  76. l
  77. o
  78. Y
  79. "
  80. ;
  81. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  82. Application.End (rs);
  83. }
  84. [Fact]
  85. [AutoInitShutdown]
  86. public void TextDirection_Toggle ()
  87. {
  88. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  89. var view = new View ();
  90. win.Add (view);
  91. var top = new Toplevel ();
  92. top.Add (win);
  93. RunState rs = Application.Begin (top);
  94. ((FakeDriver)Application.Driver).SetBufferSize (15, 15);
  95. Assert.Equal (new Rectangle (0, 0, 15, 15), win.Frame);
  96. Assert.Equal (new Rectangle (0, 0, 15, 15), win.Margin.Frame);
  97. Assert.Equal (new Rectangle (0, 0, 15, 15), win.Border.Frame);
  98. Assert.Equal (new Rectangle (1, 1, 13, 13), win.Padding.Frame);
  99. Assert.Equal (TextDirection.LeftRight_TopBottom, view.TextDirection);
  100. Assert.Equal (Rectangle.Empty, view.Frame);
  101. Assert.Equal ("Absolute(0)", view.X.ToString ());
  102. Assert.Equal ("Absolute(0)", view.Y.ToString ());
  103. Assert.Equal ("Absolute(0)", view.Width.ToString ());
  104. Assert.Equal ("Absolute(0)", view.Height.ToString ());
  105. var expected = @"
  106. ┌─────────────┐
  107. │ │
  108. │ │
  109. │ │
  110. │ │
  111. │ │
  112. │ │
  113. │ │
  114. │ │
  115. │ │
  116. │ │
  117. │ │
  118. │ │
  119. │ │
  120. └─────────────┘
  121. ";
  122. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  123. view.Text = "Hello World";
  124. view.Width = 11;
  125. view.Height = 1;
  126. win.LayoutSubviews ();
  127. Application.Refresh ();
  128. Assert.Equal (new Rectangle (0, 0, 11, 1), view.Frame);
  129. Assert.Equal ("Absolute(0)", view.X.ToString ());
  130. Assert.Equal ("Absolute(0)", view.Y.ToString ());
  131. Assert.Equal ("Absolute(11)", view.Width.ToString ());
  132. Assert.Equal ("Absolute(1)", view.Height.ToString ());
  133. expected = @"
  134. ┌─────────────┐
  135. │Hello World │
  136. │ │
  137. │ │
  138. │ │
  139. │ │
  140. │ │
  141. │ │
  142. │ │
  143. │ │
  144. │ │
  145. │ │
  146. │ │
  147. │ │
  148. └─────────────┘
  149. ";
  150. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  151. view.Width = Dim.Auto ();
  152. view.Height = Dim.Auto ();
  153. view.Text = "Hello Worlds";
  154. Application.Refresh ();
  155. int len = "Hello Worlds".Length;
  156. Assert.Equal (12, len);
  157. Assert.Equal (new Rectangle (0, 0, len, 1), view.Frame);
  158. expected = @"
  159. ┌─────────────┐
  160. │Hello Worlds │
  161. │ │
  162. │ │
  163. │ │
  164. │ │
  165. │ │
  166. │ │
  167. │ │
  168. │ │
  169. │ │
  170. │ │
  171. │ │
  172. │ │
  173. └─────────────┘
  174. ";
  175. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  176. view.TextDirection = TextDirection.TopBottom_LeftRight;
  177. Application.Refresh ();
  178. Assert.Equal (new Rectangle (0, 0, 1, 12), view.Frame);
  179. Assert.Equal (new Rectangle (0, 0, 1, 12), view.Frame);
  180. expected = @"
  181. ┌─────────────┐
  182. │H │
  183. │e │
  184. │l │
  185. │l │
  186. │o │
  187. │ │
  188. │W │
  189. │o │
  190. │r │
  191. │l │
  192. │d │
  193. │s │
  194. │ │
  195. └─────────────┘
  196. ";
  197. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  198. // Setting to false causes Width and Height to be set to the current ContentSize
  199. view.Width = 1;
  200. view.Height = 12;
  201. Assert.Equal (new Rectangle (0, 0, 1, 12), view.Frame);
  202. view.Width = 12;
  203. view.Height = 1;
  204. view.TextFormatter.Size = new (12, 1);
  205. win.LayoutSubviews ();
  206. Assert.Equal (new Size (12, 1), view.TextFormatter.Size);
  207. Assert.Equal (new Rectangle (0, 0, 12, 1), view.Frame);
  208. top.Clear ();
  209. view.Draw ();
  210. expected = @" HelloWorlds";
  211. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  212. Application.Refresh ();
  213. // TextDirection.TopBottom_LeftRight - Height of 1 and Width of 12 means
  214. // that the text will be spread "vertically" across 1 line.
  215. // Hence no space.
  216. expected = @"
  217. ┌─────────────┐
  218. │HelloWorlds │
  219. │ │
  220. │ │
  221. │ │
  222. │ │
  223. │ │
  224. │ │
  225. │ │
  226. │ │
  227. │ │
  228. │ │
  229. │ │
  230. │ │
  231. └─────────────┘
  232. ";
  233. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  234. view.PreserveTrailingSpaces = true;
  235. Application.Refresh ();
  236. Assert.Equal (new Rectangle (0, 0, 12, 1), view.Frame);
  237. expected = @"
  238. ┌─────────────┐
  239. │Hello Worlds │
  240. │ │
  241. │ │
  242. │ │
  243. │ │
  244. │ │
  245. │ │
  246. │ │
  247. │ │
  248. │ │
  249. │ │
  250. │ │
  251. │ │
  252. └─────────────┘
  253. ";
  254. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  255. view.PreserveTrailingSpaces = false;
  256. Rectangle f = view.Frame;
  257. view.Width = f.Height;
  258. view.Height = f.Width;
  259. view.TextDirection = TextDirection.TopBottom_LeftRight;
  260. Application.Refresh ();
  261. Assert.Equal (new Rectangle (0, 0, 1, 12), view.Frame);
  262. expected = @"
  263. ┌─────────────┐
  264. │H │
  265. │e │
  266. │l │
  267. │l │
  268. │o │
  269. │ │
  270. │W │
  271. │o │
  272. │r │
  273. │l │
  274. │d │
  275. │s │
  276. │ │
  277. └─────────────┘
  278. ";
  279. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  280. view.Width = Dim.Auto ();
  281. view.Height = Dim.Auto ();
  282. Application.Refresh ();
  283. Assert.Equal (new Rectangle (0, 0, 1, 12), view.Frame);
  284. expected = @"
  285. ┌─────────────┐
  286. │H │
  287. │e │
  288. │l │
  289. │l │
  290. │o │
  291. │ │
  292. │W │
  293. │o │
  294. │r │
  295. │l │
  296. │d │
  297. │s │
  298. │ │
  299. └─────────────┘
  300. ";
  301. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  302. Application.End (rs);
  303. }
  304. [Fact]
  305. [AutoInitShutdown]
  306. public void AutoSize_True_View_IsEmpty_False_Minimum_Width ()
  307. {
  308. var text = "Views";
  309. var view = new View
  310. {
  311. TextDirection = TextDirection.TopBottom_LeftRight,
  312. Height = Dim.Fill () - text.Length,
  313. Text = text,
  314. };
  315. view.Width = Dim.Auto ();
  316. view.Height = Dim.Auto ();
  317. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  318. win.Add (view);
  319. var top = new Toplevel ();
  320. top.Add (win);
  321. Application.Begin (top);
  322. ((FakeDriver)Application.Driver).SetBufferSize (4, 10);
  323. Assert.Equal (5, text.Length);
  324. Assert.Equal (new (0, 0, 1, 5), view.Frame);
  325. Assert.Equal (new (1, 5), view.TextFormatter.Size);
  326. Assert.Equal (new List<string> { "Views" }, view.TextFormatter.GetLines ());
  327. Assert.Equal (new (0, 0, 4, 10), win.Frame);
  328. Assert.Equal (new (0, 0, 4, 10), Application.Top.Frame);
  329. var expected = @"
  330. ┌──┐
  331. │V │
  332. │i │
  333. │e │
  334. │w │
  335. │s │
  336. │ │
  337. │ │
  338. │ │
  339. └──┘
  340. ";
  341. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  342. Assert.Equal (new (0, 0, 4, 10), pos);
  343. text = "0123456789";
  344. Assert.Equal (10, text.Length);
  345. //view.Height = Dim.Fill () - text.Length;
  346. Application.Refresh ();
  347. Assert.Equal (new (0, 0, 1, 5), view.Frame);
  348. Assert.Equal (new (1, 5), view.TextFormatter.Size);
  349. Exception exception = Record.Exception (() => Assert.Single (view.TextFormatter.GetLines ()));
  350. Assert.Null (exception);
  351. expected = @"
  352. ┌──┐
  353. │V │
  354. │i │
  355. │e │
  356. │w │
  357. │s │
  358. │ │
  359. │ │
  360. │ │
  361. └──┘
  362. ";
  363. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  364. Assert.Equal (new Rectangle (0, 0, 4, 10), pos);
  365. }
  366. [Fact]
  367. [AutoInitShutdown]
  368. public void AutoSize_True_View_IsEmpty_False_Minimum_Width_Wide_Rune ()
  369. {
  370. var text = "界View";
  371. var view = new View
  372. {
  373. TextDirection = TextDirection.TopBottom_LeftRight,
  374. Text = text,
  375. Width = Dim.Auto (),
  376. Height = Dim.Auto ()
  377. };
  378. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  379. win.Add (view);
  380. var top = new Toplevel ();
  381. top.Add (win);
  382. Application.Begin (top);
  383. ((FakeDriver)Application.Driver).SetBufferSize (4, 10);
  384. Assert.Equal (5, text.Length);
  385. Assert.Equal (new (0, 0, 2, 5), view.Frame);
  386. Assert.Equal (new (2, 5), view.TextFormatter.Size);
  387. Assert.Equal (new List<string> { "界View" }, view.TextFormatter.GetLines ());
  388. Assert.Equal (new (0, 0, 4, 10), win.Frame);
  389. Assert.Equal (new (0, 0, 4, 10), Application.Top.Frame);
  390. var expected = @"
  391. ┌──┐
  392. │界│
  393. │V │
  394. │i │
  395. │e │
  396. │w │
  397. │ │
  398. │ │
  399. │ │
  400. └──┘
  401. ";
  402. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  403. Assert.Equal (new (0, 0, 4, 10), pos);
  404. text = "0123456789";
  405. Assert.Equal (10, text.Length);
  406. //view.Height = Dim.Fill () - text.Length;
  407. Application.Refresh ();
  408. Assert.Equal (new (0, 0, 2, 5), view.Frame);
  409. Assert.Equal (new (2, 5), view.TextFormatter.Size);
  410. Exception exception = Record.Exception (
  411. () => Assert.Equal (
  412. new List<string> { "界View" },
  413. view.TextFormatter.GetLines ()
  414. )
  415. );
  416. Assert.Null (exception);
  417. expected = @"
  418. ┌──┐
  419. │界│
  420. │V │
  421. │i │
  422. │e │
  423. │w │
  424. │ │
  425. │ │
  426. │ │
  427. └──┘
  428. ";
  429. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  430. Assert.Equal (new Rectangle (0, 0, 4, 10), pos);
  431. }
  432. [Fact]
  433. [AutoInitShutdown]
  434. public void AutoSize_True_Width_Height_SetMinWidthHeight_Narrow_Wide_Runes ()
  435. {
  436. var text = $"0123456789{Environment.NewLine}01234567891";
  437. var horizontalView = new View
  438. {
  439. Width = Dim.Auto (),
  440. Height = Dim.Auto (),
  441. Text = text
  442. };
  443. var verticalView = new View
  444. {
  445. Width = Dim.Auto (),
  446. Height = Dim.Auto (),
  447. Y = 3,
  448. //Height = 11,
  449. //Width = 2,
  450. Text = text,
  451. TextDirection = TextDirection.TopBottom_LeftRight
  452. };
  453. var win = new Window
  454. {
  455. Width = Dim.Fill (),
  456. Height = Dim.Fill (),
  457. Text = "Window"
  458. };
  459. win.Add (horizontalView, verticalView);
  460. var top = new Toplevel ();
  461. top.Add (win);
  462. RunState rs = Application.Begin (top);
  463. ((FakeDriver)Application.Driver).SetBufferSize (20, 20);
  464. Assert.Equal (new Rectangle (0, 0, 11, 2), horizontalView.Frame);
  465. Assert.Equal (new Rectangle (0, 3, 2, 11), verticalView.Frame);
  466. var expected = @"
  467. ┌──────────────────┐
  468. │0123456789 │
  469. │01234567891 │
  470. │ │
  471. │00 │
  472. │11 │
  473. │22 │
  474. │33 │
  475. │44 │
  476. │55 │
  477. │66 │
  478. │77 │
  479. │88 │
  480. │99 │
  481. │ 1 │
  482. │ │
  483. │ │
  484. │ │
  485. │ │
  486. └──────────────────┘
  487. ";
  488. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  489. verticalView.Text = $"最初の行{Environment.NewLine}二行目";
  490. Application.Top.Draw ();
  491. Assert.Equal (new Rectangle (0, 3, 4, 4), verticalView.Frame);
  492. expected = @"
  493. ┌──────────────────┐
  494. │0123456789 │
  495. │01234567891 │
  496. │ │
  497. │最二 │
  498. │初行 │
  499. │の目 │
  500. │行 │
  501. │ │
  502. │ │
  503. │ │
  504. │ │
  505. │ │
  506. │ │
  507. │ │
  508. │ │
  509. │ │
  510. │ │
  511. │ │
  512. └──────────────────┘
  513. ";
  514. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  515. Application.End (rs);
  516. }
  517. [Fact]
  518. [AutoInitShutdown]
  519. public void AutoSize_True_Width_Height_Stay_True_If_TextFormatter_Size_Fit ()
  520. {
  521. var text = "Finish 終";
  522. var horizontalView = new View
  523. {
  524. Id = "horizontalView",
  525. Width = Dim.Auto (), Height = Dim.Auto (), Text = text
  526. };
  527. var verticalView = new View
  528. {
  529. Id = "verticalView",
  530. Y = 3,
  531. Width = Dim.Auto (),
  532. Height = Dim.Auto (),
  533. Text = text,
  534. TextDirection = TextDirection.TopBottom_LeftRight
  535. };
  536. var win = new Window { Id = "win", Width = Dim.Fill (), Height = Dim.Fill (), Text = "Window" };
  537. win.Add (horizontalView, verticalView);
  538. var top = new Toplevel ();
  539. top.Add (win);
  540. RunState rs = Application.Begin (top);
  541. ((FakeDriver)Application.Driver).SetBufferSize (22, 22);
  542. Assert.Equal (new (text.GetColumns (), 1), horizontalView.TextFormatter.Size);
  543. Assert.Equal (new (2, 8), verticalView.TextFormatter.Size);
  544. //Assert.Equal (new (0, 0, 10, 1), horizontalView.Frame);
  545. //Assert.Equal (new (0, 3, 10, 9), verticalView.Frame);
  546. var expected = @"
  547. ┌────────────────────┐
  548. │Finish 終 │
  549. │ │
  550. │ │
  551. │F │
  552. │i │
  553. │n │
  554. │i │
  555. │s │
  556. │h │
  557. │ │
  558. │終 │
  559. │ │
  560. │ │
  561. │ │
  562. │ │
  563. │ │
  564. │ │
  565. │ │
  566. │ │
  567. │ │
  568. └────────────────────┘
  569. ";
  570. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  571. verticalView.Text = "最初の行二行目";
  572. Application.Top.Draw ();
  573. // height was initialized with 8 and can only grow or keep initial value
  574. Assert.Equal (new Rectangle (0, 3, 2, 7), verticalView.Frame);
  575. expected = @"
  576. ┌────────────────────┐
  577. │Finish 終 │
  578. │ │
  579. │ │
  580. │最 │
  581. │初 │
  582. │の │
  583. │行 │
  584. │二 │
  585. │行 │
  586. │目 │
  587. │ │
  588. │ │
  589. │ │
  590. │ │
  591. │ │
  592. │ │
  593. │ │
  594. │ │
  595. │ │
  596. │ │
  597. └────────────────────┘
  598. ";
  599. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  600. Application.End (rs);
  601. }
  602. [Fact]
  603. [AutoInitShutdown]
  604. public void Excess_Text_Is_Erased_When_The_Width_Is_Reduced ()
  605. {
  606. var lbl = new Label { Text = "123" };
  607. var top = new Toplevel ();
  608. top.Add (lbl);
  609. RunState rs = Application.Begin (top);
  610. Assert.Equal ("123 ", GetContents ());
  611. lbl.Text = "12";
  612. Assert.Equal (new Rectangle (0, 0, 2, 1), lbl.Frame);
  613. Assert.Equal (new Rectangle (0, 0, 3, 1), lbl._needsDisplayRect);
  614. Assert.Equal (new Rectangle (0, 0, 0, 0), lbl.SuperView._needsDisplayRect);
  615. Assert.True (lbl.SuperView.LayoutNeeded);
  616. lbl.SuperView.Draw ();
  617. Assert.Equal ("12 ", GetContents ());
  618. string GetContents ()
  619. {
  620. var text = "";
  621. for (var i = 0; i < 4; i++)
  622. {
  623. text += Application.Driver.Contents [0, i].Rune;
  624. }
  625. return text;
  626. }
  627. Application.End (rs);
  628. }
  629. [Fact]
  630. [AutoInitShutdown]
  631. public void GetTextFormatterBoundsSize_GetSizeNeededForText_HotKeySpecifier ()
  632. {
  633. var text = "Say Hello 你";
  634. // Frame: 0, 0, 12, 1
  635. var horizontalView = new View
  636. {
  637. Width = Dim.Auto (), Height = Dim.Auto ()
  638. };
  639. horizontalView.TextFormatter.HotKeySpecifier = (Rune)'_';
  640. horizontalView.Text = text;
  641. // Frame: 0, 0, 1, 12
  642. var verticalView = new View
  643. {
  644. Width = Dim.Auto (), Height = Dim.Auto (), TextDirection = TextDirection.TopBottom_LeftRight
  645. };
  646. verticalView.Text = text;
  647. verticalView.TextFormatter.HotKeySpecifier = (Rune)'_';
  648. var top = new Toplevel ();
  649. top.Add (horizontalView, verticalView);
  650. Application.Begin (top);
  651. ((FakeDriver)Application.Driver).SetBufferSize (50, 50);
  652. Assert.Equal (new (0, 0, 12, 1), horizontalView.Frame);
  653. Assert.Equal (new (12, 1), horizontalView.GetSizeNeededForTextWithoutHotKey ());
  654. Assert.Equal (horizontalView.Frame.Size, horizontalView.GetSizeNeededForTextWithoutHotKey ());
  655. Assert.Equal (new (0, 0, 2, 11), verticalView.Frame);
  656. Assert.Equal (new (2, 11), verticalView.GetSizeNeededForTextWithoutHotKey ());
  657. Assert.Equal (verticalView.Frame.Size, verticalView.GetSizeNeededForTextWithoutHotKey ());
  658. text = "012345678你";
  659. horizontalView.Text = text;
  660. verticalView.Text = text;
  661. Assert.Equal (new (0, 0, 11, 1), horizontalView.Frame);
  662. Assert.Equal (new (11, 1), horizontalView.GetSizeNeededForTextWithoutHotKey ());
  663. Assert.Equal (horizontalView.Frame.Size, horizontalView.GetSizeNeededForTextWithoutHotKey ());
  664. Assert.Equal (new (0, 0, 2, 10), verticalView.Frame);
  665. Assert.Equal (new (2, 10), verticalView.GetSizeNeededForTextWithoutHotKey ());
  666. Assert.Equal (verticalView.Frame.Size, verticalView.GetSizeNeededForTextWithoutHotKey ());
  667. }
  668. [Theory]
  669. [AutoInitShutdown]
  670. [InlineData (true)]
  671. [InlineData (false)]
  672. public void View_Draw_Horizontal_Simple_TextAlignments (bool autoSize)
  673. {
  674. var text = "Hello World";
  675. var width = 20;
  676. var lblLeft = new View
  677. {
  678. Text = text,
  679. Width = width,
  680. Height = 1,
  681. };
  682. if (autoSize)
  683. {
  684. lblLeft.Width = Dim.Auto ();
  685. lblLeft.Height = Dim.Auto ();
  686. }
  687. var lblCenter = new View
  688. {
  689. Text = text,
  690. Y = 1,
  691. Width = width,
  692. Height = 1,
  693. TextAlignment = TextAlignment.Centered,
  694. };
  695. if (autoSize)
  696. {
  697. lblCenter.Width = Dim.Auto ();
  698. lblCenter.Height = Dim.Auto ();
  699. }
  700. var lblRight = new View
  701. {
  702. Text = text,
  703. Y = 2,
  704. Width = width,
  705. Height = 1,
  706. TextAlignment = TextAlignment.Right,
  707. };
  708. if (autoSize)
  709. {
  710. lblRight.Width = Dim.Auto ();
  711. lblRight.Height = Dim.Auto ();
  712. }
  713. var lblJust = new View
  714. {
  715. Text = text,
  716. Y = 3,
  717. Width = width,
  718. Height = 1,
  719. TextAlignment = TextAlignment.Justified,
  720. };
  721. if (autoSize)
  722. {
  723. lblJust.Width = Dim.Auto ();
  724. lblJust.Height = Dim.Auto ();
  725. }
  726. var frame = new FrameView { Width = Dim.Fill (), Height = Dim.Fill () };
  727. frame.Add (lblLeft, lblCenter, lblRight, lblJust);
  728. var top = new Toplevel ();
  729. top.Add (frame);
  730. Application.Begin (top);
  731. ((FakeDriver)Application.Driver).SetBufferSize (width + 2, 6);
  732. if (autoSize)
  733. {
  734. Size expectedSize = new (11, 1);
  735. Assert.Equal (expectedSize, lblLeft.TextFormatter.Size);
  736. Assert.Equal (expectedSize, lblCenter.TextFormatter.Size);
  737. Assert.Equal (expectedSize, lblRight.TextFormatter.Size);
  738. Assert.Equal (expectedSize, lblJust.TextFormatter.Size);
  739. }
  740. else
  741. {
  742. Size expectedSize = new (width, 1);
  743. Assert.Equal (expectedSize, lblLeft.TextFormatter.Size);
  744. Assert.Equal (expectedSize, lblCenter.TextFormatter.Size);
  745. Assert.Equal (expectedSize, lblRight.TextFormatter.Size);
  746. Assert.Equal (expectedSize, lblJust.TextFormatter.Size);
  747. }
  748. Assert.Equal (new (0, 0, width + 2, 6), frame.Frame);
  749. string expected;
  750. if (autoSize)
  751. {
  752. expected = @"
  753. ┌────────────────────┐
  754. │Hello World │
  755. │Hello World │
  756. │Hello World │
  757. │Hello World │
  758. └────────────────────┘
  759. ";
  760. }
  761. else
  762. {
  763. expected = @"
  764. ┌────────────────────┐
  765. │Hello World │
  766. │ Hello World │
  767. │ Hello World│
  768. │Hello World│
  769. └────────────────────┘
  770. ";
  771. }
  772. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  773. Assert.Equal (new (0, 0, width + 2, 6), pos);
  774. }
  775. [Theory]
  776. [AutoInitShutdown]
  777. [InlineData (true)]
  778. [InlineData (false)]
  779. public void View_Draw_Vertical_Simple_TextAlignments (bool autoSize)
  780. {
  781. var text = "Hello World";
  782. var height = 20;
  783. var lblLeft = new View
  784. {
  785. Text = text,
  786. Width = 1,
  787. Height = height,
  788. TextDirection = TextDirection.TopBottom_LeftRight,
  789. };
  790. if (autoSize)
  791. {
  792. lblLeft.Width = Dim.Auto ();
  793. lblLeft.Height = Dim.Auto ();
  794. }
  795. var lblCenter = new View
  796. {
  797. Text = text,
  798. X = 2,
  799. Width = 1,
  800. Height = height,
  801. TextDirection = TextDirection.TopBottom_LeftRight,
  802. VerticalTextAlignment = VerticalTextAlignment.Middle
  803. };
  804. if (autoSize)
  805. {
  806. lblCenter.Width = Dim.Auto ();
  807. lblCenter.Height = Dim.Auto ();
  808. }
  809. var lblRight = new View
  810. {
  811. Text = text,
  812. X = 4,
  813. Width = 1,
  814. Height = height,
  815. TextDirection = TextDirection.TopBottom_LeftRight,
  816. VerticalTextAlignment = VerticalTextAlignment.Bottom
  817. };
  818. if (autoSize)
  819. {
  820. lblRight.Width = Dim.Auto ();
  821. lblRight.Height = Dim.Auto ();
  822. }
  823. var lblJust = new View
  824. {
  825. Text = text,
  826. X = 6,
  827. Width = 1,
  828. Height = height,
  829. TextDirection = TextDirection.TopBottom_LeftRight,
  830. VerticalTextAlignment = VerticalTextAlignment.Justified
  831. };
  832. if (autoSize)
  833. {
  834. lblJust.Width = Dim.Auto ();
  835. lblJust.Height = Dim.Auto ();
  836. }
  837. var frame = new FrameView { Width = Dim.Fill (), Height = Dim.Fill () };
  838. frame.Add (lblLeft, lblCenter, lblRight, lblJust);
  839. var top = new Toplevel ();
  840. top.Add (frame);
  841. Application.Begin (top);
  842. ((FakeDriver)Application.Driver).SetBufferSize (9, height + 2);
  843. if (autoSize)
  844. {
  845. Assert.Equal (new (1, 11), lblLeft.TextFormatter.Size);
  846. Assert.Equal (new (1, 11), lblCenter.TextFormatter.Size);
  847. Assert.Equal (new (1, 11), lblRight.TextFormatter.Size);
  848. Assert.Equal (new (1, 11), lblJust.TextFormatter.Size);
  849. Assert.Equal (new (0, 0, 9, height + 2), frame.Frame);
  850. }
  851. else
  852. {
  853. Assert.Equal (new (1, height), lblLeft.TextFormatter.Size);
  854. Assert.Equal (new (1, height), lblCenter.TextFormatter.Size);
  855. Assert.Equal (new (1, height), lblRight.TextFormatter.Size);
  856. Assert.Equal (new (1, height), lblJust.TextFormatter.Size);
  857. Assert.Equal (new (0, 0, 9, height + 2), frame.Frame);
  858. }
  859. string expected;
  860. if (autoSize)
  861. {
  862. expected = @"
  863. ┌───────┐
  864. │H H H H│
  865. │e e e e│
  866. │l l l l│
  867. │l l l l│
  868. │o o o o│
  869. │ │
  870. │W W W W│
  871. │o o o o│
  872. │r r r r│
  873. │l l l l│
  874. │d d d d│
  875. │ │
  876. │ │
  877. │ │
  878. │ │
  879. │ │
  880. │ │
  881. │ │
  882. │ │
  883. │ │
  884. └───────┘
  885. ";
  886. }
  887. else
  888. {
  889. expected = @"
  890. ┌───────┐
  891. │H H│
  892. │e e│
  893. │l l│
  894. │l l│
  895. │o H o│
  896. │ e │
  897. │W l │
  898. │o l │
  899. │r o │
  900. │l H │
  901. │d W e │
  902. │ o l │
  903. │ r l │
  904. │ l o │
  905. │ d │
  906. │ W W│
  907. │ o o│
  908. │ r r│
  909. │ l l│
  910. │ d d│
  911. └───────┘
  912. ";
  913. }
  914. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  915. Assert.Equal (new (0, 0, 9, height + 2), pos);
  916. }
  917. // Test that View.PreserveTrailingSpaces removes trailing spaces
  918. [Fact]
  919. public void PreserveTrailingSpaces_Removes_Trailing_Spaces ()
  920. {
  921. var view = new View { Text = "Hello World " };
  922. Assert.Equal ("Hello World ", view.TextFormatter.Text);
  923. view.TextFormatter.WordWrap = true;
  924. view.TextFormatter.Size = new (5, 3);
  925. view.PreserveTrailingSpaces = false;
  926. Assert.Equal ($"Hello{Environment.NewLine}World", view.TextFormatter.Format ());
  927. view.PreserveTrailingSpaces = true;
  928. Assert.Equal ($"Hello{Environment.NewLine} {Environment.NewLine}World", view.TextFormatter.Format ());
  929. }
  930. // View.PreserveTrailingSpaces Gets or sets whether trailing spaces at the end of word-wrapped lines are preserved
  931. // or not when <see cref="TextFormatter.WordWrap"/> is enabled.
  932. // If <see langword="true"/> trailing spaces at the end of wrapped lines will be removed when
  933. // <see cref = "Text" / > is formatted for display.The default is <see langword = "false" / >.
  934. [Fact]
  935. public void PreserveTrailingSpaces_Set_Get ()
  936. {
  937. var view = new View { Text = "Hello World" };
  938. Assert.False (view.PreserveTrailingSpaces);
  939. view.PreserveTrailingSpaces = true;
  940. Assert.True (view.PreserveTrailingSpaces);
  941. }
  942. // Setting TextFormatter DOES NOT update Text
  943. [Fact]
  944. public void SettingTextFormatterDoesNotUpdateText ()
  945. {
  946. var view = new View ();
  947. view.TextFormatter.Text = "Hello World";
  948. Assert.True (string.IsNullOrEmpty (view.Text));
  949. }
  950. // Setting Text updates TextFormatter
  951. [Fact]
  952. public void SettingTextUpdatesTextFormatter ()
  953. {
  954. var view = new View { Text = "Hello World" };
  955. Assert.Equal ("Hello World", view.Text);
  956. Assert.Equal ("Hello World", view.TextFormatter.Text);
  957. }
  958. // Setting Text does NOT set the HotKey
  959. [Fact]
  960. public void Text_Does_Not_Set_HotKey ()
  961. {
  962. var view = new View { HotKeySpecifier = (Rune)'_', Text = "_Hello World" };
  963. Assert.NotEqual (Key.H, view.HotKey);
  964. }
  965. // Test that TextFormatter is init only
  966. [Fact]
  967. public void TextFormatterIsInitOnly ()
  968. {
  969. var view = new View ();
  970. // Use reflection to ensure the TextFormatter property is `init` only
  971. Assert.Contains (
  972. typeof (IsExternalInit),
  973. typeof (View).GetMethod ("set_TextFormatter")
  974. .ReturnParameter.GetRequiredCustomModifiers ());
  975. }
  976. // Test that the Text property is set correctly.
  977. [Fact]
  978. public void TextProperty ()
  979. {
  980. var view = new View { Text = "Hello World" };
  981. Assert.Equal ("Hello World", view.Text);
  982. }
  983. // Test view.UpdateTextFormatterText overridden in a subclass updates TextFormatter.Text
  984. [Fact]
  985. public void UpdateTextFormatterText_Overridden ()
  986. {
  987. var view = new TestView { Text = "Hello World" };
  988. Assert.Equal ("Hello World", view.Text);
  989. Assert.Equal (">Hello World<", view.TextFormatter.Text);
  990. }
  991. private class TestView : View
  992. {
  993. protected override void UpdateTextFormatterText () { TextFormatter.Text = $">{Text}<"; }
  994. }
  995. [Fact]
  996. public void TextDirection_Horizontal_Dims_Correct ()
  997. {
  998. // Initializes a view with a vertical direction
  999. var view = new View
  1000. {
  1001. Text = "01234",
  1002. TextDirection = TextDirection.LeftRight_TopBottom,
  1003. Width = Dim.Auto (Dim.DimAutoStyle.Text),
  1004. Height = Dim.Auto (Dim.DimAutoStyle.Text)
  1005. };
  1006. Assert.Equal (new Rectangle (0, 0, 5, 1), view.Frame);
  1007. Assert.Equal (new Rectangle (0, 0, 5, 1), view.Viewport);
  1008. view.BeginInit ();
  1009. view.EndInit ();
  1010. Assert.Equal (new Rectangle (0, 0, 5, 1), view.Frame);
  1011. Assert.Equal (new Rectangle (0, 0, 5, 1), view.Viewport);
  1012. }
  1013. // BUGBUG: this is a temporary test that helped identify #3469 - It needs to be expanded upon (and renamed)
  1014. [Fact]
  1015. public void TextDirection_Horizontal_Dims_Correct_WidthAbsolute ()
  1016. {
  1017. var view = new View
  1018. {
  1019. Text = "01234",
  1020. TextDirection = TextDirection.LeftRight_TopBottom,
  1021. TextAlignment = TextAlignment.Centered,
  1022. Width = 10,
  1023. Height = Dim.Auto (Dim.DimAutoStyle.Text)
  1024. };
  1025. view.BeginInit ();
  1026. view.EndInit ();
  1027. Assert.Equal (new Rectangle (0, 0, 10, 1), view.Frame);
  1028. Assert.Equal (new Rectangle (0, 0, 10, 1), view.Viewport);
  1029. Assert.Equal (new (10, 1), view.TextFormatter.Size);
  1030. }
  1031. [Fact]
  1032. public void TextDirection_Vertical_Dims_Correct ()
  1033. {
  1034. // Initializes a view with a vertical direction
  1035. var view = new View
  1036. {
  1037. TextDirection = TextDirection.TopBottom_LeftRight,
  1038. Text = "01234",
  1039. Width = Dim.Auto (Dim.DimAutoStyle.Text),
  1040. Height = Dim.Auto (Dim.DimAutoStyle.Text),
  1041. };
  1042. Assert.Equal (new Rectangle (0, 0, 1, 5), view.Frame);
  1043. Assert.Equal (new Rectangle (0, 0, 1, 5), view.Viewport);
  1044. view.BeginInit ();
  1045. Assert.Equal (new Rectangle (0, 0, 1, 5), view.Frame);
  1046. view.EndInit ();
  1047. Assert.Equal (new Rectangle (0, 0, 1, 5), view.Frame);
  1048. Assert.Equal (new Rectangle (0, 0, 1, 5), view.Viewport);
  1049. }
  1050. // Test behavior of AutoSize property.
  1051. // - Default is false
  1052. // - Setting to true invalidates Height/Width
  1053. // - Setting to false invalidates Height/Width
  1054. }