ViewTests.cs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. using System.ComponentModel;
  2. using System.Text;
  3. using Xunit.Abstractions;
  4. namespace Terminal.Gui.ViewTests;
  5. public class ViewTests
  6. {
  7. private readonly ITestOutputHelper _output;
  8. public ViewTests (ITestOutputHelper output) { _output = output; }
  9. [Fact]
  10. [AutoInitShutdown]
  11. public void Clear_Bounds_Can_Use_Driver_AddRune_Or_AddStr_Methods ()
  12. {
  13. var view = new FrameView { Width = Dim.Fill (), Height = Dim.Fill () };
  14. view.DrawContent += (s, e) =>
  15. {
  16. Rectangle savedClip = Application.Driver.Clip;
  17. Application.Driver.Clip = new Rectangle (1, 1, view.Bounds.Width, view.Bounds.Height);
  18. for (var row = 0; row < view.Bounds.Height; row++)
  19. {
  20. Application.Driver.Move (1, row + 1);
  21. for (var col = 0; col < view.Bounds.Width; col++)
  22. {
  23. Application.Driver.AddStr ($"{col}");
  24. }
  25. }
  26. Application.Driver.Clip = savedClip;
  27. e.Cancel = true;
  28. };
  29. Application.Top.Add (view);
  30. Application.Begin (Application.Top);
  31. ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
  32. var expected = @"
  33. ┌──────────────────┐
  34. │012345678910111213│
  35. │012345678910111213│
  36. │012345678910111213│
  37. │012345678910111213│
  38. │012345678910111213│
  39. │012345678910111213│
  40. │012345678910111213│
  41. │012345678910111213│
  42. └──────────────────┘
  43. ";
  44. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  45. Assert.Equal (new Rectangle (0, 0, 20, 10), pos);
  46. view.Clear (view.Frame);
  47. expected = @"
  48. ";
  49. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  50. Assert.Equal (Rectangle.Empty, pos);
  51. }
  52. [Fact]
  53. [AutoInitShutdown]
  54. public void Clear_Can_Use_Driver_AddRune_Or_AddStr_Methods ()
  55. {
  56. var view = new FrameView { Width = Dim.Fill (), Height = Dim.Fill () };
  57. view.DrawContent += (s, e) =>
  58. {
  59. Rectangle savedClip = Application.Driver.Clip;
  60. Application.Driver.Clip = new Rectangle (1, 1, view.Bounds.Width, view.Bounds.Height);
  61. for (var row = 0; row < view.Bounds.Height; row++)
  62. {
  63. Application.Driver.Move (1, row + 1);
  64. for (var col = 0; col < view.Bounds.Width; col++)
  65. {
  66. Application.Driver.AddStr ($"{col}");
  67. }
  68. }
  69. Application.Driver.Clip = savedClip;
  70. e.Cancel = true;
  71. };
  72. Application.Top.Add (view);
  73. Application.Begin (Application.Top);
  74. ((FakeDriver)Application.Driver).SetBufferSize (20, 10);
  75. var expected = @"
  76. ┌──────────────────┐
  77. │012345678910111213│
  78. │012345678910111213│
  79. │012345678910111213│
  80. │012345678910111213│
  81. │012345678910111213│
  82. │012345678910111213│
  83. │012345678910111213│
  84. │012345678910111213│
  85. └──────────────────┘
  86. ";
  87. Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  88. Assert.Equal (new Rectangle (0, 0, 20, 10), pos);
  89. view.Clear (view.Frame);
  90. expected = @"
  91. ";
  92. pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output);
  93. Assert.Equal (Rectangle.Empty, pos);
  94. }
  95. [Theory]
  96. [AutoInitShutdown]
  97. [InlineData (true)]
  98. [InlineData (false)]
  99. public void Clear_Does_Not_Spillover_Its_Parent (bool label)
  100. {
  101. var root = new View { Width = 20, Height = 10, ColorScheme = Colors.ColorSchemes ["Base"] };
  102. View v = label
  103. ? new Label { Text = new string ('c', 100) }
  104. : new TextView { Height = 1, Text = new string ('c', 100), Width = Dim.Fill () };
  105. root.Add (v);
  106. Application.Top.Add (root);
  107. RunState runState = Application.Begin (Application.Top);
  108. if (label)
  109. {
  110. Assert.True (v.AutoSize);
  111. Assert.False (v.CanFocus);
  112. Assert.Equal (new Rectangle (0, 0, 100, 1), v.Frame);
  113. }
  114. else
  115. {
  116. Assert.False (v.AutoSize);
  117. Assert.True (v.CanFocus);
  118. Assert.Equal (new Rectangle (0, 0, 20, 1), v.Frame);
  119. }
  120. TestHelpers.AssertDriverContentsWithFrameAre (
  121. @"
  122. cccccccccccccccccccc",
  123. _output
  124. );
  125. Attribute [] attributes =
  126. {
  127. Colors.ColorSchemes ["TopLevel"].Normal,
  128. Colors.ColorSchemes ["Base"].Normal,
  129. Colors.ColorSchemes ["Base"].Focus
  130. };
  131. if (label)
  132. {
  133. TestHelpers.AssertDriverAttributesAre (
  134. @"
  135. 111111111111111111110
  136. 111111111111111111110",
  137. Application.Driver,
  138. attributes
  139. );
  140. }
  141. else
  142. {
  143. TestHelpers.AssertDriverAttributesAre (
  144. @"
  145. 222222222222222222220
  146. 111111111111111111110",
  147. Application.Driver,
  148. attributes
  149. );
  150. }
  151. if (label)
  152. {
  153. root.CanFocus = true;
  154. v.CanFocus = true;
  155. Assert.False (v.HasFocus);
  156. v.SetFocus ();
  157. Assert.True (v.HasFocus);
  158. Application.Refresh ();
  159. TestHelpers.AssertDriverAttributesAre (
  160. @"
  161. 222222222222222222220
  162. 111111111111111111110",
  163. Application.Driver,
  164. attributes
  165. );
  166. }
  167. Application.End (runState);
  168. }
  169. [Fact]
  170. [AutoInitShutdown]
  171. public void Correct_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Down_Right_Using_Frame ()
  172. {
  173. var label = new Label { Text = "At 0,0" };
  174. var view = new DerivedView
  175. {
  176. X = 2,
  177. Y = 2,
  178. Width = 30,
  179. Height = 2,
  180. Text = "A text with some long width\n and also with two lines."
  181. };
  182. Toplevel top = Application.Top;
  183. top.Add (label, view);
  184. RunState runState = Application.Begin (top);
  185. TestHelpers.AssertDriverContentsWithFrameAre (
  186. @"
  187. At 0,0
  188. A text with some long width
  189. and also with two lines. ",
  190. _output
  191. );
  192. view.Frame = new Rectangle (3, 3, 10, 1);
  193. Assert.Equal (new Rectangle (3, 3, 10, 1), view.Frame);
  194. Assert.Equal (LayoutStyle.Absolute, view.LayoutStyle);
  195. Assert.Equal (new Rectangle (0, 0, 10, 1), view.Bounds);
  196. Assert.Equal (new Rectangle (0, 0, 10, 1), view._needsDisplayRect);
  197. top.Draw ();
  198. TestHelpers.AssertDriverContentsWithFrameAre (
  199. @"
  200. At 0,0
  201. A text wit",
  202. _output
  203. );
  204. Application.End (runState);
  205. }
  206. [Fact]
  207. [AutoInitShutdown]
  208. public void Correct_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Down_Right_Using_Pos_Dim ()
  209. {
  210. var label = new Label { Text = "At 0,0" };
  211. var view = new DerivedView
  212. {
  213. X = 2,
  214. Y = 2,
  215. Width = 30,
  216. Height = 2,
  217. Text = "A text with some long width\n and also with two lines."
  218. };
  219. Toplevel top = Application.Top;
  220. top.Add (label, view);
  221. RunState runState = Application.Begin (top);
  222. top.Draw ();
  223. TestHelpers.AssertDriverContentsWithFrameAre (
  224. @"
  225. At 0,0
  226. A text with some long width
  227. and also with two lines. ",
  228. _output
  229. );
  230. view.X = 3;
  231. view.Y = 3;
  232. view.Width = 10;
  233. view.Height = 1;
  234. Assert.Equal (new Rectangle (3, 3, 10, 1), view.Frame);
  235. Assert.Equal (new Rectangle (0, 0, 10, 1), view.Bounds);
  236. Assert.Equal (new Rectangle (0, 0, 30, 2), view._needsDisplayRect);
  237. top.Draw ();
  238. TestHelpers.AssertDriverContentsWithFrameAre (
  239. @"
  240. At 0,0
  241. A text wit",
  242. _output
  243. );
  244. Application.End (runState);
  245. }
  246. [Fact]
  247. [AutoInitShutdown]
  248. public void Correct_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Up_Left_Using_Frame ()
  249. {
  250. var label = new Label { Text = "At 0,0" };
  251. var view = new DerivedView
  252. {
  253. X = 2,
  254. Y = 2,
  255. Width = 30,
  256. Height = 2,
  257. Text = "A text with some long width\n and also with two lines."
  258. };
  259. Toplevel top = Application.Top;
  260. top.Add (label, view);
  261. RunState runState = Application.Begin (top);
  262. top.Draw ();
  263. TestHelpers.AssertDriverContentsWithFrameAre (
  264. @"
  265. At 0,0
  266. A text with some long width
  267. and also with two lines. ",
  268. _output
  269. );
  270. view.Frame = new Rectangle (1, 1, 10, 1);
  271. Assert.Equal (new Rectangle (1, 1, 10, 1), view.Frame);
  272. Assert.Equal (LayoutStyle.Absolute, view.LayoutStyle);
  273. Assert.Equal (new Rectangle (0, 0, 10, 1), view.Bounds);
  274. Assert.Equal (new Rectangle (0, 0, 10, 1), view._needsDisplayRect);
  275. top.Draw ();
  276. TestHelpers.AssertDriverContentsWithFrameAre (
  277. @"
  278. At 0,0
  279. A text wit",
  280. _output
  281. );
  282. Application.End (runState);
  283. }
  284. [Fact]
  285. [AutoInitShutdown]
  286. public void Correct_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Up_Left_Using_Pos_Dim ()
  287. {
  288. var label = new Label { Text = "At 0,0" };
  289. var view = new DerivedView
  290. {
  291. X = 2,
  292. Y = 2,
  293. Width = 30,
  294. Height = 2,
  295. Text = "A text with some long width\n and also with two lines."
  296. };
  297. Toplevel top = Application.Top;
  298. top.Add (label, view);
  299. RunState runState = Application.Begin (top);
  300. top.Draw ();
  301. TestHelpers.AssertDriverContentsWithFrameAre (
  302. @"
  303. At 0,0
  304. A text with some long width
  305. and also with two lines. ",
  306. _output
  307. );
  308. view.X = 1;
  309. view.Y = 1;
  310. view.Width = 10;
  311. view.Height = 1;
  312. Assert.Equal (new Rectangle (1, 1, 10, 1), view.Frame);
  313. Assert.Equal (new Rectangle (0, 0, 10, 1), view.Bounds);
  314. Assert.Equal (new Rectangle (0, 0, 30, 2), view._needsDisplayRect);
  315. top.Draw ();
  316. TestHelpers.AssertDriverContentsWithFrameAre (
  317. @"
  318. At 0,0
  319. A text wit",
  320. _output
  321. );
  322. Application.End (runState);
  323. }
  324. [Fact]
  325. [TestRespondersDisposed]
  326. public void Dispose_View ()
  327. {
  328. var view = new View ();
  329. Assert.NotNull (view.Margin);
  330. Assert.NotNull (view.Border);
  331. Assert.NotNull (view.Padding);
  332. #if DEBUG_IDISPOSABLE
  333. Assert.Equal (4, Responder.Instances.Count);
  334. #endif
  335. view.Dispose ();
  336. Assert.Null (view.Margin);
  337. Assert.Null (view.Border);
  338. Assert.Null (view.Padding);
  339. }
  340. [Fact]
  341. [AutoInitShutdown]
  342. public void DrawContentComplete_Event_Is_Always_Called ()
  343. {
  344. var viewCalled = false;
  345. var tvCalled = false;
  346. var view = new View { Width = 10, Height = 10, Text = "View" };
  347. view.DrawContentComplete += (s, e) => viewCalled = true;
  348. var tv = new TextView { Y = 11, Width = 10, Height = 10 };
  349. tv.DrawContentComplete += (s, e) => tvCalled = true;
  350. Application.Top.Add (view, tv);
  351. Application.Begin (Application.Top);
  352. Assert.True (viewCalled);
  353. Assert.True (tvCalled);
  354. }
  355. [Fact]
  356. [AutoInitShutdown]
  357. public void Frame_Set_After_Initialize_Update_NeededDisplay ()
  358. {
  359. var frame = new FrameView ();
  360. var label = new Label
  361. {
  362. ColorScheme = Colors.ColorSchemes ["Menu"], X = 0, Y = 0, Text = "This should be the first line."
  363. };
  364. var button = new Button
  365. {
  366. X = 0, // don't overcomplicate unit tests
  367. Y = 1,
  368. Text = "Press me!"
  369. };
  370. frame.Add (label, button);
  371. frame.X = Pos.Center ();
  372. frame.Y = Pos.Center ();
  373. frame.Width = 40;
  374. frame.Height = 8;
  375. Toplevel top = Application.Top;
  376. top.Add (frame);
  377. RunState runState = Application.Begin (top);
  378. top.LayoutComplete += (s, e) => { Assert.Equal (new Rectangle (0, 0, 80, 25), top._needsDisplayRect); };
  379. frame.LayoutComplete += (s, e) => { Assert.Equal (new Rectangle (0, 0, 40, 8), frame._needsDisplayRect); };
  380. label.LayoutComplete += (s, e) => { Assert.Equal (new Rectangle (0, 0, 38, 1), label._needsDisplayRect); };
  381. button.LayoutComplete += (s, e) => { Assert.Equal (new Rectangle (0, 0, 13, 1), button._needsDisplayRect); };
  382. Assert.True (label.AutoSize);
  383. Assert.Equal (new Rectangle (0, 0, 80, 25), top.Frame);
  384. Assert.Equal (new Rectangle (20, 8, 40, 8), frame.Frame);
  385. Assert.Equal (
  386. new Rectangle (20, 8, 60, 16),
  387. new Rectangle (
  388. frame.Frame.Left,
  389. frame.Frame.Top,
  390. frame.Frame.Right,
  391. frame.Frame.Bottom
  392. )
  393. );
  394. Assert.Equal (new Rectangle (0, 0, 30, 1), label.Frame);
  395. Assert.Equal (new Rectangle (0, 1, 13, 1), button.Frame); // this proves frame was set
  396. Application.End (runState);
  397. }
  398. [Fact]
  399. [AutoInitShutdown]
  400. public void GetHotNormalColor_ColorScheme ()
  401. {
  402. var view = new View { ColorScheme = Colors.ColorSchemes ["Base"] };
  403. Assert.Equal (view.ColorScheme.HotNormal, view.GetHotNormalColor ());
  404. view.Enabled = false;
  405. Assert.Equal (view.ColorScheme.Disabled, view.GetHotNormalColor ());
  406. view.Dispose ();
  407. }
  408. [Fact]
  409. [AutoInitShutdown]
  410. public void GetNormalColor_ColorScheme ()
  411. {
  412. var view = new View { ColorScheme = Colors.ColorSchemes ["Base"] };
  413. Assert.Equal (view.ColorScheme.Normal, view.GetNormalColor ());
  414. view.Enabled = false;
  415. Assert.Equal (view.ColorScheme.Disabled, view.GetNormalColor ());
  416. view.Dispose ();
  417. }
  418. [Fact]
  419. [AutoInitShutdown]
  420. public void Incorrect_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Down_Right_Using_Frame ()
  421. {
  422. var label = new Label { Text = "At 0,0" };
  423. var view = new DerivedView
  424. {
  425. X = 2,
  426. Y = 2,
  427. Width = 30,
  428. Height = 2,
  429. Text = "A text with some long width\n and also with two lines."
  430. };
  431. Toplevel top = Application.Top;
  432. top.Add (label, view);
  433. RunState runState = Application.Begin (top);
  434. view.Draw ();
  435. TestHelpers.AssertDriverContentsWithFrameAre (
  436. @"
  437. At 0,0
  438. A text with some long width
  439. and also with two lines. ",
  440. _output
  441. );
  442. view.Frame = new Rectangle (3, 3, 10, 1);
  443. Assert.Equal (new Rectangle (0, 0, 10, 1), view.Bounds);
  444. Assert.Equal (new Rectangle (0, 0, 10, 1), view._needsDisplayRect);
  445. view.Draw ();
  446. TestHelpers.AssertDriverContentsWithFrameAre (
  447. @"
  448. At 0,0
  449. A text with some long width
  450. A text witith two lines. ",
  451. _output
  452. );
  453. Application.End (runState);
  454. }
  455. [Fact]
  456. [AutoInitShutdown]
  457. public void Incorrect_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Down_Right_Using_Pos_Dim ()
  458. {
  459. var label = new Label { Text = "At 0,0" };
  460. var view = new DerivedView
  461. {
  462. X = 2,
  463. Y = 2,
  464. Width = 30,
  465. Height = 2,
  466. Text = "A text with some long width\n and also with two lines."
  467. };
  468. Toplevel top = Application.Top;
  469. top.Add (label, view);
  470. RunState runState = Application.Begin (top);
  471. view.Draw ();
  472. TestHelpers.AssertDriverContentsWithFrameAre (
  473. @"
  474. At 0,0
  475. A text with some long width
  476. and also with two lines. ",
  477. _output
  478. );
  479. view.X = 3;
  480. view.Y = 3;
  481. view.Width = 10;
  482. view.Height = 1;
  483. Assert.Equal (new Rectangle (3, 3, 10, 1), view.Frame);
  484. Assert.Equal (new Rectangle (0, 0, 10, 1), view.Bounds);
  485. Assert.Equal (new Rectangle (0, 0, 30, 2), view._needsDisplayRect);
  486. view.Draw ();
  487. TestHelpers.AssertDriverContentsWithFrameAre (
  488. @"
  489. At 0,0
  490. A text with some long width
  491. A text witith two lines. ",
  492. _output
  493. );
  494. Application.End (runState);
  495. }
  496. [Fact]
  497. [AutoInitShutdown]
  498. public void Incorrect_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Up_Left_Using_Frame ()
  499. {
  500. var label = new Label { Text = "At 0,0" };
  501. var view = new DerivedView
  502. {
  503. X = 2,
  504. Y = 2,
  505. Width = 30,
  506. Height = 2,
  507. Text = "A text with some long width\n and also with two lines."
  508. };
  509. Toplevel top = Application.Top;
  510. top.Add (label, view);
  511. RunState runState = Application.Begin (top);
  512. view.Draw ();
  513. TestHelpers.AssertDriverContentsWithFrameAre (
  514. @"
  515. At 0,0
  516. A text with some long width
  517. and also with two lines. ",
  518. _output
  519. );
  520. view.Frame = new Rectangle (1, 1, 10, 1);
  521. Assert.Equal (new Rectangle (1, 1, 10, 1), view.Frame);
  522. Assert.Equal (LayoutStyle.Absolute, view.LayoutStyle);
  523. Assert.Equal (new Rectangle (0, 0, 10, 1), view.Bounds);
  524. Assert.Equal (new Rectangle (0, 0, 10, 1), view._needsDisplayRect);
  525. view.Draw ();
  526. TestHelpers.AssertDriverContentsWithFrameAre (
  527. @"
  528. At 0,0
  529. A text wit
  530. A text with some long width
  531. and also with two lines. ",
  532. _output
  533. );
  534. Application.End (runState);
  535. }
  536. [Fact]
  537. [AutoInitShutdown]
  538. public void Incorrect_Redraw_Bounds_NeedDisplay_On_Shrink_And_Move_Up_Left_Using_Pos_Dim ()
  539. {
  540. var label = new Label { Text = "At 0,0" };
  541. var view = new DerivedView
  542. {
  543. X = 2,
  544. Y = 2,
  545. Width = 30,
  546. Height = 2,
  547. Text = "A text with some long width\n and also with two lines."
  548. };
  549. Toplevel top = Application.Top;
  550. top.Add (label, view);
  551. RunState runState = Application.Begin (top);
  552. view.Draw ();
  553. TestHelpers.AssertDriverContentsWithFrameAre (
  554. @"
  555. At 0,0
  556. A text with some long width
  557. and also with two lines. ",
  558. _output
  559. );
  560. view.X = 1;
  561. view.Y = 1;
  562. view.Width = 10;
  563. view.Height = 1;
  564. Assert.Equal (new Rectangle (1, 1, 10, 1), view.Frame);
  565. Assert.Equal (new Rectangle (0, 0, 10, 1), view.Bounds);
  566. Assert.Equal (new Rectangle (0, 0, 30, 2), view._needsDisplayRect);
  567. view.Draw ();
  568. TestHelpers.AssertDriverContentsWithFrameAre (
  569. @"
  570. At 0,0
  571. A text wit
  572. A text with some long width
  573. and also with two lines. ",
  574. _output
  575. );
  576. Application.End (runState);
  577. }
  578. [Fact]
  579. public void Internal_Tests ()
  580. {
  581. var rect = new Rectangle (1, 1, 10, 1);
  582. var view = new View { Frame = rect };
  583. }
  584. [Fact]
  585. [SetupFakeDriver]
  586. public void SetText_RendersCorrectly ()
  587. {
  588. View view;
  589. var text = "test";
  590. view = new Label { Text = text };
  591. view.BeginInit ();
  592. view.EndInit ();
  593. view.Draw ();
  594. TestHelpers.AssertDriverContentsWithFrameAre ( text, _output);
  595. }
  596. [Fact]
  597. [TestRespondersDisposed]
  598. public void New_Initializes ()
  599. {
  600. // Parameterless
  601. var r = new View ();
  602. Assert.NotNull (r);
  603. Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
  604. Assert.Equal ($"View(){r.Bounds}", r.ToString ());
  605. Assert.False (r.CanFocus);
  606. Assert.False (r.HasFocus);
  607. Assert.Equal (new Rectangle (0, 0, 0, 0), r.Bounds);
  608. Assert.Equal (new Rectangle (0, 0, 0, 0), r.Frame);
  609. Assert.Null (r.Focused);
  610. Assert.Null (r.ColorScheme);
  611. Assert.Equal (0, r.Width);
  612. Assert.Equal (0, r.Height);
  613. Assert.Equal (0, r.X);
  614. Assert.Equal (0, r.Y);
  615. Assert.False (r.IsCurrentTop);
  616. Assert.Empty (r.Id);
  617. Assert.Empty (r.Subviews);
  618. Assert.False (r.WantContinuousButtonPressed);
  619. Assert.False (r.WantMousePositionReports);
  620. Assert.Null (r.SuperView);
  621. Assert.Null (r.MostFocused);
  622. Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
  623. r.Dispose ();
  624. // Empty Rect
  625. r = new View { Frame = Rectangle.Empty };
  626. Assert.NotNull (r);
  627. Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
  628. Assert.Equal ($"View(){r.Bounds}", r.ToString ());
  629. Assert.False (r.CanFocus);
  630. Assert.False (r.HasFocus);
  631. Assert.Equal (new Rectangle (0, 0, 0, 0), r.Bounds);
  632. Assert.Equal (new Rectangle (0, 0, 0, 0), r.Frame);
  633. Assert.Null (r.Focused);
  634. Assert.Null (r.ColorScheme);
  635. Assert.Equal (0, r.Width);
  636. Assert.Equal (0, r.Height);
  637. Assert.Equal (0, r.X);
  638. Assert.Equal (0, r.Y);
  639. Assert.False (r.IsCurrentTop);
  640. Assert.Empty (r.Id);
  641. Assert.Empty (r.Subviews);
  642. Assert.False (r.WantContinuousButtonPressed);
  643. Assert.False (r.WantMousePositionReports);
  644. Assert.Null (r.SuperView);
  645. Assert.Null (r.MostFocused);
  646. Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
  647. r.Dispose ();
  648. // Rect with values
  649. r = new View { Frame = new Rectangle (1, 2, 3, 4) };
  650. Assert.NotNull (r);
  651. Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
  652. Assert.Equal ($"View(){r.Frame}", r.ToString ());
  653. Assert.False (r.CanFocus);
  654. Assert.False (r.HasFocus);
  655. Assert.Equal (new Rectangle (0, 0, 3, 4), r.Bounds);
  656. Assert.Equal (new Rectangle (1, 2, 3, 4), r.Frame);
  657. Assert.Null (r.Focused);
  658. Assert.Null (r.ColorScheme);
  659. Assert.Equal (3, r.Width);
  660. Assert.Equal (4, r.Height);
  661. Assert.Equal (1, r.X);
  662. Assert.Equal (2, r.Y);
  663. Assert.False (r.IsCurrentTop);
  664. Assert.Empty (r.Id);
  665. Assert.Empty (r.Subviews);
  666. Assert.False (r.WantContinuousButtonPressed);
  667. Assert.False (r.WantMousePositionReports);
  668. Assert.Null (r.SuperView);
  669. Assert.Null (r.MostFocused);
  670. Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection);
  671. r.Dispose ();
  672. // Initializes a view with a vertical direction
  673. r = new View
  674. {
  675. Text = "Vertical View", TextDirection = TextDirection.TopBottom_LeftRight, AutoSize = true
  676. }; // BUGBUG: AutoSize or Height need be set
  677. Assert.NotNull (r);
  678. Assert.Equal (LayoutStyle.Absolute, r.LayoutStyle);
  679. // BUGBUG: IsInitialized must be true to process calculation
  680. r.BeginInit ();
  681. r.EndInit ();
  682. Assert.False (r.CanFocus);
  683. Assert.False (r.HasFocus);
  684. Assert.Equal (new Rectangle (0, 0, 1, 13), r.Bounds);
  685. Assert.Equal (new Rectangle (0, 0, 1, 13), r.Frame);
  686. Assert.Null (r.Focused);
  687. Assert.Null (r.ColorScheme);
  688. Assert.False (r.IsCurrentTop);
  689. #if DEBUG
  690. Assert.Equal ("Vertical View", r.Id);
  691. #else
  692. Assert.Equal (string.Empty, r.Id);
  693. #endif
  694. Assert.Empty (r.Subviews);
  695. Assert.False (r.WantContinuousButtonPressed);
  696. Assert.False (r.WantMousePositionReports);
  697. Assert.Null (r.SuperView);
  698. Assert.Null (r.MostFocused);
  699. Assert.Equal (TextDirection.TopBottom_LeftRight, r.TextDirection);
  700. r.Dispose ();
  701. }
  702. [Fact]
  703. [TestRespondersDisposed]
  704. public void New_Methods_Return_False ()
  705. {
  706. var r = new View ();
  707. Assert.False (r.OnKeyDown (new Key { KeyCode = KeyCode.Null }));
  708. //Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown }));
  709. Assert.False (r.OnKeyUp (new Key { KeyCode = KeyCode.Null }));
  710. Assert.False (r.OnMouseEvent (new MouseEvent { Flags = MouseFlags.AllEvents }));
  711. Assert.False (r.OnMouseEnter (new MouseEvent { Flags = MouseFlags.AllEvents }));
  712. Assert.False (r.OnMouseLeave (new MouseEvent { Flags = MouseFlags.AllEvents }));
  713. var v1 = new View ();
  714. Assert.False (r.OnEnter (v1));
  715. v1.Dispose ();
  716. var v2 = new View ();
  717. Assert.False (r.OnLeave (v2));
  718. v2.Dispose ();
  719. r.Dispose ();
  720. // TODO: Add more
  721. }
  722. [Fact]
  723. [AutoInitShutdown]
  724. public void Test_Nested_Views_With_Height_Equal_To_One ()
  725. {
  726. var v = new View { Width = 11, Height = 3, ColorScheme = new ColorScheme () };
  727. var top = new View { Width = Dim.Fill (), Height = 1 };
  728. var bottom = new View { Width = Dim.Fill (), Height = 1, Y = 2 };
  729. top.Add (new Label { Text = "111" });
  730. v.Add (top);
  731. v.Add (new LineView (Orientation.Horizontal) { Y = 1 });
  732. bottom.Add (new Label { Text = "222" });
  733. v.Add (bottom);
  734. v.BeginInit ();
  735. v.EndInit ();
  736. v.LayoutSubviews ();
  737. v.Draw ();
  738. var looksLike =
  739. @"
  740. 111
  741. ───────────
  742. 222";
  743. TestHelpers.AssertDriverContentsAre (looksLike, _output);
  744. v.Dispose ();
  745. top.Dispose ();
  746. bottom.Dispose ();
  747. }
  748. [Fact]
  749. [TestRespondersDisposed]
  750. public void View_With_No_Difference_Between_An_Object_Initializer_Compute_And_A_Absolute ()
  751. {
  752. // Object Initializer Computed
  753. var view = new View { X = 1, Y = 2, Width = 3, Height = 4 };
  754. // Object Initializer Absolute
  755. var super = new View { Frame = new Rectangle (0, 0, 10, 10) };
  756. super.Add (view);
  757. super.BeginInit ();
  758. super.EndInit ();
  759. super.LayoutSubviews ();
  760. Assert.Equal (1, view.X);
  761. Assert.Equal (2, view.Y);
  762. Assert.Equal (3, view.Width);
  763. Assert.Equal (4, view.Height);
  764. Assert.False (view.Frame.IsEmpty);
  765. Assert.Equal (new Rectangle (1, 2, 3, 4), view.Frame);
  766. Assert.False (view.Bounds.IsEmpty);
  767. Assert.Equal (new Rectangle (0, 0, 3, 4), view.Bounds);
  768. view.LayoutSubviews ();
  769. Assert.Equal (1, view.X);
  770. Assert.Equal (2, view.Y);
  771. Assert.Equal (3, view.Width);
  772. Assert.Equal (4, view.Height);
  773. Assert.False (view.Frame.IsEmpty);
  774. Assert.False (view.Bounds.IsEmpty);
  775. super.Dispose ();
  776. #if DEBUG_IDISPOSABLE
  777. Assert.Empty (Responder.Instances);
  778. #endif
  779. // Default Constructor
  780. view = new View ();
  781. Assert.Equal (0, view.X);
  782. Assert.Equal (0, view.Y);
  783. Assert.Equal (0, view.Width);
  784. Assert.Equal (0, view.Height);
  785. Assert.True (view.Frame.IsEmpty);
  786. Assert.True (view.Bounds.IsEmpty);
  787. view.Dispose ();
  788. // Object Initializer
  789. view = new View { X = 1, Y = 2, Text = "" };
  790. Assert.Equal (1, view.X);
  791. Assert.Equal (2, view.Y);
  792. Assert.Equal (0, view.Width);
  793. Assert.Equal (0, view.Height);
  794. Assert.False (view.Frame.IsEmpty);
  795. Assert.True (view.Bounds.IsEmpty);
  796. view.Dispose ();
  797. // Default Constructor and post assignment equivalent to Object Initializer
  798. view = new View ();
  799. view.X = 1;
  800. view.Y = 2;
  801. view.Width = 3;
  802. view.Height = 4;
  803. super = new View { Frame = new Rectangle (0, 0, 10, 10) };
  804. super.Add (view);
  805. super.BeginInit ();
  806. super.EndInit ();
  807. super.LayoutSubviews ();
  808. Assert.Equal (1, view.X);
  809. Assert.Equal (2, view.Y);
  810. Assert.Equal (3, view.Width);
  811. Assert.Equal (4, view.Height);
  812. Assert.False (view.Frame.IsEmpty);
  813. Assert.Equal (new Rectangle (1, 2, 3, 4), view.Frame);
  814. Assert.False (view.Bounds.IsEmpty);
  815. Assert.Equal (new Rectangle (0, 0, 3, 4), view.Bounds);
  816. super.Dispose ();
  817. }
  818. [Fact]
  819. [AutoInitShutdown]
  820. public void Visible_Clear_The_View_Output ()
  821. {
  822. var view = new View { Text = "Testing visibility." }; // use View, not Label to avoid AutoSize == true
  823. // BUGBUG: AutoSize is false and size wasn't provided so it's 0,0
  824. Assert.Equal (0, view.Frame.Width);
  825. Assert.Equal (0, view.Height);
  826. var win = new Window ();
  827. win.Add (view);
  828. Toplevel top = Application.Top;
  829. top.Add (win);
  830. RunState rs = Application.Begin (top);
  831. view.AutoSize = true;
  832. Assert.Equal ("Testing visibility.".Length, view.Frame.Width);
  833. Assert.True (view.Visible);
  834. ((FakeDriver)Application.Driver).SetBufferSize (30, 5);
  835. TestHelpers.AssertDriverContentsWithFrameAre (
  836. @"
  837. ┌────────────────────────────┐
  838. │Testing visibility. │
  839. │ │
  840. │ │
  841. └────────────────────────────┘
  842. ",
  843. _output
  844. );
  845. view.Visible = false;
  846. var firstIteration = false;
  847. Application.RunIteration (ref rs, ref firstIteration);
  848. TestHelpers.AssertDriverContentsWithFrameAre (
  849. @"
  850. ┌────────────────────────────┐
  851. │ │
  852. │ │
  853. │ │
  854. └────────────────────────────┘
  855. ",
  856. _output
  857. );
  858. Application.End (rs);
  859. }
  860. [Fact]
  861. [AutoInitShutdown]
  862. public void Visible_Sets_Also_Sets_Subviews ()
  863. {
  864. var button = new Button { Text = "Click Me" };
  865. var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
  866. win.Add (button);
  867. Toplevel top = Application.Top;
  868. top.Add (win);
  869. var iterations = 0;
  870. Application.Iteration += (s, a) =>
  871. {
  872. iterations++;
  873. Assert.True (button.Visible);
  874. Assert.True (button.CanFocus);
  875. Assert.True (button.HasFocus);
  876. Assert.True (win.Visible);
  877. Assert.True (win.CanFocus);
  878. Assert.True (win.HasFocus);
  879. Assert.True (RunesCount () > 0);
  880. win.Visible = false;
  881. Assert.True (button.Visible);
  882. Assert.True (button.CanFocus);
  883. Assert.False (button.HasFocus);
  884. Assert.False (win.Visible);
  885. Assert.True (win.CanFocus);
  886. Assert.False (win.HasFocus);
  887. button.SetFocus ();
  888. Assert.False (button.HasFocus);
  889. Assert.False (win.HasFocus);
  890. win.SetFocus ();
  891. Assert.False (button.HasFocus);
  892. Assert.False (win.HasFocus);
  893. top.Draw ();
  894. Assert.True (RunesCount () == 0);
  895. win.Visible = true;
  896. win.FocusFirst ();
  897. Assert.True (button.HasFocus);
  898. Assert.True (win.HasFocus);
  899. top.Draw ();
  900. Assert.True (RunesCount () > 0);
  901. Application.RequestStop ();
  902. };
  903. Application.Run ();
  904. Assert.Equal (1, iterations);
  905. int RunesCount ()
  906. {
  907. Cell [,] contents = ((FakeDriver)Application.Driver).Contents;
  908. var runesCount = 0;
  909. for (var i = 0; i < Application.Driver.Rows; i++)
  910. {
  911. for (var j = 0; j < Application.Driver.Cols; j++)
  912. {
  913. if (contents [i, j].Rune != (Rune)' ')
  914. {
  915. runesCount++;
  916. }
  917. }
  918. }
  919. return runesCount;
  920. }
  921. }
  922. public class DerivedView : View
  923. {
  924. public DerivedView () { CanFocus = true; }
  925. public bool IsKeyDown { get; set; }
  926. public bool IsKeyPress { get; set; }
  927. public bool IsKeyUp { get; set; }
  928. public override string Text { get; set; }
  929. public override void OnDrawContent (Rectangle contentArea)
  930. {
  931. var idx = 0;
  932. // BUGBUG: v2 - this should use Bounds, not Frame
  933. for (var r = 0; r < Frame.Height; r++)
  934. {
  935. for (var c = 0; c < Frame.Width; c++)
  936. {
  937. if (idx < Text.Length)
  938. {
  939. char rune = Text [idx];
  940. if (rune != '\n')
  941. {
  942. AddRune (c, r, (Rune)Text [idx]);
  943. }
  944. idx++;
  945. if (rune == '\n')
  946. {
  947. break;
  948. }
  949. }
  950. }
  951. }
  952. ClearLayoutNeeded ();
  953. ClearNeedsDisplay ();
  954. }
  955. public override bool OnKeyDown (Key keyEvent)
  956. {
  957. IsKeyDown = true;
  958. return true;
  959. }
  960. public override bool OnKeyUp (Key keyEvent)
  961. {
  962. IsKeyUp = true;
  963. return true;
  964. }
  965. public override bool OnProcessKeyDown (Key keyEvent)
  966. {
  967. IsKeyPress = true;
  968. return true;
  969. }
  970. }
  971. // OnAccept/Accept tests
  972. [Fact]
  973. public void OnAccept_Fires_Accept ()
  974. {
  975. var view = new View ();
  976. var accepted = false;
  977. view.Accept += ViewOnAccept;
  978. view.OnAccept ();
  979. Assert.True (accepted);
  980. return;
  981. void ViewOnAccept (object sender, CancelEventArgs e) { accepted = true; }
  982. }
  983. [Fact]
  984. public void Accept_Cancel_Event_OnAccept_Returns_True ()
  985. {
  986. var view = new View ();
  987. var acceptInvoked = false;
  988. view.Accept += ViewOnAccept;
  989. var ret = view.OnAccept ();
  990. Assert.True (ret);
  991. Assert.True (acceptInvoked);
  992. return;
  993. void ViewOnAccept (object sender, CancelEventArgs e) {
  994. acceptInvoked = true;
  995. e.Cancel = true;
  996. }
  997. }
  998. [Fact]
  999. public void Accept_Command_Invokes_Accept_Event ()
  1000. {
  1001. var view = new View ();
  1002. var accepted = false;
  1003. view.Accept += ViewOnAccept;
  1004. view.InvokeCommand (Command.Accept);
  1005. Assert.True (accepted);
  1006. return;
  1007. void ViewOnAccept (object sender, CancelEventArgs e) { accepted = true; }
  1008. }
  1009. [Fact]
  1010. public void HotKey_Command_SetsFocus ()
  1011. {
  1012. var view = new View ();
  1013. view.CanFocus = true;
  1014. Assert.False (view.HasFocus);
  1015. view.InvokeCommand (Command.HotKey);
  1016. Assert.True (view.HasFocus);
  1017. }
  1018. }