RuneCellTests.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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. Application.Top.Add (tv);
  63. RunState rs = Application.Begin (Application.Top);
  64. Assert.True (tv.InheritsPreviousColorScheme);
  65. var expectedText = @"
  66. TopLevel
  67. Base
  68. Dialog
  69. Menu
  70. Error ";
  71. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  72. Attribute [] attributes =
  73. {
  74. // 0
  75. Colors.ColorSchemes ["TopLevel"].Focus,
  76. // 1
  77. Colors.ColorSchemes ["Base"].Focus,
  78. // 2
  79. Colors.ColorSchemes ["Dialog"].Focus,
  80. // 3
  81. Colors.ColorSchemes ["Menu"].Focus,
  82. // 4
  83. Colors.ColorSchemes ["Error"].Focus
  84. };
  85. var expectedColor = @"
  86. 0000000000
  87. 1111000000
  88. 2222220000
  89. 3333000000
  90. 4444400000";
  91. TestHelpers.AssertDriverAttributesAre (expectedColor, Application.Driver, attributes);
  92. tv.WordWrap = true;
  93. Application.Refresh ();
  94. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  95. TestHelpers.AssertDriverAttributesAre (expectedColor, Application.Driver, attributes);
  96. tv.CursorPosition = new Point (6, 2);
  97. tv.SelectionStartColumn = 0;
  98. tv.SelectionStartRow = 0;
  99. Assert.Equal ($"TopLevel{Environment.NewLine}Base{Environment.NewLine}Dialog", tv.SelectedText);
  100. tv.Copy ();
  101. tv.Selecting = false;
  102. tv.CursorPosition = new Point (2, 4);
  103. tv.Paste ();
  104. Application.Refresh ();
  105. expectedText = @"
  106. TopLevel
  107. Base
  108. Dialog
  109. Menu
  110. ErTopLevel
  111. Base
  112. Dialogror ";
  113. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  114. expectedColor = @"
  115. 0000000000
  116. 1111000000
  117. 2222220000
  118. 3333000000
  119. 4444444444
  120. 4444000000
  121. 4444444440";
  122. TestHelpers.AssertDriverAttributesAre (expectedColor, Application.Driver, attributes);
  123. tv.Undo ();
  124. tv.CursorPosition = new Point (0, 3);
  125. tv.SelectionStartColumn = 0;
  126. tv.SelectionStartRow = 0;
  127. Assert.Equal (
  128. $"TopLevel{Environment.NewLine}Base{Environment.NewLine}Dialog{Environment.NewLine}",
  129. tv.SelectedText
  130. );
  131. tv.Copy ();
  132. tv.Selecting = false;
  133. tv.CursorPosition = new Point (2, 4);
  134. tv.Paste ();
  135. Application.Refresh ();
  136. expectedText = @"
  137. TopLevel
  138. Base
  139. Dialog
  140. Menu
  141. ErTopLevel
  142. Base
  143. Dialog
  144. ror ";
  145. TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output);
  146. expectedColor = @"
  147. 0000000000
  148. 1111000000
  149. 2222220000
  150. 3333000000
  151. 4444444444
  152. 4444000000
  153. 4444440000
  154. 4440000000";
  155. TestHelpers.AssertDriverAttributesAre (expectedColor, Application.Driver, attributes);
  156. Application.End (rs);
  157. }
  158. [Fact]
  159. [AutoInitShutdown]
  160. public void RuneCell_LoadRuneCells_Without_ColorScheme_Is_Never_Null ()
  161. {
  162. List<RuneCell> cells = new ()
  163. {
  164. new RuneCell { Rune = new Rune ('T') },
  165. new RuneCell { Rune = new Rune ('e') },
  166. new RuneCell { Rune = new Rune ('s') },
  167. new RuneCell { Rune = new Rune ('t') }
  168. };
  169. TextView tv = CreateTextView ();
  170. Application.Top.Add (tv);
  171. tv.Load (cells);
  172. for (var i = 0; i < tv.Lines; i++)
  173. {
  174. List<RuneCell> line = tv.GetLine (i);
  175. foreach (RuneCell rc in line)
  176. {
  177. Assert.NotNull (rc.ColorScheme);
  178. }
  179. }
  180. }
  181. [Fact]
  182. [AutoInitShutdown]
  183. public void RuneCellEventArgs_WordWrap_True ()
  184. {
  185. var eventCount = 0;
  186. List<List<RuneCell>> text = new ()
  187. {
  188. TextModel.ToRuneCells (
  189. "This is the first line.".ToRunes ()
  190. ),
  191. TextModel.ToRuneCells (
  192. "This is the second line.".ToRunes ()
  193. )
  194. };
  195. TextView tv = CreateTextView ();
  196. tv.DrawNormalColor += _textView_DrawColor;
  197. tv.DrawReadOnlyColor += _textView_DrawColor;
  198. tv.DrawSelectionColor += _textView_DrawColor;
  199. tv.DrawUsedColor += _textView_DrawColor;
  200. void _textView_DrawColor (object sender, RuneCellEventArgs e)
  201. {
  202. Assert.Equal (e.Line [e.Col], text [e.UnwrappedPosition.Row] [e.UnwrappedPosition.Col]);
  203. eventCount++;
  204. }
  205. tv.Text = $"{TextModel.ToString (text [0])}\n{TextModel.ToString (text [1])}\n";
  206. Assert.False (tv.WordWrap);
  207. Application.Top.Add (tv);
  208. Application.Begin (Application.Top);
  209. TestHelpers.AssertDriverContentsWithFrameAre (
  210. @"
  211. This is the first line.
  212. This is the second line.",
  213. _output
  214. );
  215. tv.Width = 10;
  216. tv.Height = 25;
  217. tv.WordWrap = true;
  218. Application.Refresh ();
  219. TestHelpers.AssertDriverContentsWithFrameAre (
  220. @"
  221. This is
  222. the
  223. first
  224. line.
  225. This is
  226. the
  227. second
  228. line. ",
  229. _output
  230. );
  231. Assert.Equal (eventCount, (text [0].Count + text [1].Count) * 2);
  232. }
  233. [Fact]
  234. public void ToString_Override ()
  235. {
  236. var rc1 = new RuneCell ();
  237. var rc2 = new RuneCell
  238. {
  239. Rune = new Rune ('a'), ColorScheme = new ColorScheme { Normal = new Attribute (Color.Red) }
  240. };
  241. Assert.Equal ("U+0000 '\0'; null", rc1.ToString ());
  242. Assert.Equal (
  243. "U+0061 'a'; Normal: [Red,Red]; Focus: [White,Black]; HotNormal: [White,Black]; HotFocus: [White,Black]; Disabled: [White,Black]",
  244. rc2.ToString ()
  245. );
  246. }
  247. // TODO: Move the tests below to View or Color - they test ColorScheme, not RuneCell primitives.
  248. private TextView CreateTextView () { return new TextView { Width = 30, Height = 10 }; }
  249. }