TreeTableSourceTests.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. using System.Text;
  2. using Xunit.Abstractions;
  3. namespace Terminal.Gui.ViewsTests;
  4. public class TreeTableSourceTests : IDisposable
  5. {
  6. private readonly Rune _origChecked;
  7. private readonly Rune _origUnchecked;
  8. private readonly ITestOutputHelper _output;
  9. public TreeTableSourceTests (ITestOutputHelper output)
  10. {
  11. _output = output;
  12. _origChecked = ConfigurationManager.Glyphs.Checked;
  13. _origUnchecked = ConfigurationManager.Glyphs.UnChecked;
  14. ConfigurationManager.Glyphs.Checked = new Rune ('☑');
  15. ConfigurationManager.Glyphs.UnChecked = new Rune ('☐');
  16. }
  17. public void Dispose ()
  18. {
  19. ConfigurationManager.Glyphs.Checked = _origChecked;
  20. ConfigurationManager.Glyphs.UnChecked = _origUnchecked;
  21. }
  22. [Fact]
  23. [AutoInitShutdown]
  24. public void TestTreeTableSource_BasicExpanding_WithKeyboard ()
  25. {
  26. TableView tv = GetTreeTable (out _);
  27. tv.Style.GetOrCreateColumnStyle (1).MinAcceptableWidth = 1;
  28. tv.Draw ();
  29. var expected =
  30. @"
  31. │Name │Description │
  32. ├──────────────┼───────────────────────┤
  33. │├+Lost Highway│Exciting night road │
  34. │└+Route 66 │Great race course │";
  35. TestHelpers.AssertDriverContentsAre (expected, _output);
  36. Assert.Equal (2, tv.Table.Rows);
  37. // top left is selected cell
  38. Assert.Equal (0, tv.SelectedRow);
  39. Assert.Equal (0, tv.SelectedColumn);
  40. // when pressing right we should expand the top route
  41. tv.NewKeyDownEvent (Key.CursorRight);
  42. tv.Draw ();
  43. expected =
  44. @"
  45. │Name │Description │
  46. ├─────────────────┼────────────────────┤
  47. │├-Lost Highway │Exciting night road │
  48. ││ ├─Ford Trans-Am│Talking thunderbird │
  49. ││ └─DeLorean │Time travelling car │
  50. │└+Route 66 │Great race course │
  51. ";
  52. TestHelpers.AssertDriverContentsAre (expected, _output);
  53. // when pressing left we should collapse the top route again
  54. tv.NewKeyDownEvent (Key.CursorLeft);
  55. tv.Draw ();
  56. expected =
  57. @"
  58. │Name │Description │
  59. ├──────────────┼───────────────────────┤
  60. │├+Lost Highway│Exciting night road │
  61. │└+Route 66 │Great race course │
  62. ";
  63. TestHelpers.AssertDriverContentsAre (expected, _output);
  64. }
  65. [Fact]
  66. [AutoInitShutdown]
  67. public void TestTreeTableSource_BasicExpanding_WithMouse ()
  68. {
  69. TableView tv = GetTreeTable (out _);
  70. tv.Style.GetOrCreateColumnStyle (1).MinAcceptableWidth = 1;
  71. tv.Draw ();
  72. var expected =
  73. @"
  74. │Name │Description │
  75. ├──────────────┼───────────────────────┤
  76. │├+Lost Highway│Exciting night road │
  77. │└+Route 66 │Great race course │";
  78. TestHelpers.AssertDriverContentsAre (expected, _output);
  79. Assert.Equal (2, tv.Table.Rows);
  80. // top left is selected cell
  81. Assert.Equal (0, tv.SelectedRow);
  82. Assert.Equal (0, tv.SelectedColumn);
  83. Assert.True (tv.OnMouseEvent (new MouseEvent { X = 2, Y = 2, Flags = MouseFlags.Button1Clicked }));
  84. tv.Draw ();
  85. expected =
  86. @"
  87. │Name │Description │
  88. ├─────────────────┼────────────────────┤
  89. │├-Lost Highway │Exciting night road │
  90. ││ ├─Ford Trans-Am│Talking thunderbird │
  91. ││ └─DeLorean │Time travelling car │
  92. │└+Route 66 │Great race course │
  93. ";
  94. TestHelpers.AssertDriverContentsAre (expected, _output);
  95. // Clicking to the right/left of the expand/collapse does nothing
  96. tv.OnMouseEvent (new MouseEvent { X = 3, Y = 2, Flags = MouseFlags.Button1Clicked });
  97. tv.Draw ();
  98. TestHelpers.AssertDriverContentsAre (expected, _output);
  99. tv.OnMouseEvent (new MouseEvent { X = 1, Y = 2, Flags = MouseFlags.Button1Clicked });
  100. tv.Draw ();
  101. TestHelpers.AssertDriverContentsAre (expected, _output);
  102. // Clicking on the + again should collapse
  103. tv.OnMouseEvent (new MouseEvent { X = 2, Y = 2, Flags = MouseFlags.Button1Clicked });
  104. tv.Draw ();
  105. expected =
  106. @"
  107. │Name │Description │
  108. ├──────────────┼───────────────────────┤
  109. │├+Lost Highway│Exciting night road │
  110. │└+Route 66 │Great race course │";
  111. TestHelpers.AssertDriverContentsAre (expected, _output);
  112. }
  113. [Fact]
  114. [AutoInitShutdown]
  115. public void TestTreeTableSource_CombinedWithCheckboxes ()
  116. {
  117. TableView tv = GetTreeTable (out TreeView<IDescribedThing> treeSource);
  118. CheckBoxTableSourceWrapperByIndex checkSource;
  119. tv.Table = checkSource = new CheckBoxTableSourceWrapperByIndex (tv, tv.Table);
  120. tv.Style.GetOrCreateColumnStyle (2).MinAcceptableWidth = 1;
  121. tv.Draw ();
  122. var expected =
  123. @"
  124. │ │Name │Description │
  125. ├─┼──────────────┼─────────────────────┤
  126. │☐│├+Lost Highway│Exciting night road │
  127. │☐│└+Route 66 │Great race course │
  128. ";
  129. TestHelpers.AssertDriverContentsAre (expected, _output);
  130. Assert.Equal (2, tv.Table.Rows);
  131. // top left is selected cell
  132. Assert.Equal (0, tv.SelectedRow);
  133. Assert.Equal (0, tv.SelectedColumn);
  134. // when pressing right we move to tree column
  135. tv.NewKeyDownEvent (Key.CursorRight);
  136. // now we are in tree column
  137. Assert.Equal (0, tv.SelectedRow);
  138. Assert.Equal (1, tv.SelectedColumn);
  139. Application.Top.NewKeyDownEvent (Key.CursorRight);
  140. tv.Draw ();
  141. expected =
  142. @"
  143. │ │Name │Description │
  144. ├─┼─────────────────┼──────────────────┤
  145. │☐│├-Lost Highway │Exciting night roa│
  146. │☐││ ├─Ford Trans-Am│Talking thunderbir│
  147. │☐││ └─DeLorean │Time travelling ca│
  148. │☐│└+Route 66 │Great race course │
  149. ";
  150. TestHelpers.AssertDriverContentsAre (expected, _output);
  151. tv.NewKeyDownEvent (Key.CursorDown);
  152. tv.NewKeyDownEvent (Key.Space);
  153. tv.Draw ();
  154. expected =
  155. @"
  156. │ │Name │Description │
  157. ├─┼─────────────────┼──────────────────┤
  158. │☐│├-Lost Highway │Exciting night roa│
  159. │☑││ ├─Ford Trans-Am│Talking thunderbir│
  160. │☐││ └─DeLorean │Time travelling ca│
  161. │☐│└+Route 66 │Great race course │
  162. ";
  163. TestHelpers.AssertDriverContentsAre (expected, _output);
  164. IDescribedThing [] selectedObjects = checkSource.CheckedRows.Select (treeSource.GetObjectOnRow).ToArray ();
  165. IDescribedThing selected = Assert.Single (selectedObjects);
  166. Assert.Equal ("Ford Trans-Am", selected.Name);
  167. Assert.Equal ("Talking thunderbird car", selected.Description);
  168. }
  169. private TableView GetTreeTable (out TreeView<IDescribedThing> tree)
  170. {
  171. var tableView = new TableView ();
  172. tableView.ColorScheme = Colors.ColorSchemes ["TopLevel"];
  173. tableView.ColorScheme = Colors.ColorSchemes ["TopLevel"];
  174. tableView.Viewport = new Rectangle (0, 0, 40, 6);
  175. tableView.Style.ShowHorizontalHeaderUnderline = true;
  176. tableView.Style.ShowHorizontalHeaderOverline = false;
  177. tableView.Style.AlwaysShowHeaders = true;
  178. tableView.Style.SmoothHorizontalScrolling = true;
  179. tree = new TreeView<IDescribedThing> ();
  180. tree.AspectGetter = d => d.Name;
  181. tree.TreeBuilder = new DelegateTreeBuilder<IDescribedThing> (
  182. d => d is Road r
  183. ? r.Traffic
  184. : Enumerable.Empty<IDescribedThing> ()
  185. );
  186. tree.AddObject (
  187. new Road
  188. {
  189. Name = "Lost Highway",
  190. Description = "Exciting night road",
  191. Traffic = new List<Car>
  192. {
  193. new () { Name = "Ford Trans-Am", Description = "Talking thunderbird car" },
  194. new () { Name = "DeLorean", Description = "Time travelling car" }
  195. }
  196. }
  197. );
  198. tree.AddObject (
  199. new Road
  200. {
  201. Name = "Route 66",
  202. Description = "Great race course",
  203. Traffic = new List<Car>
  204. {
  205. new () { Name = "Pink Compact", Description = "Penelope Pitstop's car" },
  206. new () { Name = "Mean Machine", Description = "Dick Dastardly's car" }
  207. }
  208. }
  209. );
  210. tableView.Table = new TreeTableSource<IDescribedThing> (
  211. tableView,
  212. "Name",
  213. tree,
  214. new Dictionary<string, Func<IDescribedThing, object>> { { "Description", d => d.Description } }
  215. );
  216. tableView.BeginInit ();
  217. tableView.EndInit ();
  218. tableView.LayoutSubviews ();
  219. Application.Top.Add (tableView);
  220. Application.Top.EnsureFocus ();
  221. Assert.Equal (tableView, Application.Top.MostFocused);
  222. return tableView;
  223. }
  224. private class Car : IDescribedThing
  225. {
  226. public string Name { get; set; }
  227. public string Description { get; set; }
  228. }
  229. private interface IDescribedThing
  230. {
  231. string Description { get; }
  232. string Name { get; }
  233. }
  234. private class Road : IDescribedThing
  235. {
  236. public List<Car> Traffic { get; set; }
  237. public string Name { get; set; }
  238. public string Description { get; set; }
  239. }
  240. }