TextTests.cs 40 KB

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