RuneCellTests.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. using System.Text;
  2. using Xunit.Abstractions;
  3. namespace Terminal.Gui.ViewsTests;
  4. public class RuneCellTests
  5. {
  6. private readonly ITestOutputHelper _output;
  7. public RuneCellTests (ITestOutputHelper output) { _output = output; }
  8. [Fact]
  9. public void Constructor_Defaults ()
  10. {
  11. var rc = new RuneCell ();
  12. Assert.NotNull (rc);
  13. Assert.Equal (0, rc.Rune.Value);
  14. Assert.Null (rc.ColorScheme);
  15. }
  16. [Fact]
  17. public void Equals_False ()
  18. {
  19. var rc1 = new RuneCell ();
  20. var rc2 = new RuneCell
  21. {
  22. Rune = new Rune ('a'), ColorScheme = new ColorScheme { Normal = new Attribute (Color.Red) }
  23. };
  24. Assert.False (rc1.Equals (rc2));
  25. Assert.False (rc2.Equals (rc1));
  26. rc1.Rune = new Rune ('a');
  27. rc1.ColorScheme = new ColorScheme ();
  28. Assert.Equal (rc1.Rune, rc2.Rune);
  29. Assert.False (rc1.Equals (rc2));
  30. Assert.False (rc2.Equals (rc1));
  31. }
  32. [Fact]
  33. public void Equals_True ()
  34. {
  35. var rc1 = new RuneCell ();
  36. var rc2 = new RuneCell ();
  37. Assert.True (rc1.Equals (rc2));
  38. Assert.True (rc2.Equals (rc1));
  39. rc1.Rune = new Rune ('a');
  40. rc1.ColorScheme = new ColorScheme ();
  41. rc2.Rune = new Rune ('a');
  42. rc2.ColorScheme = new ColorScheme ();
  43. Assert.True (rc1.Equals (rc2));
  44. Assert.True (rc2.Equals (rc1));
  45. }
  46. [Fact]
  47. [AutoInitShutdown]
  48. public void RuneCell_LoadRuneCells_InheritsPreviousColorScheme ()
  49. {
  50. List<RuneCell> runeCells = new ();
  51. foreach (KeyValuePair<string, ColorScheme> color in Colors.ColorSchemes)
  52. {
  53. string csName = color.Key;
  54. foreach (Rune rune in csName.EnumerateRunes ())
  55. {
  56. runeCells.Add (new RuneCell { Rune = rune, ColorScheme = color.Value });
  57. }
  58. runeCells.Add (new RuneCell { Rune = (Rune)'\n', ColorScheme = color.Value });
  59. }
  60. TextView tv = CreateTextView ();
  61. tv.Load (runeCells);
  62. var top = new Toplevel ();
  63. top.Add (tv);
  64. RunState rs = Application.Begin (top);
  65. Assert.True (tv.InheritsPreviousColorScheme);
  66. var expectedText = @"
  67. TopLevel
  68. Base
  69. Dialog
  70. Menu
  71. Error ";
  72. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  73. Attribute [] attributes =
  74. {
  75. // 0
  76. Colors.ColorSchemes ["TopLevel"].Focus,
  77. // 1
  78. Colors.ColorSchemes ["Base"].Focus,
  79. // 2
  80. Colors.ColorSchemes ["Dialog"].Focus,
  81. // 3
  82. Colors.ColorSchemes ["Menu"].Focus,
  83. // 4
  84. Colors.ColorSchemes ["Error"].Focus
  85. };
  86. var expectedColor = @"
  87. 0000000000
  88. 1111000000
  89. 2222220000
  90. 3333000000
  91. 4444400000";
  92. TestHelpers.AssertDriverAttributesAre (expectedColor, Application.Driver, attributes);
  93. tv.WordWrap = true;
  94. Application.Refresh ();
  95. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  96. TestHelpers.AssertDriverAttributesAre (expectedColor, Application.Driver, attributes);
  97. tv.CursorPosition = new Point (6, 2);
  98. tv.SelectionStartColumn = 0;
  99. tv.SelectionStartRow = 0;
  100. Assert.Equal ($"TopLevel{Environment.NewLine}Base{Environment.NewLine}Dialog", tv.SelectedText);
  101. tv.Copy ();
  102. tv.Selecting = false;
  103. tv.CursorPosition = new Point (2, 4);
  104. tv.Paste ();
  105. Application.Refresh ();
  106. expectedText = @"
  107. TopLevel
  108. Base
  109. Dialog
  110. Menu
  111. ErTopLevel
  112. Base
  113. Dialogror ";
  114. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  115. expectedColor = @"
  116. 0000000000
  117. 1111000000
  118. 2222220000
  119. 3333000000
  120. 4444444444
  121. 4444000000
  122. 4444444440";
  123. TestHelpers.AssertDriverAttributesAre (expectedColor, Application.Driver, attributes);
  124. tv.Undo ();
  125. tv.CursorPosition = new Point (0, 3);
  126. tv.SelectionStartColumn = 0;
  127. tv.SelectionStartRow = 0;
  128. Assert.Equal (
  129. $"TopLevel{Environment.NewLine}Base{Environment.NewLine}Dialog{Environment.NewLine}",
  130. tv.SelectedText
  131. );
  132. tv.Copy ();
  133. tv.Selecting = false;
  134. tv.CursorPosition = new Point (2, 4);
  135. tv.Paste ();
  136. Application.Refresh ();
  137. expectedText = @"
  138. TopLevel
  139. Base
  140. Dialog
  141. Menu
  142. ErTopLevel
  143. Base
  144. Dialog
  145. ror ";
  146. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  147. expectedColor = @"
  148. 0000000000
  149. 1111000000
  150. 2222220000
  151. 3333000000
  152. 4444444444
  153. 4444000000
  154. 4444440000
  155. 4440000000";
  156. TestHelpers.AssertDriverAttributesAre (expectedColor, Application.Driver, attributes);
  157. Application.End (rs);
  158. }
  159. [Fact]
  160. [AutoInitShutdown]
  161. public void RuneCell_LoadRuneCells_Without_ColorScheme_Is_Never_Null ()
  162. {
  163. List<RuneCell> cells = new ()
  164. {
  165. new RuneCell { Rune = new Rune ('T') },
  166. new RuneCell { Rune = new Rune ('e') },
  167. new RuneCell { Rune = new Rune ('s') },
  168. new RuneCell { Rune = new Rune ('t') }
  169. };
  170. TextView tv = CreateTextView ();
  171. var top = new Toplevel ();
  172. top.Add (tv);
  173. tv.Load (cells);
  174. for (var i = 0; i < tv.Lines; i++)
  175. {
  176. List<RuneCell> line = tv.GetLine (i);
  177. foreach (RuneCell rc in line)
  178. {
  179. Assert.NotNull (rc.ColorScheme);
  180. }
  181. }
  182. }
  183. [Fact]
  184. [AutoInitShutdown]
  185. public void RuneCellEventArgs_WordWrap_True ()
  186. {
  187. var eventCount = 0;
  188. List<List<RuneCell>> text = new ()
  189. {
  190. TextModel.ToRuneCells (
  191. "This is the first line.".ToRunes ()
  192. ),
  193. TextModel.ToRuneCells (
  194. "This is the second line.".ToRunes ()
  195. )
  196. };
  197. TextView tv = CreateTextView ();
  198. tv.DrawNormalColor += _textView_DrawColor;
  199. tv.DrawReadOnlyColor += _textView_DrawColor;
  200. tv.DrawSelectionColor += _textView_DrawColor;
  201. tv.DrawUsedColor += _textView_DrawColor;
  202. void _textView_DrawColor (object sender, RuneCellEventArgs e)
  203. {
  204. Assert.Equal (e.Line [e.Col], text [e.UnwrappedPosition.Row] [e.UnwrappedPosition.Col]);
  205. eventCount++;
  206. }
  207. tv.Text = $"{TextModel.ToString (text [0])}\n{TextModel.ToString (text [1])}\n";
  208. Assert.False (tv.WordWrap);
  209. var top = new Toplevel ();
  210. top.Add (tv);
  211. Application.Begin (top);
  212. TestHelpers.AssertDriverContentsWithFrameAre (
  213. @"
  214. This is the first line.
  215. This is the second line.",
  216. _output
  217. );
  218. tv.Width = 10;
  219. tv.Height = 25;
  220. tv.WordWrap = true;
  221. Application.Refresh ();
  222. TestHelpers.AssertDriverContentsWithFrameAre (
  223. @"
  224. This is
  225. the
  226. first
  227. line.
  228. This is
  229. the
  230. second
  231. line. ",
  232. _output
  233. );
  234. Assert.Equal (eventCount, (text [0].Count + text [1].Count) * 2);
  235. }
  236. [Fact]
  237. public void ToString_Override ()
  238. {
  239. var rc1 = new RuneCell ();
  240. var rc2 = new RuneCell
  241. {
  242. Rune = new Rune ('a'), ColorScheme = new ColorScheme { Normal = new Attribute (Color.Red) }
  243. };
  244. Assert.Equal ("U+0000 '\0'; null", rc1.ToString ());
  245. Assert.Equal (
  246. "U+0061 'a'; Normal: [Red,Red]; Focus: [White,Black]; HotNormal: [White,Black]; HotFocus: [White,Black]; Disabled: [White,Black]",
  247. rc2.ToString ()
  248. );
  249. }
  250. // TODO: Move the tests below to View or Color - they test ColorScheme, not RuneCell primitives.
  251. private TextView CreateTextView () { return new TextView { Width = 30, Height = 10 }; }
  252. }