DrawTests.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. #nullable enable
  2. using System.Text;
  3. using Xunit.Abstractions;
  4. using static System.Net.Mime.MediaTypeNames;
  5. namespace Terminal.Gui.ViewTests;
  6. [Trait ("Category", "Output")]
  7. public class DrawTests (ITestOutputHelper output)
  8. {
  9. [Fact]
  10. [SetupFakeDriver]
  11. public void Move_Is_Constrained_To_Viewport ()
  12. {
  13. var view = new View
  14. {
  15. X = 1,
  16. Y = 1,
  17. Width = 3, Height = 3
  18. };
  19. view.Margin.Thickness = new Thickness (1);
  20. // Only valid location w/in Viewport is 0, 0 (view) - 2, 2 (screen)
  21. view.Move (0, 0);
  22. Assert.Equal (new Point (2, 2), new Point (Application.Driver.Col, Application.Driver.Row));
  23. view.Move (-1, -1);
  24. Assert.Equal (new Point (2, 2), new Point (Application.Driver.Col, Application.Driver.Row));
  25. view.Move (1, 1);
  26. Assert.Equal (new Point (2, 2), new Point (Application.Driver.Col, Application.Driver.Row));
  27. }
  28. [Fact]
  29. [SetupFakeDriver]
  30. public void AddRune_Is_Constrained_To_Viewport ()
  31. {
  32. var view = new View
  33. {
  34. X = 1,
  35. Y = 1,
  36. Width = 3, Height = 3
  37. };
  38. view.Margin.Thickness = new Thickness (1);
  39. View.Diagnostics = ViewDiagnosticFlags.Padding;
  40. view.BeginInit ();
  41. view.EndInit ();
  42. view.Draw ();
  43. // Only valid location w/in Viewport is 0, 0 (view) - 2, 2 (screen)
  44. Assert.Equal ((Rune)' ', Application.Driver.Contents [2, 2].Rune);
  45. view.AddRune (0, 0, Rune.ReplacementChar);
  46. Assert.Equal (Rune.ReplacementChar, Application.Driver.Contents [2, 2].Rune);
  47. view.AddRune (-1, -1, Rune.ReplacementChar);
  48. Assert.Equal ((Rune)'M', Application.Driver.Contents [1, 1].Rune);
  49. view.AddRune (1, 1, Rune.ReplacementChar);
  50. Assert.Equal ((Rune)'M', Application.Driver.Contents [3, 3].Rune);
  51. View.Diagnostics = ViewDiagnosticFlags.Off;
  52. }
  53. [Theory]
  54. [InlineData (0, 0, 1, 1)]
  55. [InlineData (0, 0, 2, 2)]
  56. [InlineData (-1, -1, 2, 2)]
  57. [SetupFakeDriver]
  58. public void FillRect_Fills_HonorsClip (int x, int y, int width, int height)
  59. {
  60. var superView = new View { Width = Dim.Fill (), Height = Dim.Fill () };
  61. var view = new View
  62. {
  63. Text = "X",
  64. X = 1, Y = 1,
  65. Width = 3, Height = 3,
  66. BorderStyle = LineStyle.Single
  67. };
  68. superView.Add (view);
  69. superView.BeginInit ();
  70. superView.EndInit ();
  71. superView.LayoutSubviews ();
  72. superView.Draw ();
  73. TestHelpers.AssertDriverContentsWithFrameAre (
  74. @"
  75. ┌─┐
  76. │X│
  77. └─┘",
  78. output);
  79. Rectangle toFill = new (x, y, width, height);
  80. view.FillRect (toFill);
  81. TestHelpers.AssertDriverContentsWithFrameAre (
  82. @"
  83. ┌─┐
  84. │ │
  85. └─┘",
  86. output);
  87. // Now try to clear beyond Viewport (invalid; clipping should prevent)
  88. superView.SetNeedsDisplay ();
  89. superView.Draw ();
  90. TestHelpers.AssertDriverContentsWithFrameAre (
  91. @"
  92. ┌─┐
  93. │X│
  94. └─┘",
  95. output);
  96. toFill = new (-width, -height, width, height);
  97. view.FillRect (toFill);
  98. TestHelpers.AssertDriverContentsWithFrameAre (
  99. @"
  100. ┌─┐
  101. │X│
  102. └─┘",
  103. output);
  104. // Now try to clear beyond Viewport (valid)
  105. superView.SetNeedsDisplay ();
  106. superView.Draw ();
  107. TestHelpers.AssertDriverContentsWithFrameAre (
  108. @"
  109. ┌─┐
  110. │X│
  111. └─┘",
  112. output);
  113. toFill = new (-1, -1, width + 1, height + 1);
  114. view.FillRect (toFill);
  115. TestHelpers.AssertDriverContentsWithFrameAre (
  116. @"
  117. ┌─┐
  118. │ │
  119. └─┘",
  120. output);
  121. // Now clear too much size
  122. superView.SetNeedsDisplay ();
  123. superView.Draw ();
  124. TestHelpers.AssertDriverContentsWithFrameAre (
  125. @"
  126. ┌─┐
  127. │X│
  128. └─┘",
  129. output);
  130. toFill = new (0, 0, width * 2, height * 2);
  131. view.FillRect (toFill);
  132. TestHelpers.AssertDriverContentsWithFrameAre (
  133. @"
  134. ┌─┐
  135. │ │
  136. └─┘",
  137. output);
  138. }
  139. [Theory]
  140. [InlineData (0, 0, 1, 1)]
  141. [InlineData (0, 0, 2, 2)]
  142. [InlineData (-1, -1, 2, 2)]
  143. [SetupFakeDriver]
  144. public void Clear_ClearsEntireViewport (int x, int y, int width, int height)
  145. {
  146. var superView = new View { Width = Dim.Fill (), Height = Dim.Fill () };
  147. var view = new View
  148. {
  149. Text = "X",
  150. X = 1, Y = 1,
  151. Width = 3, Height = 3,
  152. BorderStyle = LineStyle.Single
  153. };
  154. superView.Add (view);
  155. superView.BeginInit ();
  156. superView.EndInit ();
  157. superView.LayoutSubviews ();
  158. superView.Draw ();
  159. TestHelpers.AssertDriverContentsWithFrameAre (
  160. @"
  161. ┌─┐
  162. │X│
  163. └─┘",
  164. output);
  165. view.Clear ();
  166. TestHelpers.AssertDriverContentsWithFrameAre (
  167. @"
  168. ┌─┐
  169. │ │
  170. └─┘",
  171. output);
  172. }
  173. [Theory]
  174. [InlineData (0, 0, 1, 1)]
  175. [InlineData (0, 0, 2, 2)]
  176. [InlineData (-1, -1, 2, 2)]
  177. [SetupFakeDriver]
  178. public void Clear_WithClearVisibleContentOnly_ClearsVisibleContentOnly (int x, int y, int width, int height)
  179. {
  180. var superView = new View { Width = Dim.Fill (), Height = Dim.Fill () };
  181. var view = new View
  182. {
  183. Text = "X",
  184. X = 1, Y = 1,
  185. Width = 3, Height = 3,
  186. BorderStyle = LineStyle.Single,
  187. ViewportSettings = ViewportSettings.ClearContentOnly
  188. };
  189. superView.Add (view);
  190. superView.BeginInit ();
  191. superView.EndInit ();
  192. superView.LayoutSubviews ();
  193. superView.Draw ();
  194. TestHelpers.AssertDriverContentsWithFrameAre (
  195. @"
  196. ┌─┐
  197. │X│
  198. └─┘",
  199. output);
  200. view.Clear ();
  201. TestHelpers.AssertDriverContentsWithFrameAre (
  202. @"
  203. ┌─┐
  204. │ │
  205. └─┘",
  206. output);
  207. }
  208. [Fact]
  209. [AutoInitShutdown]
  210. [Trait ("Category", "Unicode")]
  211. public void CJK_Compatibility_Ideographs_ConsoleWidth_ColumnWidth_Equal_Two ()
  212. {
  213. const string us = "\U0000f900";
  214. var r = (Rune)0xf900;
  215. Assert.Equal ("豈", us);
  216. Assert.Equal ("豈", r.ToString ());
  217. Assert.Equal (us, r.ToString ());
  218. Assert.Equal (2, us.GetColumns ());
  219. Assert.Equal (2, r.GetColumns ());
  220. var win = new Window { Title = us };
  221. var view = new View { Text = r.ToString (), Height = Dim.Fill (), Width = Dim.Fill ()};
  222. var tf = new TextField { Text = us, Y = 1, Width = 3 };
  223. win.Add (view, tf);
  224. Toplevel top = new ();
  225. top.Add (win);
  226. Application.Begin (top);
  227. ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
  228. const string expectedOutput = """
  229. ┌┤豈├────┐
  230. │豈 │
  231. │豈 │
  232. └────────┘
  233. """;
  234. TestHelpers.AssertDriverContentsWithFrameAre (expectedOutput, output);
  235. TestHelpers.AssertDriverContentsAre (expectedOutput, output);
  236. // This test has nothing to do with color - removing as it is not relevant and fragile
  237. }
  238. // TODO: Refactor this test to not depend on TextView etc... Make it as primitive as possible
  239. [Fact]
  240. [AutoInitShutdown]
  241. [Trait ("Category", "Unicode")]
  242. public void Clipping_AddRune_Left_Or_Right_Replace_Previous_Or_Next_Wide_Rune_With_Space ()
  243. {
  244. var tv = new TextView
  245. {
  246. Width = Dim.Fill (),
  247. Height = Dim.Fill (),
  248. Text = """
  249. これは広いルーンラインです。
  250. これは広いルーンラインです。
  251. これは広いルーンラインです。
  252. これは広いルーンラインです。
  253. これは広いルーンラインです。
  254. これは広いルーンラインです。
  255. これは広いルーンラインです。
  256. これは広いルーンラインです。
  257. """
  258. };
  259. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  260. win.Add (tv);
  261. var top = new Toplevel ();
  262. top.Add (win);
  263. // Don't use Label. It sets AutoSize = true which is not what we're testing here.
  264. var view = new View { Text = "ワイドルーン。", Height = Dim.Fill (), Width = Dim.Fill () };
  265. // Don't have unit tests use things that aren't absolutely critical for the test, like Dialog
  266. var dg = new Window { X = 2, Y = 2, Width = 14, Height = 3 };
  267. dg.Add (view);
  268. RunState rsTop = Application.Begin (top);
  269. RunState rsDiag = Application.Begin (dg);
  270. ((FakeDriver)Application.Driver).SetBufferSize (30, 10);
  271. const string expectedOutput = """
  272. ┌────────────────────────────┐
  273. │これは広いルーンラインです。│
  274. │�┌────────────┐�ラインです。│
  275. │�│ワイドルーン│�ラインです。│
  276. │�└────────────┘�ラインです。│
  277. │これは広いルーンラインです。│
  278. │これは広いルーンラインです。│
  279. │これは広いルーンラインです。│
  280. │これは広いルーンラインです。│
  281. └────────────────────────────┘
  282. """;
  283. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expectedOutput, output);
  284. Assert.Equal (new Rectangle (0, 0, 30, 10), pos);
  285. Application.End (rsDiag);
  286. Application.End (rsTop);
  287. }
  288. [Fact]
  289. [AutoInitShutdown]
  290. [Trait ("Category", "Output")]
  291. public void Colors_On_TextAlignment_Right_And_Bottom ()
  292. {
  293. var viewRight = new View
  294. {
  295. Text = "Test",
  296. Width = 6,
  297. Height = 1,
  298. TextAlignment = TextAlignment.Right,
  299. ColorScheme = Colors.ColorSchemes ["Base"]
  300. };
  301. var viewBottom = new View
  302. {
  303. Text = "Test",
  304. TextDirection = TextDirection.TopBottom_LeftRight,
  305. Y = 1,
  306. Width = 1,
  307. Height = 6,
  308. VerticalTextAlignment = VerticalTextAlignment.Bottom,
  309. ColorScheme = Colors.ColorSchemes ["Base"]
  310. };
  311. Toplevel top = new ();
  312. top.Add (viewRight, viewBottom);
  313. Application.Begin (top);
  314. ((FakeDriver)Application.Driver).SetBufferSize (7, 7);
  315. TestHelpers.AssertDriverContentsWithFrameAre (
  316. """
  317. Test
  318. T
  319. e
  320. s
  321. t
  322. """,
  323. output
  324. );
  325. TestHelpers.AssertDriverAttributesAre (
  326. """
  327. 000000
  328. 0
  329. 0
  330. 0
  331. 0
  332. 0
  333. 0
  334. """,
  335. Application.Driver,
  336. Colors.ColorSchemes ["Base"].Normal
  337. );
  338. }
  339. [Fact]
  340. [SetupFakeDriver]
  341. public void Draw_Minimum_Full_Border_With_Empty_Viewport ()
  342. {
  343. var view = new View { Width = 2, Height = 2, BorderStyle = LineStyle.Single };
  344. view.BeginInit ();
  345. view.EndInit ();
  346. view.SetRelativeLayout (Application.Driver.Screen.Size);
  347. Assert.Equal (new (0, 0, 2, 2), view.Frame);
  348. Assert.Equal (Rectangle.Empty, view.Viewport);
  349. view.Draw ();
  350. TestHelpers.AssertDriverContentsWithFrameAre (
  351. """
  352. ┌┐
  353. └┘
  354. """,
  355. output
  356. );
  357. }
  358. [Fact]
  359. [SetupFakeDriver]
  360. public void Draw_Minimum_Full_Border_With_Empty_Viewport_Without_Bottom ()
  361. {
  362. var view = new View { Width = 2, Height = 1, BorderStyle = LineStyle.Single };
  363. view.Border.Thickness = new Thickness (1, 1, 1, 0);
  364. view.BeginInit ();
  365. view.EndInit ();
  366. view.SetRelativeLayout (Application.Driver.Screen.Size);
  367. Assert.Equal (new (0, 0, 2, 1), view.Frame);
  368. Assert.Equal (Rectangle.Empty, view.Viewport);
  369. view.Draw ();
  370. TestHelpers.AssertDriverContentsWithFrameAre (string.Empty, output);
  371. }
  372. [Fact]
  373. [SetupFakeDriver]
  374. public void Draw_Minimum_Full_Border_With_Empty_Viewport_Without_Left ()
  375. {
  376. var view = new View { Width = 1, Height = 2, BorderStyle = LineStyle.Single };
  377. view.Border.Thickness = new Thickness (0, 1, 1, 1);
  378. view.BeginInit ();
  379. view.EndInit ();
  380. view.SetRelativeLayout (Application.Driver.Screen.Size);
  381. Assert.Equal (new (0, 0, 1, 2), view.Frame);
  382. Assert.Equal (Rectangle.Empty, view.Viewport);
  383. view.Draw ();
  384. TestHelpers.AssertDriverContentsWithFrameAre (
  385. """
  386. """,
  387. output
  388. );
  389. }
  390. [Fact]
  391. [SetupFakeDriver]
  392. public void Draw_Minimum_Full_Border_With_Empty_Viewport_Without_Right ()
  393. {
  394. var view = new View { Width = 1, Height = 2, BorderStyle = LineStyle.Single };
  395. view.Border.Thickness = new Thickness (1, 1, 0, 1);
  396. view.BeginInit ();
  397. view.EndInit ();
  398. view.SetRelativeLayout (Application.Driver.Screen.Size);
  399. Assert.Equal (new (0, 0, 1, 2), view.Frame);
  400. Assert.Equal (Rectangle.Empty, view.Viewport);
  401. view.Draw ();
  402. TestHelpers.AssertDriverContentsWithFrameAre (
  403. """
  404. """,
  405. output
  406. );
  407. }
  408. [Fact]
  409. [SetupFakeDriver]
  410. public void Draw_Minimum_Full_Border_With_Empty_Viewport_Without_Top ()
  411. {
  412. var view = new View { Width = 2, Height = 1, BorderStyle = LineStyle.Single };
  413. view.Border.Thickness = new Thickness (1, 0, 1, 1);
  414. view.BeginInit ();
  415. view.EndInit ();
  416. view.SetRelativeLayout (Application.Driver.Screen.Size);
  417. Assert.Equal (new (0, 0, 2, 1), view.Frame);
  418. Assert.Equal (Rectangle.Empty, view.Viewport);
  419. view.Draw ();
  420. // BUGBUG: Wha? Is this right? Shouldn't it be "└┘"???
  421. TestHelpers.AssertDriverContentsWithFrameAre (
  422. """
  423. ┌┐
  424. """,
  425. output
  426. );
  427. }
  428. [Fact]
  429. [AutoInitShutdown]
  430. public void Draw_Negative_Viewport_Horizontal_With_New_Lines ()
  431. {
  432. var subView = new View
  433. {
  434. Id = "subView",
  435. X = 1,
  436. Width = 1,
  437. Height = 7,
  438. Text = """
  439. s
  440. u
  441. b
  442. V
  443. i
  444. e
  445. w
  446. """
  447. };
  448. var view = new View
  449. {
  450. Id = "view", Width = 2, Height = 20, Text = """
  451. 0
  452. 1
  453. 2
  454. 3
  455. 4
  456. 5
  457. 6
  458. 7
  459. 8
  460. 9
  461. 0
  462. 1
  463. 2
  464. 3
  465. 4
  466. 5
  467. 6
  468. 7
  469. 8
  470. 9
  471. """
  472. };
  473. view.Add (subView);
  474. var content = new View { Id = "content", Width = 20, Height = 20 };
  475. content.Add (view);
  476. var container = new View
  477. {
  478. Id = "container",
  479. X = 1,
  480. Y = 1,
  481. Width = 5,
  482. Height = 5
  483. };
  484. container.Add (content);
  485. Toplevel top = new ();
  486. top.Add (container);
  487. Application.Driver.Clip = container.Frame;
  488. Application.Begin (top);
  489. TestHelpers.AssertDriverContentsWithFrameAre (
  490. """
  491. 0s
  492. 1u
  493. 2b
  494. 3V
  495. 4i
  496. """,
  497. output
  498. );
  499. content.X = -1;
  500. Application.Refresh ();
  501. TestHelpers.AssertDriverContentsWithFrameAre (
  502. """
  503. s
  504. u
  505. b
  506. V
  507. i
  508. """,
  509. output
  510. );
  511. content.X = -2;
  512. Application.Refresh ();
  513. TestHelpers.AssertDriverContentsWithFrameAre (@"", output);
  514. content.X = 0;
  515. content.Y = -1;
  516. Application.Refresh ();
  517. TestHelpers.AssertDriverContentsWithFrameAre (
  518. """
  519. 1u
  520. 2b
  521. 3V
  522. 4i
  523. 5e
  524. """,
  525. output
  526. );
  527. content.Y = -6;
  528. Application.Refresh ();
  529. TestHelpers.AssertDriverContentsWithFrameAre (
  530. """
  531. 6w
  532. 7
  533. 8
  534. 9
  535. 0
  536. """,
  537. output
  538. );
  539. content.Y = -19;
  540. Application.Refresh ();
  541. TestHelpers.AssertDriverContentsWithFrameAre (
  542. """
  543. 9
  544. """,
  545. output
  546. );
  547. content.Y = -20;
  548. Application.Refresh ();
  549. TestHelpers.AssertDriverContentsWithFrameAre ("", output);
  550. content.X = -2;
  551. content.Y = 0;
  552. Application.Refresh ();
  553. TestHelpers.AssertDriverContentsWithFrameAre ("", output);
  554. }
  555. [Fact]
  556. [AutoInitShutdown]
  557. public void Draw_Negative_Viewport_Horizontal_Without_New_Lines ()
  558. {
  559. // BUGBUG: This previously assumed the default height of a View was 1.
  560. var subView = new View
  561. {
  562. Id = "subView",
  563. Y = 1,
  564. Width = 7,
  565. Height = 1,
  566. Text = "subView"
  567. };
  568. var view = new View { Id = "view", Width = 20, Height = 2, Text = "01234567890123456789" };
  569. view.Add (subView);
  570. var content = new View { Id = "content", Width = 20, Height = 20 };
  571. content.Add (view);
  572. var container = new View
  573. {
  574. Id = "container",
  575. X = 1,
  576. Y = 1,
  577. Width = 5,
  578. Height = 5
  579. };
  580. container.Add (content);
  581. Toplevel top = new ();
  582. top.Add (container);
  583. // BUGBUG: v2 - it's bogus to reference .Frame before BeginInit. And why is the clip being set anyway???
  584. void Top_LayoutComplete (object sender, LayoutEventArgs e) { Application.Driver.Clip = container.Frame; }
  585. top.LayoutComplete += Top_LayoutComplete;
  586. Application.Begin (top);
  587. TestHelpers.AssertDriverContentsWithFrameAre (
  588. """
  589. 01234
  590. subVi
  591. """,
  592. output
  593. );
  594. content.X = -1;
  595. Application.Refresh ();
  596. TestHelpers.AssertDriverContentsWithFrameAre (
  597. """
  598. 12345
  599. ubVie
  600. """,
  601. output
  602. );
  603. content.Y = -1;
  604. Application.Refresh ();
  605. TestHelpers.AssertDriverContentsWithFrameAre (
  606. """
  607. ubVie
  608. """,
  609. output
  610. );
  611. content.Y = -2;
  612. Application.Refresh ();
  613. TestHelpers.AssertDriverContentsWithFrameAre ("", output);
  614. content.X = -20;
  615. content.Y = 0;
  616. Application.Refresh ();
  617. TestHelpers.AssertDriverContentsWithFrameAre ("", output);
  618. }
  619. [Fact]
  620. [AutoInitShutdown]
  621. public void Draw_Negative_Viewport_Vertical ()
  622. {
  623. var subView = new View
  624. {
  625. Id = "subView",
  626. X = 1,
  627. Width = 1,
  628. Height = 7,
  629. Text = "subView",
  630. TextDirection = TextDirection.TopBottom_LeftRight
  631. };
  632. var view = new View
  633. {
  634. Id = "view",
  635. Width = 2,
  636. Height = 20,
  637. Text = "01234567890123456789",
  638. TextDirection = TextDirection.TopBottom_LeftRight
  639. };
  640. view.Add (subView);
  641. var content = new View { Id = "content", Width = 20, Height = 20 };
  642. content.Add (view);
  643. var container = new View
  644. {
  645. Id = "container",
  646. X = 1,
  647. Y = 1,
  648. Width = 5,
  649. Height = 5
  650. };
  651. container.Add (content);
  652. Toplevel top = new ();
  653. top.Add (container);
  654. Application.Driver.Clip = container.Frame;
  655. Application.Begin (top);
  656. TestHelpers.AssertDriverContentsWithFrameAre (
  657. """
  658. 0s
  659. 1u
  660. 2b
  661. 3V
  662. 4i
  663. """,
  664. output
  665. );
  666. content.X = -1;
  667. Application.Refresh ();
  668. TestHelpers.AssertDriverContentsWithFrameAre (
  669. """
  670. s
  671. u
  672. b
  673. V
  674. i
  675. """,
  676. output
  677. );
  678. content.X = -2;
  679. Application.Refresh ();
  680. TestHelpers.AssertDriverContentsWithFrameAre (@"", output);
  681. content.X = 0;
  682. content.Y = -1;
  683. Application.Refresh ();
  684. TestHelpers.AssertDriverContentsWithFrameAre (
  685. """
  686. 1u
  687. 2b
  688. 3V
  689. 4i
  690. 5e
  691. """,
  692. output
  693. );
  694. content.Y = -6;
  695. Application.Refresh ();
  696. TestHelpers.AssertDriverContentsWithFrameAre (
  697. """
  698. 6w
  699. 7
  700. 8
  701. 9
  702. 0
  703. """,
  704. output
  705. );
  706. content.Y = -19;
  707. Application.Refresh ();
  708. TestHelpers.AssertDriverContentsWithFrameAre (
  709. """
  710. 9
  711. """,
  712. output
  713. );
  714. content.Y = -20;
  715. Application.Refresh ();
  716. TestHelpers.AssertDriverContentsWithFrameAre ("", output);
  717. content.X = -2;
  718. content.Y = 0;
  719. Application.Refresh ();
  720. TestHelpers.AssertDriverContentsWithFrameAre ("", output);
  721. }
  722. [Theory]
  723. [SetupFakeDriver]
  724. [InlineData ("𝔽𝕆𝕆𝔹𝔸R")]
  725. [InlineData ("a𐐀b")]
  726. public void DrawHotString_NonBmp (string expected)
  727. {
  728. var view = new View { Width = 10, Height = 1 };
  729. view.DrawHotString (expected, Attribute.Default, Attribute.Default);
  730. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  731. }
  732. // TODO: The tests below that use Label should use View instead.
  733. [Fact]
  734. [AutoInitShutdown]
  735. public void Non_Bmp_ConsoleWidth_ColumnWidth_Equal_Two ()
  736. {
  737. var us = "\U0001d539";
  738. var r = (Rune)0x1d539;
  739. Assert.Equal ("𝔹", us);
  740. Assert.Equal ("𝔹", r.ToString ());
  741. Assert.Equal (us, r.ToString ());
  742. Assert.Equal (1, us.GetColumns ());
  743. Assert.Equal (1, r.GetColumns ());
  744. var win = new Window { Title = us };
  745. var view = new Label { Text = r.ToString () };
  746. var tf = new TextField { Text = us, Y = 1, Width = 3 };
  747. win.Add (view, tf);
  748. Toplevel top = new ();
  749. top.Add (win);
  750. Application.Begin (top);
  751. ((FakeDriver)Application.Driver).SetBufferSize (10, 4);
  752. var expected = """
  753. ┌┤𝔹├─────┐
  754. │𝔹 │
  755. │𝔹 │
  756. └────────┘
  757. """;
  758. TestHelpers.AssertDriverContentsWithFrameAre (expected, output);
  759. TestHelpers.AssertDriverContentsAre (expected, output);
  760. // This test has nothing to do with color - removing as it is not relevant and fragile
  761. }
  762. [Fact]
  763. [SetupFakeDriver]
  764. public void SetClip_ClipVisibleContentOnly_VisibleContentIsClipped ()
  765. {
  766. // Screen is 25x25
  767. // View is 25x25
  768. // Viewport is (0, 0, 23, 23)
  769. // ContentSize is (10, 10)
  770. // ViewportToScreen is (1, 1, 23, 23)
  771. // Visible content is (1, 1, 10, 10)
  772. // Expected clip is (1, 1, 10, 10) - same as visible content
  773. Rectangle expectedClip = new (1, 1, 10, 10);
  774. // Arrange
  775. var view = new View ()
  776. {
  777. Width = Dim.Fill (),
  778. Height = Dim.Fill (),
  779. ContentSize = new Size (10, 10),
  780. ViewportSettings = ViewportSettings.ClipContentOnly
  781. };
  782. view.Border.Thickness = new Thickness (1);
  783. view.BeginInit ();
  784. view.EndInit ();
  785. Assert.Equal (view.Frame, Application.Driver.Clip);
  786. // Act
  787. view.SetClip ();
  788. // Assert
  789. Assert.Equal (expectedClip, Application.Driver.Clip);
  790. view.Dispose ();
  791. }
  792. [Fact]
  793. [SetupFakeDriver]
  794. public void SetClip_Default_ClipsToViewport ()
  795. {
  796. // Screen is 25x25
  797. // View is 25x25
  798. // Viewport is (0, 0, 23, 23)
  799. // ContentSize is (10, 10)
  800. // ViewportToScreen is (1, 1, 23, 23)
  801. // Visible content is (1, 1, 10, 10)
  802. // Expected clip is (1, 1, 23, 23) - same as Viewport
  803. Rectangle expectedClip = new (1, 1, 23, 23);
  804. // Arrange
  805. var view = new View ()
  806. {
  807. Width = Dim.Fill (),
  808. Height = Dim.Fill (),
  809. ContentSize = new Size (10, 10),
  810. };
  811. view.Border.Thickness = new Thickness (1);
  812. view.BeginInit ();
  813. view.EndInit ();
  814. Assert.Equal (view.Frame, Application.Driver.Clip);
  815. view.Viewport = view.Viewport with { X = 1, Y = 1 };
  816. // Act
  817. view.SetClip ();
  818. // Assert
  819. Assert.Equal (expectedClip, Application.Driver.Clip);
  820. view.Dispose ();
  821. }
  822. }