TextViewTests.cs 91 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448
  1. #nullable disable
  2. using System.Text;
  3. namespace ViewsTests;
  4. public class TextViewTests
  5. {
  6. [Fact]
  7. public void CloseFile_Throws_If_FilePath_Is_Null ()
  8. {
  9. var tv = new TextView ();
  10. Assert.Throws<ArgumentNullException> (() => tv.CloseFile ());
  11. }
  12. [Fact]
  13. public void ContentsChanged_Event_Fires_ClearHistoryChanges ()
  14. {
  15. var eventcount = 0;
  16. var text = "This is the first line.\nThis is the second line.\nThis is the third line.";
  17. var tv = new TextView { Width = 50, Height = 10, Text = text };
  18. tv.ContentsChanged += (s, e) => { eventcount++; };
  19. Assert.True (tv.NewKeyDownEvent (Key.Enter));
  20. Assert.Equal (
  21. $"{Environment.NewLine}This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  22. tv.Text
  23. );
  24. Assert.Equal (4, tv.Lines);
  25. var expectedEventCount = 1; // for ENTER key
  26. Assert.Equal (expectedEventCount, eventcount);
  27. tv.ClearHistoryChanges ();
  28. expectedEventCount = 2;
  29. Assert.Equal (expectedEventCount, eventcount);
  30. }
  31. [Fact]
  32. public void ContentsChanged_Event_Fires_LoadStream_By_Calling_HistoryText_Clear ()
  33. {
  34. var eventcount = 0;
  35. var tv = new TextView { Width = 50, Height = 10 };
  36. tv.ContentsChanged += (s, e) => { eventcount++; };
  37. var text = "This is the first line.\r\nThis is the second line.\r\n";
  38. tv.Load (new MemoryStream (Encoding.ASCII.GetBytes (text)));
  39. Assert.Equal (
  40. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}",
  41. tv.Text
  42. );
  43. Assert.Equal (1, eventcount);
  44. }
  45. [Fact]
  46. public void ContentsChanged_Event_Fires_On_LoadFile_By_Calling_HistoryText_Clear ()
  47. {
  48. var eventcount = 0;
  49. var tv = new TextView { Width = 50, Height = 10 };
  50. tv.BeginInit ();
  51. tv.EndInit ();
  52. tv.ContentsChanged += (s, e) => { eventcount++; };
  53. var fileName = "textview.txt";
  54. File.WriteAllText (fileName, "This is the first line.\r\nThis is the second line.\r\n");
  55. tv.Load (fileName);
  56. Assert.Equal (1, eventcount);
  57. Assert.Equal (
  58. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}",
  59. tv.Text
  60. );
  61. }
  62. [Fact]
  63. public void GetRegion_StringFromRunes_Environment_NewLine ()
  64. {
  65. var tv = new TextView { Text = $"1{Environment.NewLine}2" };
  66. Assert.Equal ($"1{Environment.NewLine}2", tv.Text);
  67. Assert.Equal ("", tv.SelectedText);
  68. tv.SelectAll ();
  69. Assert.Equal ($"1{Environment.NewLine}2", tv.Text);
  70. Assert.Equal ($"1{Environment.NewLine}2", tv.SelectedText);
  71. }
  72. [Fact]
  73. public void HistoryText_ClearHistoryChanges ()
  74. {
  75. var text = "This is the first line.\nThis is the second line.\nThis is the third line.";
  76. var tv = new TextView { Text = text };
  77. Assert.True (tv.NewKeyDownEvent (Key.Enter));
  78. Assert.Equal (
  79. $"{Environment.NewLine}This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  80. tv.Text
  81. );
  82. Assert.Equal (4, tv.Lines);
  83. Assert.Equal (new (0, 1), tv.CursorPosition);
  84. Assert.True (tv.IsDirty);
  85. Assert.True (tv.HasHistoryChanges);
  86. tv.ClearHistoryChanges ();
  87. Assert.Equal (
  88. $"{Environment.NewLine}This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  89. tv.Text
  90. );
  91. Assert.Equal (4, tv.Lines);
  92. Assert.Equal (new (0, 1), tv.CursorPosition);
  93. Assert.False (tv.IsDirty);
  94. Assert.False (tv.HasHistoryChanges);
  95. }
  96. [Fact]
  97. public void HistoryText_Exceptions ()
  98. {
  99. var ht = new HistoryText ();
  100. foreach (object ls in Enum.GetValues (typeof (TextEditingLineStatus)))
  101. {
  102. if ((TextEditingLineStatus)ls != TextEditingLineStatus.Original)
  103. {
  104. Assert.Throws<ArgumentException> (
  105. () => ht.Add (
  106. new List<List<Cell>> (),
  107. Point.Empty,
  108. (TextEditingLineStatus)ls
  109. )
  110. );
  111. }
  112. }
  113. Assert.Null (Record.Exception (() => ht.Add (new () { new () }, Point.Empty)));
  114. }
  115. [Fact]
  116. public void HistoryText_IsDirty_HasHistoryChanges ()
  117. {
  118. var tv = new TextView ();
  119. Assert.Equal ("", tv.Text);
  120. Assert.Equal (1, tv.Lines);
  121. Assert.Equal (Point.Empty, tv.CursorPosition);
  122. Assert.False (tv.IsDirty);
  123. Assert.False (tv.HasHistoryChanges);
  124. Assert.True (tv.NewKeyDownEvent (Key.D1));
  125. Assert.Equal ("1", tv.Text);
  126. Assert.Equal (1, tv.Lines);
  127. Assert.Equal (new (1, 0), tv.CursorPosition);
  128. Assert.True (tv.IsDirty);
  129. Assert.True (tv.HasHistoryChanges);
  130. Assert.True (tv.NewKeyDownEvent (Key.Enter));
  131. Assert.Equal ($"1{Environment.NewLine}", tv.Text);
  132. Assert.Equal (2, tv.Lines);
  133. Assert.Equal (new (0, 1), tv.CursorPosition);
  134. Assert.True (tv.IsDirty);
  135. Assert.True (tv.HasHistoryChanges);
  136. Assert.True (tv.NewKeyDownEvent (Key.D2));
  137. Assert.Equal ($"1{Environment.NewLine}2", tv.Text);
  138. Assert.Equal (2, tv.Lines);
  139. Assert.Equal (new (1, 1), tv.CursorPosition);
  140. Assert.True (tv.IsDirty);
  141. Assert.True (tv.HasHistoryChanges);
  142. Assert.True (tv.NewKeyDownEvent (Key.Backspace));
  143. Assert.Equal ($"1{Environment.NewLine}", tv.Text);
  144. Assert.Equal (2, tv.Lines);
  145. Assert.Equal (new (0, 1), tv.CursorPosition);
  146. Assert.True (tv.IsDirty);
  147. Assert.True (tv.HasHistoryChanges);
  148. Assert.True (tv.NewKeyDownEvent (Key.Backspace));
  149. Assert.Equal ("1", tv.Text);
  150. Assert.Equal (1, tv.Lines);
  151. Assert.Equal (new (1, 0), tv.CursorPosition);
  152. Assert.True (tv.IsDirty);
  153. Assert.True (tv.HasHistoryChanges);
  154. Assert.True (tv.NewKeyDownEvent (Key.Backspace));
  155. Assert.Equal ("", tv.Text);
  156. Assert.Equal (1, tv.Lines);
  157. Assert.Equal (Point.Empty, tv.CursorPosition);
  158. // IsDirty cannot be based on HasHistoryChanges because HasHistoryChanges is greater than 0
  159. // The only way is comparing from the original text
  160. Assert.False (tv.IsDirty);
  161. // Still true because HasHistoryChanges is greater than 0
  162. Assert.True (tv.HasHistoryChanges);
  163. }
  164. [Fact]
  165. public void HistoryText_Undo_Redo_Changing_On_Middle_Clear_History_Forwards ()
  166. {
  167. var tv = new TextView ();
  168. Assert.True (tv.NewKeyDownEvent (Key.D1));
  169. Assert.Equal ("1", tv.Text);
  170. Assert.Equal (1, tv.Lines);
  171. Assert.Equal (new (1, 0), tv.CursorPosition);
  172. Assert.True (tv.NewKeyDownEvent (Key.D2));
  173. Assert.Equal ("12", tv.Text);
  174. Assert.Equal (1, tv.Lines);
  175. Assert.Equal (new (2, 0), tv.CursorPosition);
  176. Assert.True (tv.NewKeyDownEvent (Key.D3));
  177. Assert.Equal ("123", tv.Text);
  178. Assert.Equal (1, tv.Lines);
  179. Assert.Equal (new (3, 0), tv.CursorPosition);
  180. // Undo
  181. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  182. Assert.Equal ("12", tv.Text);
  183. Assert.Equal (1, tv.Lines);
  184. Assert.Equal (new (2, 0), tv.CursorPosition);
  185. Assert.True (tv.NewKeyDownEvent (Key.D4));
  186. Assert.Equal ("124", tv.Text);
  187. Assert.Equal (1, tv.Lines);
  188. Assert.Equal (new (3, 0), tv.CursorPosition);
  189. // Redo
  190. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  191. Assert.Equal ("124", tv.Text);
  192. Assert.Equal (1, tv.Lines);
  193. Assert.Equal (new (3, 0), tv.CursorPosition);
  194. }
  195. [Fact]
  196. public void HistoryText_Undo_Redo_Disabled_On_WordWrap ()
  197. {
  198. var text = "This is the first line.\nThis is the second line.\nThis is the third line.\n";
  199. var tv = new TextView { Width = 80, Height = 5, Text = text };
  200. Assert.False (tv.WordWrap);
  201. tv.WordWrap = true;
  202. tv.SelectionStartColumn = 12;
  203. tv.CursorPosition = new (12, 2);
  204. Assert.True (tv.NewKeyDownEvent (Key.Enter));
  205. Assert.Equal ($"This is the {Environment.NewLine}third line.{Environment.NewLine}", tv.Text);
  206. Assert.Equal (3, tv.Lines);
  207. Assert.Equal (new (0, 1), tv.CursorPosition);
  208. Assert.True (tv.NewKeyDownEvent (Key.A));
  209. Assert.Equal ($"This is the {Environment.NewLine}athird line.{Environment.NewLine}", tv.Text);
  210. Assert.Equal (3, tv.Lines);
  211. Assert.Equal (new (1, 1), tv.CursorPosition);
  212. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  213. Assert.Equal ($"This is the {Environment.NewLine}third line.{Environment.NewLine}", tv.Text);
  214. Assert.Equal (3, tv.Lines);
  215. Assert.Equal (new (0, 1), tv.CursorPosition);
  216. Assert.True (tv.IsDirty);
  217. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  218. Assert.Equal ($"This is the {Environment.NewLine}athird line.{Environment.NewLine}", tv.Text);
  219. Assert.Equal (3, tv.Lines);
  220. Assert.Equal (new (1, 1), tv.CursorPosition);
  221. }
  222. [Fact]
  223. public void HistoryText_Undo_Redo_Ending_With_Newline_Multi_Line_Selected_Almost_All_Return_And_InsertText ()
  224. {
  225. var text = "This is the first line.\nThis is the second line.\nThis is the third line.\n";
  226. var tv = new TextView { Text = text };
  227. tv.SelectionStartColumn = 12;
  228. tv.CursorPosition = new (12, 2);
  229. Assert.True (tv.NewKeyDownEvent (Key.Enter));
  230. Assert.Equal ($"This is the {Environment.NewLine}third line.{Environment.NewLine}", tv.Text);
  231. Assert.Equal (3, tv.Lines);
  232. Assert.Equal (new (0, 1), tv.CursorPosition);
  233. Assert.True (tv.NewKeyDownEvent (Key.A));
  234. Assert.Equal ($"This is the {Environment.NewLine}athird line.{Environment.NewLine}", tv.Text);
  235. Assert.Equal (3, tv.Lines);
  236. Assert.Equal (new (1, 1), tv.CursorPosition);
  237. // Undo
  238. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  239. Assert.Equal ($"This is the {Environment.NewLine}third line.{Environment.NewLine}", tv.Text);
  240. Assert.Equal (3, tv.Lines);
  241. Assert.Equal (new (0, 1), tv.CursorPosition);
  242. Assert.True (tv.IsDirty);
  243. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  244. Assert.Equal (
  245. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.{Environment.NewLine}",
  246. tv.Text
  247. );
  248. Assert.Equal (4, tv.Lines);
  249. Assert.Equal (new (12, 2), tv.CursorPosition);
  250. Assert.False (tv.IsDirty);
  251. // Redo
  252. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  253. Assert.Equal ($"This is the {Environment.NewLine}third line.{Environment.NewLine}", tv.Text);
  254. Assert.Equal (3, tv.Lines);
  255. Assert.Equal (new (0, 1), tv.CursorPosition);
  256. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  257. Assert.Equal ($"This is the {Environment.NewLine}athird line.{Environment.NewLine}", tv.Text);
  258. Assert.Equal (3, tv.Lines);
  259. Assert.Equal (new (1, 1), tv.CursorPosition);
  260. // Undo
  261. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  262. Assert.Equal ($"This is the {Environment.NewLine}third line.{Environment.NewLine}", tv.Text);
  263. Assert.Equal (3, tv.Lines);
  264. Assert.Equal (new (0, 1), tv.CursorPosition);
  265. Assert.True (tv.IsDirty);
  266. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  267. Assert.Equal (
  268. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.{Environment.NewLine}",
  269. tv.Text
  270. );
  271. Assert.Equal (4, tv.Lines);
  272. Assert.Equal (new (12, 2), tv.CursorPosition);
  273. Assert.False (tv.IsDirty);
  274. // Redo
  275. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  276. Assert.Equal ($"This is the {Environment.NewLine}third line.{Environment.NewLine}", tv.Text);
  277. Assert.Equal (3, tv.Lines);
  278. Assert.Equal (new (0, 1), tv.CursorPosition);
  279. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  280. Assert.Equal ($"This is the {Environment.NewLine}athird line.{Environment.NewLine}", tv.Text);
  281. Assert.Equal (3, tv.Lines);
  282. Assert.Equal (new (1, 1), tv.CursorPosition);
  283. }
  284. [Fact]
  285. public void HistoryText_Undo_Redo_First_Line_Selected_Return_And_InsertText ()
  286. {
  287. var text = "This is the first line.\nThis is the second line.\nThis is the third line.";
  288. var tv = new TextView { Text = text };
  289. tv.SelectionStartColumn = 12;
  290. tv.CursorPosition = new (17, 0);
  291. Assert.True (tv.NewKeyDownEvent (Key.Enter));
  292. Assert.Equal (
  293. $"This is the {Environment.NewLine} line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  294. tv.Text
  295. );
  296. Assert.Equal (4, tv.Lines);
  297. Assert.Equal (new (0, 1), tv.CursorPosition);
  298. Assert.True (tv.NewKeyDownEvent (Key.A));
  299. Assert.Equal (
  300. $"This is the {Environment.NewLine}a line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  301. tv.Text
  302. );
  303. Assert.Equal (4, tv.Lines);
  304. Assert.Equal (new (1, 1), tv.CursorPosition);
  305. // Undo
  306. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  307. Assert.Equal (
  308. $"This is the {Environment.NewLine} line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  309. tv.Text
  310. );
  311. Assert.Equal (4, tv.Lines);
  312. Assert.Equal (new (0, 1), tv.CursorPosition);
  313. Assert.True (tv.IsDirty);
  314. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  315. Assert.Equal (
  316. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  317. tv.Text
  318. );
  319. Assert.Equal (3, tv.Lines);
  320. Assert.Equal (new (17, 0), tv.CursorPosition);
  321. Assert.False (tv.IsDirty);
  322. // Redo
  323. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  324. Assert.Equal (
  325. $"This is the {Environment.NewLine} line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  326. tv.Text
  327. );
  328. Assert.Equal (4, tv.Lines);
  329. Assert.Equal (new (0, 1), tv.CursorPosition);
  330. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  331. Assert.Equal (
  332. $"This is the {Environment.NewLine}a line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  333. tv.Text
  334. );
  335. Assert.Equal (4, tv.Lines);
  336. Assert.Equal (new (1, 1), tv.CursorPosition);
  337. // Undo
  338. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  339. Assert.Equal (
  340. $"This is the {Environment.NewLine} line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  341. tv.Text
  342. );
  343. Assert.Equal (4, tv.Lines);
  344. Assert.Equal (new (0, 1), tv.CursorPosition);
  345. Assert.True (tv.IsDirty);
  346. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  347. Assert.Equal (
  348. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  349. tv.Text
  350. );
  351. Assert.Equal (3, tv.Lines);
  352. Assert.Equal (new (17, 0), tv.CursorPosition);
  353. Assert.False (tv.IsDirty);
  354. // Redo
  355. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  356. Assert.Equal (
  357. $"This is the {Environment.NewLine} line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  358. tv.Text
  359. );
  360. Assert.Equal (4, tv.Lines);
  361. Assert.Equal (new (0, 1), tv.CursorPosition);
  362. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  363. Assert.Equal (
  364. $"This is the {Environment.NewLine}a line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  365. tv.Text
  366. );
  367. Assert.Equal (4, tv.Lines);
  368. Assert.Equal (new (1, 1), tv.CursorPosition);
  369. }
  370. [Fact]
  371. public void HistoryText_Undo_Redo_KillWordBackward ()
  372. {
  373. var text = "First line.\nSecond line.";
  374. var tv = new TextView { Text = text };
  375. Assert.True (tv.NewKeyDownEvent (Key.End.WithCtrl));
  376. Assert.Equal ($"First line.{Environment.NewLine}Second line.", tv.Text);
  377. Assert.Equal ("", tv.SelectedText);
  378. Assert.Equal (2, tv.Lines);
  379. Assert.Equal (new (12, 1), tv.CursorPosition);
  380. Assert.True (tv.NewKeyDownEvent (Key.Backspace.WithCtrl));
  381. Assert.Equal ($"First line.{Environment.NewLine}Second line", tv.Text);
  382. Assert.Equal ("", tv.SelectedText);
  383. Assert.Equal (2, tv.Lines);
  384. Assert.Equal (new (11, 1), tv.CursorPosition);
  385. Assert.True (tv.NewKeyDownEvent (Key.Backspace.WithCtrl));
  386. Assert.Equal ($"First line.{Environment.NewLine}Second ", tv.Text);
  387. Assert.Equal ("", tv.SelectedText);
  388. Assert.Equal (2, tv.Lines);
  389. Assert.Equal (new (7, 1), tv.CursorPosition);
  390. Assert.True (tv.NewKeyDownEvent (Key.Backspace.WithCtrl));
  391. Assert.Equal ($"First line.{Environment.NewLine}", tv.Text);
  392. Assert.Equal ("", tv.SelectedText);
  393. Assert.Equal (2, tv.Lines);
  394. Assert.Equal (new (0, 1), tv.CursorPosition);
  395. Assert.True (tv.NewKeyDownEvent (Key.Backspace.WithCtrl));
  396. Assert.Equal ("First line.", tv.Text);
  397. Assert.Equal ("", tv.SelectedText);
  398. Assert.Equal (1, tv.Lines);
  399. Assert.Equal (new (11, 0), tv.CursorPosition);
  400. Assert.True (tv.NewKeyDownEvent (Key.Backspace.WithCtrl));
  401. Assert.Equal ("First line", tv.Text);
  402. Assert.Equal ("", tv.SelectedText);
  403. Assert.Equal (1, tv.Lines);
  404. Assert.Equal (new (10, 0), tv.CursorPosition);
  405. Assert.True (tv.NewKeyDownEvent (Key.Backspace.WithCtrl));
  406. Assert.Equal ("First ", tv.Text);
  407. Assert.Equal ("", tv.SelectedText);
  408. Assert.Equal (1, tv.Lines);
  409. Assert.Equal (new (6, 0), tv.CursorPosition);
  410. Assert.True (tv.NewKeyDownEvent (Key.Backspace.WithCtrl));
  411. Assert.Equal ("", tv.Text);
  412. Assert.Equal ("", tv.SelectedText);
  413. Assert.Equal (1, tv.Lines);
  414. Assert.Equal (Point.Empty, tv.CursorPosition);
  415. // Undo
  416. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  417. Assert.Equal ("First ", tv.Text);
  418. Assert.Equal (1, tv.Lines);
  419. Assert.Equal (new (6, 0), tv.CursorPosition);
  420. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  421. Assert.Equal ("First line", tv.Text);
  422. Assert.Equal (1, tv.Lines);
  423. Assert.Equal (new (10, 0), tv.CursorPosition);
  424. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  425. Assert.Equal ("First line.", tv.Text);
  426. Assert.Equal (1, tv.Lines);
  427. Assert.Equal (new (11, 0), tv.CursorPosition);
  428. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  429. Assert.Equal ($"First line.{Environment.NewLine}", tv.Text);
  430. Assert.Equal (2, tv.Lines);
  431. Assert.Equal (new (0, 1), tv.CursorPosition);
  432. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  433. Assert.Equal ($"First line.{Environment.NewLine}Second ", tv.Text);
  434. Assert.Equal (2, tv.Lines);
  435. Assert.Equal (new (7, 1), tv.CursorPosition);
  436. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  437. Assert.Equal ($"First line.{Environment.NewLine}Second line", tv.Text);
  438. Assert.Equal (2, tv.Lines);
  439. Assert.Equal (new (11, 1), tv.CursorPosition);
  440. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  441. Assert.Equal ($"First line.{Environment.NewLine}Second line.", tv.Text);
  442. Assert.Equal (2, tv.Lines);
  443. Assert.Equal (new (12, 1), tv.CursorPosition);
  444. // Redo
  445. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  446. Assert.Equal ($"First line.{Environment.NewLine}Second line", tv.Text);
  447. Assert.Equal (2, tv.Lines);
  448. Assert.Equal (new (11, 1), tv.CursorPosition);
  449. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  450. Assert.Equal ($"First line.{Environment.NewLine}Second ", tv.Text);
  451. Assert.Equal (2, tv.Lines);
  452. Assert.Equal (new (7, 1), tv.CursorPosition);
  453. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  454. Assert.Equal ($"First line.{Environment.NewLine}", tv.Text);
  455. Assert.Equal (2, tv.Lines);
  456. Assert.Equal (new (0, 1), tv.CursorPosition);
  457. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  458. Assert.Equal ("First line.", tv.Text);
  459. Assert.Equal (1, tv.Lines);
  460. Assert.Equal (new (11, 0), tv.CursorPosition);
  461. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  462. Assert.Equal ("First line", tv.Text);
  463. Assert.Equal (1, tv.Lines);
  464. Assert.Equal (new (10, 0), tv.CursorPosition);
  465. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  466. Assert.Equal ("First ", tv.Text);
  467. Assert.Equal (1, tv.Lines);
  468. Assert.Equal (new (6, 0), tv.CursorPosition);
  469. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  470. Assert.Equal ("", tv.Text);
  471. Assert.Equal (1, tv.Lines);
  472. Assert.Equal (Point.Empty, tv.CursorPosition);
  473. }
  474. [Fact]
  475. public void HistoryText_Undo_Redo_KillWordForward ()
  476. {
  477. var text = "First line.\nSecond line.";
  478. var tv = new TextView { Text = text };
  479. Assert.True (tv.NewKeyDownEvent (Key.Delete.WithCtrl));
  480. Assert.Equal ($"line.{Environment.NewLine}Second line.", tv.Text);
  481. Assert.Equal ("", tv.SelectedText);
  482. Assert.Equal (2, tv.Lines);
  483. Assert.Equal (Point.Empty, tv.CursorPosition);
  484. Assert.True (tv.NewKeyDownEvent (Key.Delete.WithCtrl));
  485. Assert.Equal ($".{Environment.NewLine}Second line.", tv.Text);
  486. Assert.Equal (2, tv.Lines);
  487. Assert.Equal (Point.Empty, tv.CursorPosition);
  488. Assert.True (tv.NewKeyDownEvent (Key.Delete.WithCtrl));
  489. Assert.Equal ($"{Environment.NewLine}Second line.", tv.Text);
  490. Assert.Equal (2, tv.Lines);
  491. Assert.Equal (Point.Empty, tv.CursorPosition);
  492. Assert.True (tv.NewKeyDownEvent (Key.Delete.WithCtrl));
  493. Assert.Equal ("Second line.", tv.Text);
  494. Assert.Equal (1, tv.Lines);
  495. Assert.Equal (Point.Empty, tv.CursorPosition);
  496. Assert.True (tv.NewKeyDownEvent (Key.Delete.WithCtrl));
  497. Assert.Equal ("line.", tv.Text);
  498. Assert.Equal (1, tv.Lines);
  499. Assert.Equal (Point.Empty, tv.CursorPosition);
  500. Assert.True (tv.NewKeyDownEvent (Key.Delete.WithCtrl));
  501. Assert.Equal (".", tv.Text);
  502. Assert.Equal (1, tv.Lines);
  503. Assert.Equal (Point.Empty, tv.CursorPosition);
  504. Assert.True (tv.NewKeyDownEvent (Key.Delete.WithCtrl));
  505. Assert.Equal ("", tv.Text);
  506. Assert.Equal (1, tv.Lines);
  507. Assert.Equal (Point.Empty, tv.CursorPosition);
  508. // Undo
  509. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  510. Assert.Equal (".", tv.Text);
  511. Assert.Equal (1, tv.Lines);
  512. Assert.Equal (Point.Empty, tv.CursorPosition);
  513. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  514. Assert.Equal ("line.", tv.Text);
  515. Assert.Equal (1, tv.Lines);
  516. Assert.Equal (Point.Empty, tv.CursorPosition);
  517. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  518. Assert.Equal ("Second line.", tv.Text);
  519. Assert.Equal (1, tv.Lines);
  520. Assert.Equal (Point.Empty, tv.CursorPosition);
  521. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  522. Assert.Equal ($"{Environment.NewLine}Second line.", tv.Text);
  523. Assert.Equal (2, tv.Lines);
  524. Assert.Equal (Point.Empty, tv.CursorPosition);
  525. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  526. Assert.Equal ($".{Environment.NewLine}Second line.", tv.Text);
  527. Assert.Equal (2, tv.Lines);
  528. Assert.Equal (Point.Empty, tv.CursorPosition);
  529. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  530. Assert.Equal ($"line.{Environment.NewLine}Second line.", tv.Text);
  531. Assert.Equal (2, tv.Lines);
  532. Assert.Equal (Point.Empty, tv.CursorPosition);
  533. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  534. Assert.Equal ($"First line.{Environment.NewLine}Second line.", tv.Text);
  535. Assert.Equal (2, tv.Lines);
  536. Assert.Equal (Point.Empty, tv.CursorPosition);
  537. // Redo
  538. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  539. Assert.Equal ($"line.{Environment.NewLine}Second line.", tv.Text);
  540. Assert.Equal (2, tv.Lines);
  541. Assert.Equal (Point.Empty, tv.CursorPosition);
  542. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  543. Assert.Equal ($".{Environment.NewLine}Second line.", tv.Text);
  544. Assert.Equal (2, tv.Lines);
  545. Assert.Equal (Point.Empty, tv.CursorPosition);
  546. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  547. Assert.Equal ($"{Environment.NewLine}Second line.", tv.Text);
  548. Assert.Equal (2, tv.Lines);
  549. Assert.Equal (Point.Empty, tv.CursorPosition);
  550. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  551. Assert.Equal ("Second line.", tv.Text);
  552. Assert.Equal (1, tv.Lines);
  553. Assert.Equal (Point.Empty, tv.CursorPosition);
  554. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  555. Assert.Equal ("line.", tv.Text);
  556. Assert.Equal (1, tv.Lines);
  557. Assert.Equal (Point.Empty, tv.CursorPosition);
  558. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  559. Assert.Equal (".", tv.Text);
  560. Assert.Equal (1, tv.Lines);
  561. Assert.Equal (Point.Empty, tv.CursorPosition);
  562. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  563. Assert.Equal ("", tv.Text);
  564. Assert.Equal (1, tv.Lines);
  565. Assert.Equal (Point.Empty, tv.CursorPosition);
  566. }
  567. [Fact]
  568. public void HistoryText_Undo_Redo_Multi_Line_Selected_All_Return_And_InsertText ()
  569. {
  570. var text = "This is the first line.\nThis is the second line.\nThis is the third line.";
  571. var tv = new TextView { Text = text };
  572. Assert.True (tv.NewKeyDownEvent (Key.End.WithCtrl.WithShift));
  573. Assert.Equal (
  574. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  575. tv.Text
  576. );
  577. Assert.Equal (3, tv.Lines);
  578. Assert.Equal (new (23, 2), tv.CursorPosition);
  579. Assert.True (tv.NewKeyDownEvent (Key.Enter));
  580. Assert.Equal ($"{Environment.NewLine}", tv.Text);
  581. Assert.Equal (2, tv.Lines);
  582. Assert.Equal (new (0, 1), tv.CursorPosition);
  583. Assert.True (tv.NewKeyDownEvent (Key.A));
  584. Assert.Equal ($"{Environment.NewLine}a", tv.Text);
  585. Assert.Equal (2, tv.Lines);
  586. Assert.Equal (new (1, 1), tv.CursorPosition);
  587. // Undo
  588. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  589. Assert.Equal ($"{Environment.NewLine}", tv.Text);
  590. Assert.Equal (2, tv.Lines);
  591. Assert.Equal (new (0, 1), tv.CursorPosition);
  592. Assert.True (tv.IsDirty);
  593. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  594. Assert.Equal (
  595. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  596. tv.Text
  597. );
  598. Assert.Equal (3, tv.Lines);
  599. Assert.Equal (new (23, 2), tv.CursorPosition);
  600. Assert.False (tv.IsDirty);
  601. // Redo
  602. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  603. Assert.Equal ($"{Environment.NewLine}", tv.Text);
  604. Assert.Equal (2, tv.Lines);
  605. Assert.Equal (new (0, 1), tv.CursorPosition);
  606. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  607. Assert.Equal ($"{Environment.NewLine}a", tv.Text);
  608. Assert.Equal (2, tv.Lines);
  609. Assert.Equal (new (1, 1), tv.CursorPosition);
  610. // Undo
  611. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  612. Assert.Equal ($"{Environment.NewLine}", tv.Text);
  613. Assert.Equal (2, tv.Lines);
  614. Assert.Equal (new (0, 1), tv.CursorPosition);
  615. Assert.True (tv.IsDirty);
  616. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  617. Assert.Equal (
  618. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  619. tv.Text
  620. );
  621. Assert.Equal (3, tv.Lines);
  622. Assert.Equal (new (23, 2), tv.CursorPosition);
  623. Assert.False (tv.IsDirty);
  624. // Redo
  625. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  626. Assert.Equal ($"{Environment.NewLine}", tv.Text);
  627. Assert.Equal (2, tv.Lines);
  628. Assert.Equal (new (0, 1), tv.CursorPosition);
  629. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  630. Assert.Equal ($"{Environment.NewLine}a", tv.Text);
  631. Assert.Equal (2, tv.Lines);
  632. Assert.Equal (new (1, 1), tv.CursorPosition);
  633. }
  634. [Fact]
  635. public void HistoryText_Undo_Redo_Multi_Line_Selected_DeleteCharLeft_All ()
  636. {
  637. var text = "This is the first line.\nThis is the second line.\nThis is the third line.";
  638. var tv = new TextView { Text = text };
  639. Assert.Equal (
  640. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  641. tv.Text
  642. );
  643. Assert.Equal (3, tv.Lines);
  644. Assert.Equal (Point.Empty, tv.CursorPosition);
  645. Assert.False (tv.IsDirty);
  646. Assert.False (tv.HasHistoryChanges);
  647. Assert.True (tv.NewKeyDownEvent (Key.End.WithCtrl.WithShift));
  648. Assert.Equal (
  649. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  650. tv.Text
  651. );
  652. Assert.Equal (
  653. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  654. tv.SelectedText
  655. );
  656. Assert.Equal (3, tv.Lines);
  657. Assert.Equal (new (23, 2), tv.CursorPosition);
  658. Assert.Equal (70 + Environment.NewLine.Length * 2, tv.SelectedLength);
  659. Assert.False (tv.IsDirty);
  660. Assert.False (tv.HasHistoryChanges);
  661. Assert.True (tv.NewKeyDownEvent (Key.Backspace));
  662. Assert.Equal ("", tv.Text);
  663. Assert.Equal ("", tv.SelectedText);
  664. Assert.Equal (1, tv.Lines);
  665. Assert.Equal (Point.Empty, tv.CursorPosition);
  666. Assert.Equal (0, tv.SelectedLength);
  667. Assert.True (tv.IsDirty);
  668. Assert.True (tv.HasHistoryChanges);
  669. // Undo
  670. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  671. Assert.Equal (
  672. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  673. tv.Text
  674. );
  675. Assert.Equal ("", tv.SelectedText);
  676. Assert.Equal (3, tv.Lines);
  677. Assert.Equal (new (23, 2), tv.CursorPosition);
  678. Assert.Equal (0, tv.SelectedLength);
  679. Assert.False (tv.IsDirty);
  680. Assert.True (tv.HasHistoryChanges);
  681. // Redo
  682. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  683. Assert.Equal ("", tv.Text);
  684. Assert.Equal ("", tv.SelectedText);
  685. Assert.Equal (1, tv.Lines);
  686. Assert.Equal (Point.Empty, tv.CursorPosition);
  687. Assert.Equal (0, tv.SelectedLength);
  688. Assert.True (tv.IsDirty);
  689. Assert.True (tv.HasHistoryChanges);
  690. }
  691. [Fact]
  692. public void HistoryText_Undo_Redo_Multi_Line_Selected_DeleteCharRight_All ()
  693. {
  694. var text = "This is the first line.\nThis is the second line.\nThis is the third line.";
  695. var tv = new TextView { Text = text };
  696. Assert.Equal (
  697. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  698. tv.Text
  699. );
  700. Assert.Equal (3, tv.Lines);
  701. Assert.Equal (Point.Empty, tv.CursorPosition);
  702. Assert.False (tv.IsDirty);
  703. Assert.False (tv.HasHistoryChanges);
  704. Assert.True (tv.NewKeyDownEvent (Key.End.WithCtrl.WithShift));
  705. Assert.Equal (
  706. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  707. tv.Text
  708. );
  709. Assert.Equal (
  710. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  711. tv.SelectedText
  712. );
  713. Assert.Equal (3, tv.Lines);
  714. Assert.Equal (new (23, 2), tv.CursorPosition);
  715. Assert.Equal (70 + Environment.NewLine.Length * 2, tv.SelectedLength);
  716. Assert.False (tv.IsDirty);
  717. Assert.False (tv.HasHistoryChanges);
  718. Assert.True (tv.NewKeyDownEvent (Key.Delete));
  719. Assert.Equal ("", tv.Text);
  720. Assert.Equal ("", tv.SelectedText);
  721. Assert.Equal (1, tv.Lines);
  722. Assert.Equal (Point.Empty, tv.CursorPosition);
  723. Assert.Equal (0, tv.SelectedLength);
  724. Assert.True (tv.IsDirty);
  725. Assert.True (tv.HasHistoryChanges);
  726. // Undo
  727. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  728. Assert.Equal (
  729. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  730. tv.Text
  731. );
  732. Assert.Equal ("", tv.SelectedText);
  733. Assert.Equal (3, tv.Lines);
  734. Assert.Equal (new (23, 2), tv.CursorPosition);
  735. Assert.Equal (0, tv.SelectedLength);
  736. Assert.False (tv.IsDirty);
  737. Assert.True (tv.HasHistoryChanges);
  738. // Redo
  739. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  740. Assert.Equal ("", tv.Text);
  741. Assert.Equal ("", tv.SelectedText);
  742. Assert.Equal (1, tv.Lines);
  743. Assert.Equal (Point.Empty, tv.CursorPosition);
  744. Assert.Equal (0, tv.SelectedLength);
  745. Assert.True (tv.IsDirty);
  746. Assert.True (tv.HasHistoryChanges);
  747. }
  748. [Fact]
  749. public void HistoryText_Undo_Redo_Multiline_Selected_Tab_BackTab ()
  750. {
  751. var text = "First line.\nSecond line.\nThird line.";
  752. var tv = new TextView { Width = 80, Height = 5, Text = text };
  753. tv.SelectionStartColumn = 6;
  754. tv.CursorPosition = new (6, 2);
  755. Assert.True (tv.NewKeyDownEvent (Key.Tab));
  756. Assert.Equal ("First \tline.", tv.Text);
  757. Assert.Equal (1, tv.Lines);
  758. Assert.Equal (new (7, 0), tv.CursorPosition);
  759. Assert.True (tv.NewKeyDownEvent (Key.Tab.WithShift));
  760. Assert.Equal ("First line.", tv.Text);
  761. Assert.Equal (1, tv.Lines);
  762. Assert.Equal (new (6, 0), tv.CursorPosition);
  763. // Undo
  764. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  765. Assert.Equal ("First \tline.", tv.Text);
  766. Assert.Equal (1, tv.Lines);
  767. Assert.Equal (new (7, 0), tv.CursorPosition);
  768. Assert.True (tv.IsDirty);
  769. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  770. Assert.Equal ($"First line.{Environment.NewLine}Second line.{Environment.NewLine}Third line.", tv.Text);
  771. Assert.Equal (3, tv.Lines);
  772. Assert.Equal (new (6, 2), tv.CursorPosition);
  773. Assert.False (tv.IsDirty);
  774. // Redo
  775. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  776. Assert.Equal ("First \tline.", tv.Text);
  777. Assert.Equal (1, tv.Lines);
  778. Assert.Equal (new (7, 0), tv.CursorPosition);
  779. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  780. Assert.Equal ("First line.", tv.Text);
  781. Assert.Equal (1, tv.Lines);
  782. Assert.Equal (new (6, 0), tv.CursorPosition);
  783. }
  784. [Fact]
  785. public void HistoryText_Undo_Redo_Multiline_Simples_Tab_BackTab ()
  786. {
  787. var text = "First line.\nSecond line.\nThird line.";
  788. var tv = new TextView { Width = 80, Height = 5, Text = text };
  789. Assert.True (tv.NewKeyDownEvent (Key.Tab));
  790. Assert.Equal (
  791. $"\tFirst line.{Environment.NewLine}Second line.{Environment.NewLine}Third line.",
  792. tv.Text
  793. );
  794. Assert.Equal (3, tv.Lines);
  795. Assert.Equal (new (1, 0), tv.CursorPosition);
  796. Assert.True (tv.NewKeyDownEvent (Key.Tab.WithShift));
  797. Assert.Equal ($"First line.{Environment.NewLine}Second line.{Environment.NewLine}Third line.", tv.Text);
  798. Assert.Equal (3, tv.Lines);
  799. Assert.Equal (Point.Empty, tv.CursorPosition);
  800. // Undo
  801. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  802. Assert.Equal (
  803. $"\tFirst line.{Environment.NewLine}Second line.{Environment.NewLine}Third line.",
  804. tv.Text
  805. );
  806. Assert.Equal (3, tv.Lines);
  807. Assert.Equal (new (1, 0), tv.CursorPosition);
  808. Assert.True (tv.IsDirty);
  809. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  810. Assert.Equal ($"First line.{Environment.NewLine}Second line.{Environment.NewLine}Third line.", tv.Text);
  811. Assert.Equal (3, tv.Lines);
  812. Assert.Equal (Point.Empty, tv.CursorPosition);
  813. Assert.False (tv.IsDirty);
  814. // Redo
  815. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  816. Assert.Equal (
  817. $"\tFirst line.{Environment.NewLine}Second line.{Environment.NewLine}Third line.",
  818. tv.Text
  819. );
  820. Assert.Equal (3, tv.Lines);
  821. Assert.Equal (new (1, 0), tv.CursorPosition);
  822. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  823. Assert.Equal ($"First line.{Environment.NewLine}Second line.{Environment.NewLine}Third line.", tv.Text);
  824. Assert.Equal (3, tv.Lines);
  825. Assert.Equal (Point.Empty, tv.CursorPosition);
  826. }
  827. [Fact]
  828. public void HistoryText_Undo_Redo_Single_Line_Selected_Return ()
  829. {
  830. var text = "This is the first line.\nThis is the second line.\nThis is the third line.";
  831. var tv = new TextView { Text = text };
  832. tv.SelectionStartColumn = 12;
  833. tv.CursorPosition = new (17, 0);
  834. Assert.True (tv.NewKeyDownEvent (Key.Enter));
  835. Assert.Equal (
  836. $"This is the {Environment.NewLine} line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  837. tv.Text
  838. );
  839. Assert.Equal (4, tv.Lines);
  840. Assert.Equal (new (0, 1), tv.CursorPosition);
  841. // Undo
  842. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  843. Assert.Equal (
  844. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  845. tv.Text
  846. );
  847. Assert.Equal (3, tv.Lines);
  848. Assert.Equal (new (17, 0), tv.CursorPosition);
  849. Assert.False (tv.IsDirty);
  850. // Redo
  851. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  852. Assert.Equal (
  853. $"This is the {Environment.NewLine} line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  854. tv.Text
  855. );
  856. Assert.Equal (4, tv.Lines);
  857. Assert.Equal (new (0, 1), tv.CursorPosition);
  858. // Undo
  859. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  860. Assert.Equal (
  861. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  862. tv.Text
  863. );
  864. Assert.Equal (3, tv.Lines);
  865. Assert.Equal (new (17, 0), tv.CursorPosition);
  866. Assert.False (tv.IsDirty);
  867. // Redo
  868. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  869. Assert.Equal (
  870. $"This is the {Environment.NewLine} line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  871. tv.Text
  872. );
  873. Assert.Equal (4, tv.Lines);
  874. Assert.Equal (new (0, 1), tv.CursorPosition);
  875. }
  876. [Fact]
  877. public void HistoryText_Undo_Redo_Single_Second_Line_Selected_Return ()
  878. {
  879. var text = "This is the first line.\nThis is the second line.\nThis is the third line.";
  880. var tv = new TextView { Text = text };
  881. tv.SelectionStartColumn = 12;
  882. tv.SelectionStartRow = 1;
  883. tv.CursorPosition = new (18, 1);
  884. Assert.True (tv.NewKeyDownEvent (Key.Enter));
  885. Assert.Equal (
  886. $"This is the first line.{Environment.NewLine}This is the {Environment.NewLine} line.{Environment.NewLine}This is the third line.",
  887. tv.Text
  888. );
  889. Assert.Equal (4, tv.Lines);
  890. Assert.Equal (new (0, 2), tv.CursorPosition);
  891. // Undo
  892. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  893. Assert.Equal (
  894. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  895. tv.Text
  896. );
  897. Assert.Equal (3, tv.Lines);
  898. Assert.Equal (new (18, 1), tv.CursorPosition);
  899. Assert.False (tv.IsDirty);
  900. // Redo
  901. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  902. Assert.Equal (
  903. $"This is the first line.{Environment.NewLine}This is the {Environment.NewLine} line.{Environment.NewLine}This is the third line.",
  904. tv.Text
  905. );
  906. Assert.Equal (4, tv.Lines);
  907. Assert.Equal (new (0, 2), tv.CursorPosition);
  908. // Undo
  909. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  910. Assert.Equal (
  911. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  912. tv.Text
  913. );
  914. Assert.Equal (3, tv.Lines);
  915. Assert.Equal (new (18, 1), tv.CursorPosition);
  916. Assert.False (tv.IsDirty);
  917. // Redo
  918. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  919. Assert.Equal (
  920. $"This is the first line.{Environment.NewLine}This is the {Environment.NewLine} line.{Environment.NewLine}This is the third line.",
  921. tv.Text
  922. );
  923. Assert.Equal (4, tv.Lines);
  924. Assert.Equal (new (0, 2), tv.CursorPosition);
  925. }
  926. [Fact]
  927. public void HistoryText_Undo_Redo_Single_Second_Line_Selected_Return_And_InsertText ()
  928. {
  929. var text = "This is the first line.\nThis is the second line.\nThis is the third line.";
  930. var tv = new TextView { Text = text };
  931. tv.SelectionStartColumn = 12;
  932. tv.SelectionStartRow = 1;
  933. tv.CursorPosition = new (18, 1);
  934. Assert.True (tv.NewKeyDownEvent (Key.Enter));
  935. Assert.Equal (
  936. $"This is the first line.{Environment.NewLine}This is the {Environment.NewLine} line.{Environment.NewLine}This is the third line.",
  937. tv.Text
  938. );
  939. Assert.Equal (4, tv.Lines);
  940. Assert.Equal (new (0, 2), tv.CursorPosition);
  941. Assert.True (tv.NewKeyDownEvent (Key.A));
  942. Assert.Equal (
  943. $"This is the first line.{Environment.NewLine}This is the {Environment.NewLine}a line.{Environment.NewLine}This is the third line.",
  944. tv.Text
  945. );
  946. Assert.Equal (4, tv.Lines);
  947. Assert.Equal (new (1, 2), tv.CursorPosition);
  948. // Undo
  949. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  950. Assert.Equal (
  951. $"This is the first line.{Environment.NewLine}This is the {Environment.NewLine} line.{Environment.NewLine}This is the third line.",
  952. tv.Text
  953. );
  954. Assert.Equal (4, tv.Lines);
  955. Assert.Equal (new (0, 2), tv.CursorPosition);
  956. Assert.True (tv.IsDirty);
  957. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  958. Assert.Equal (
  959. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  960. tv.Text
  961. );
  962. Assert.Equal (3, tv.Lines);
  963. Assert.Equal (new (18, 1), tv.CursorPosition);
  964. Assert.False (tv.IsDirty);
  965. // Redo
  966. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  967. Assert.Equal (
  968. $"This is the first line.{Environment.NewLine}This is the {Environment.NewLine} line.{Environment.NewLine}This is the third line.",
  969. tv.Text
  970. );
  971. Assert.Equal (4, tv.Lines);
  972. Assert.Equal (new (0, 2), tv.CursorPosition);
  973. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  974. Assert.Equal (
  975. $"This is the first line.{Environment.NewLine}This is the {Environment.NewLine}a line.{Environment.NewLine}This is the third line.",
  976. tv.Text
  977. );
  978. Assert.Equal (4, tv.Lines);
  979. Assert.Equal (new (1, 2), tv.CursorPosition);
  980. // Undo
  981. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  982. Assert.Equal (
  983. $"This is the first line.{Environment.NewLine}This is the {Environment.NewLine} line.{Environment.NewLine}This is the third line.",
  984. tv.Text
  985. );
  986. Assert.Equal (4, tv.Lines);
  987. Assert.Equal (new (0, 2), tv.CursorPosition);
  988. Assert.True (tv.IsDirty);
  989. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  990. Assert.Equal (
  991. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  992. tv.Text
  993. );
  994. Assert.Equal (3, tv.Lines);
  995. Assert.Equal (new (18, 1), tv.CursorPosition);
  996. Assert.False (tv.IsDirty);
  997. // Redo
  998. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  999. Assert.Equal (
  1000. $"This is the first line.{Environment.NewLine}This is the {Environment.NewLine} line.{Environment.NewLine}This is the third line.",
  1001. tv.Text
  1002. );
  1003. Assert.Equal (4, tv.Lines);
  1004. Assert.Equal (new (0, 2), tv.CursorPosition);
  1005. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  1006. Assert.Equal (
  1007. $"This is the first line.{Environment.NewLine}This is the {Environment.NewLine}a line.{Environment.NewLine}This is the third line.",
  1008. tv.Text
  1009. );
  1010. Assert.Equal (4, tv.Lines);
  1011. Assert.Equal (new (1, 2), tv.CursorPosition);
  1012. }
  1013. [Fact]
  1014. public void HistoryText_Undo_Redo_Three_Line_Selected_Return ()
  1015. {
  1016. var text = "This is the first line.\nThis is the second line.\nThis is the third line.";
  1017. var tv = new TextView { Text = text };
  1018. tv.SelectionStartColumn = 12;
  1019. tv.CursorPosition = new (17, 2);
  1020. Assert.True (tv.NewKeyDownEvent (Key.Enter));
  1021. Assert.Equal ($"This is the {Environment.NewLine} line.", tv.Text);
  1022. Assert.Equal (2, tv.Lines);
  1023. Assert.Equal (new (0, 1), tv.CursorPosition);
  1024. // Undo
  1025. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  1026. Assert.Equal (
  1027. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  1028. tv.Text
  1029. );
  1030. Assert.Equal (3, tv.Lines);
  1031. Assert.Equal (new (17, 2), tv.CursorPosition);
  1032. Assert.False (tv.IsDirty);
  1033. // Redo
  1034. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  1035. Assert.Equal ($"This is the {Environment.NewLine} line.", tv.Text);
  1036. Assert.Equal (2, tv.Lines);
  1037. Assert.Equal (new (0, 1), tv.CursorPosition);
  1038. // Undo
  1039. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  1040. Assert.Equal (
  1041. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  1042. tv.Text
  1043. );
  1044. Assert.Equal (3, tv.Lines);
  1045. Assert.Equal (new (17, 2), tv.CursorPosition);
  1046. Assert.False (tv.IsDirty);
  1047. // Redo
  1048. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  1049. Assert.Equal ($"This is the {Environment.NewLine} line.", tv.Text);
  1050. Assert.Equal (2, tv.Lines);
  1051. Assert.Equal (new (0, 1), tv.CursorPosition);
  1052. }
  1053. [Fact]
  1054. public void HistoryText_Undo_Redo_Two_Line_Selected_Return ()
  1055. {
  1056. var text = "This is the first line.\nThis is the second line.\nThis is the third line.";
  1057. var tv = new TextView { Text = text };
  1058. tv.SelectionStartColumn = 12;
  1059. tv.CursorPosition = new (18, 1);
  1060. Assert.True (tv.NewKeyDownEvent (Key.Enter));
  1061. Assert.Equal (
  1062. $"This is the {Environment.NewLine} line.{Environment.NewLine}This is the third line.",
  1063. tv.Text
  1064. );
  1065. Assert.Equal (3, tv.Lines);
  1066. Assert.Equal (new (0, 1), tv.CursorPosition);
  1067. // Undo
  1068. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  1069. Assert.Equal (
  1070. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  1071. tv.Text
  1072. );
  1073. Assert.Equal (3, tv.Lines);
  1074. Assert.Equal (new (18, 1), tv.CursorPosition);
  1075. Assert.False (tv.IsDirty);
  1076. // Redo
  1077. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  1078. Assert.Equal (
  1079. $"This is the {Environment.NewLine} line.{Environment.NewLine}This is the third line.",
  1080. tv.Text
  1081. );
  1082. Assert.Equal (3, tv.Lines);
  1083. Assert.Equal (new (0, 1), tv.CursorPosition);
  1084. // Undo
  1085. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  1086. Assert.Equal (
  1087. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}This is the third line.",
  1088. tv.Text
  1089. );
  1090. Assert.Equal (3, tv.Lines);
  1091. Assert.Equal (new (18, 1), tv.CursorPosition);
  1092. Assert.False (tv.IsDirty);
  1093. // Redo
  1094. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  1095. Assert.Equal (
  1096. $"This is the {Environment.NewLine} line.{Environment.NewLine}This is the third line.",
  1097. tv.Text
  1098. );
  1099. Assert.Equal (3, tv.Lines);
  1100. Assert.Equal (new (0, 1), tv.CursorPosition);
  1101. }
  1102. [Fact]
  1103. public void HistoryText_Undo_Redo_ApplyCellsAttribute ()
  1104. {
  1105. var text = "This is the first line.\nThis is the second line.\nThis is the third line.";
  1106. var tv = new TextView { Text = text };
  1107. tv.SelectionStartColumn = 12;
  1108. tv.CursorPosition = new (18, 1);
  1109. if (Environment.NewLine.Length == 2)
  1110. {
  1111. Assert.Equal (31, tv.SelectedLength);
  1112. }
  1113. else
  1114. {
  1115. Assert.Equal (30, tv.SelectedLength);
  1116. }
  1117. Assert.Equal ($"first line.{Environment.NewLine}This is the second", tv.SelectedText);
  1118. Assert.Equal ($"first line.{Environment.NewLine}This is the second", Cell.ToString (tv.SelectedCellsList));
  1119. Assert.Equal (new (18, 1), tv.CursorPosition);
  1120. Assert.False (tv.IsDirty);
  1121. AssertNullAttribute ();
  1122. tv.ApplyCellsAttribute (new (Color.Red, Color.Green));
  1123. AssertRedGreenAttribute ();
  1124. Assert.Equal (0, tv.SelectedLength);
  1125. Assert.Equal ("", tv.SelectedText);
  1126. Assert.Equal ($"first line.{Environment.NewLine}This is the second", Cell.ToString (tv.SelectedCellsList));
  1127. Assert.Equal (new (18, 1), tv.CursorPosition);
  1128. Assert.True (tv.IsDirty);
  1129. // Undo
  1130. Assert.True (tv.NewKeyDownEvent (Key.Z.WithCtrl));
  1131. AssertNullAttribute ();
  1132. Assert.Equal (12, tv.SelectionStartColumn);
  1133. Assert.Equal (0, tv.SelectionStartRow);
  1134. Assert.Equal (0, tv.SelectedLength);
  1135. Assert.Equal ("", tv.SelectedText);
  1136. Assert.Empty (tv.SelectedCellsList);
  1137. Assert.Equal (new (12, 0), tv.CursorPosition);
  1138. Assert.False (tv.IsDirty);
  1139. // Redo
  1140. Assert.True (tv.NewKeyDownEvent (Key.R.WithCtrl));
  1141. AssertRedGreenAttribute ();
  1142. Assert.Equal (12, tv.SelectionStartColumn);
  1143. Assert.Equal (0, tv.SelectionStartRow);
  1144. Assert.Equal (0, tv.SelectedLength);
  1145. Assert.Equal ("", tv.SelectedText);
  1146. Assert.Empty (tv.SelectedCellsList);
  1147. Assert.Equal (new (12, 0), tv.CursorPosition);
  1148. Assert.True (tv.IsDirty);
  1149. void AssertNullAttribute ()
  1150. {
  1151. tv.GetRegion (out List<List<Cell>> region, 0, 12, 1, 18);
  1152. foreach (List<Cell> cells in region)
  1153. {
  1154. foreach (Cell cell in cells)
  1155. {
  1156. Assert.Null (cell.Attribute);
  1157. }
  1158. }
  1159. }
  1160. void AssertRedGreenAttribute ()
  1161. {
  1162. tv.GetRegion (out List<List<Cell>> region, 0, 12, 1, 18);
  1163. foreach (List<Cell> cells in region)
  1164. {
  1165. foreach (Cell cell in cells)
  1166. {
  1167. Assert.Equal ("[Red,Green,None]", cell.Attribute.ToString ());
  1168. }
  1169. }
  1170. }
  1171. }
  1172. [Fact]
  1173. public void Internal_Tests ()
  1174. {
  1175. var txt = "This is a text.";
  1176. List<Cell> txtStrings = Cell.StringToCells (txt);
  1177. Assert.Equal (txt.Length, txtStrings.Count);
  1178. Assert.Equal ("T", txtStrings [0].Grapheme);
  1179. Assert.Equal ("h", txtStrings [1].Grapheme);
  1180. Assert.Equal ("i", txtStrings [2].Grapheme);
  1181. Assert.Equal ("s", txtStrings [3].Grapheme);
  1182. Assert.Equal (" ", txtStrings [4].Grapheme);
  1183. Assert.Equal ("i", txtStrings [5].Grapheme);
  1184. Assert.Equal ("s", txtStrings [6].Grapheme);
  1185. Assert.Equal (" ", txtStrings [7].Grapheme);
  1186. Assert.Equal ("a", txtStrings [8].Grapheme);
  1187. Assert.Equal (" ", txtStrings [9].Grapheme);
  1188. Assert.Equal ("t", txtStrings [10].Grapheme);
  1189. Assert.Equal ("e", txtStrings [11].Grapheme);
  1190. Assert.Equal ("x", txtStrings [12].Grapheme);
  1191. Assert.Equal ("t", txtStrings [13].Grapheme);
  1192. Assert.Equal (".", txtStrings [^1].Grapheme);
  1193. var col = 0;
  1194. Assert.True (TextModel.SetCol (ref col, 80, 79));
  1195. Assert.False (TextModel.SetCol (ref col, 80, 80));
  1196. Assert.Equal (79, col);
  1197. var start = 0;
  1198. var x = 8;
  1199. Assert.Equal (8, TextModel.GetColFromX (txtStrings, start, x));
  1200. Assert.Equal ("a", txtStrings [start + x].Grapheme);
  1201. start = 1;
  1202. x = 7;
  1203. Assert.Equal (7, TextModel.GetColFromX (txtStrings, start, x));
  1204. Assert.Equal ("a", txtStrings [start + x].Grapheme);
  1205. Assert.Equal ((15, 15), TextModel.DisplaySize (txtStrings));
  1206. Assert.Equal ((6, 6), TextModel.DisplaySize (txtStrings, 1, 7));
  1207. Assert.Equal (0, TextModel.CalculateLeftColumn (txtStrings, 0, 7, 8));
  1208. Assert.Equal (1, TextModel.CalculateLeftColumn (txtStrings, 0, 8, 8));
  1209. Assert.Equal (2, TextModel.CalculateLeftColumn (txtStrings, 0, 9, 8));
  1210. var tm = new TextModel ();
  1211. tm.AddLine (0, Cell.StringToCells ("This is first line."));
  1212. tm.AddLine (1, Cell.StringToCells ("This is last line."));
  1213. Assert.Equal ((new Point (2, 0), true), tm.FindNextText ("is", out bool gaveFullTurn));
  1214. Assert.False (gaveFullTurn);
  1215. Assert.Equal ((new Point (5, 0), true), tm.FindNextText ("is", out gaveFullTurn));
  1216. Assert.False (gaveFullTurn);
  1217. Assert.Equal ((new Point (2, 1), true), tm.FindNextText ("is", out gaveFullTurn));
  1218. Assert.False (gaveFullTurn);
  1219. Assert.Equal ((new Point (5, 1), true), tm.FindNextText ("is", out gaveFullTurn));
  1220. Assert.False (gaveFullTurn);
  1221. Assert.Equal ((new Point (2, 0), true), tm.FindNextText ("is", out gaveFullTurn));
  1222. Assert.True (gaveFullTurn);
  1223. tm.ResetContinuousFind (Point.Empty);
  1224. Assert.Equal ((new Point (5, 1), true), tm.FindPreviousText ("is", out gaveFullTurn));
  1225. Assert.False (gaveFullTurn);
  1226. Assert.Equal ((new Point (2, 1), true), tm.FindPreviousText ("is", out gaveFullTurn));
  1227. Assert.False (gaveFullTurn);
  1228. Assert.Equal ((new Point (5, 0), true), tm.FindPreviousText ("is", out gaveFullTurn));
  1229. Assert.False (gaveFullTurn);
  1230. Assert.Equal ((new Point (2, 0), true), tm.FindPreviousText ("is", out gaveFullTurn));
  1231. Assert.False (gaveFullTurn);
  1232. Assert.Equal ((new Point (5, 1), true), tm.FindPreviousText ("is", out gaveFullTurn));
  1233. Assert.True (gaveFullTurn);
  1234. Assert.Equal ((new Point (9, 1), true), tm.ReplaceAllText ("is", false, false, "really"));
  1235. Assert.Equal (Cell.StringToCells ("Threally really first line."), tm.GetLine (0));
  1236. Assert.Equal (Cell.StringToCells ("Threally really last line."), tm.GetLine (1));
  1237. tm = new ();
  1238. tm.AddLine (0, Cell.StringToCells ("This is first line."));
  1239. tm.AddLine (1, Cell.StringToCells ("This is last line."));
  1240. Assert.Equal ((new Point (5, 1), true), tm.ReplaceAllText ("is", false, true, "really"));
  1241. Assert.Equal (Cell.StringToCells ("This really first line."), tm.GetLine (0));
  1242. Assert.Equal (Cell.StringToCells ("This really last line."), tm.GetLine (1));
  1243. }
  1244. [Fact]
  1245. public void LeftColumn_Add_One_If_Text_Length_Is_Equal_To_Width ()
  1246. {
  1247. var tv = new TextView { Width = 10, Text = "1234567890" };
  1248. Assert.Equal (Point.Empty, tv.CursorPosition);
  1249. Assert.Equal (0, tv.LeftColumn);
  1250. tv.CursorPosition = new (9, 0);
  1251. Assert.Equal (new (9, 0), tv.CursorPosition);
  1252. Assert.Equal (0, tv.LeftColumn);
  1253. Assert.True (tv.NewKeyDownEvent (Key.CursorRight));
  1254. tv.CursorPosition = new (10, 0);
  1255. Assert.Equal (new (10, 0), tv.CursorPosition);
  1256. Assert.Equal (1, tv.LeftColumn);
  1257. }
  1258. [Fact]
  1259. public void LoadFile_Throws_If_File_Is_Empty ()
  1260. {
  1261. var result = false;
  1262. var tv = new TextView ();
  1263. Assert.Throws<ArgumentException> (() => result = tv.Load (""));
  1264. Assert.False (result);
  1265. }
  1266. [Fact]
  1267. public void LoadFile_Throws_If_File_Is_Null ()
  1268. {
  1269. var result = false;
  1270. var tv = new TextView ();
  1271. Assert.Throws<ArgumentNullException> (() => result = tv.Load ((string)null));
  1272. Assert.False (result);
  1273. }
  1274. [Fact]
  1275. public void LoadFile_Throws_If_File_Not_Exist ()
  1276. {
  1277. var result = false;
  1278. var tv = new TextView ();
  1279. Assert.Throws<FileNotFoundException> (() => result = tv.Load ("blabla"));
  1280. Assert.False (result);
  1281. }
  1282. [Fact]
  1283. public void LoadStream_CRLF ()
  1284. {
  1285. var text = "This is the first line.\r\nThis is the second line.\r\n";
  1286. var tv = new TextView ();
  1287. tv.Load (new MemoryStream (Encoding.ASCII.GetBytes (text)));
  1288. Assert.Equal (
  1289. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}",
  1290. tv.Text
  1291. );
  1292. }
  1293. [Fact]
  1294. public void LoadStream_IsDirty ()
  1295. {
  1296. var text = "Testing";
  1297. using (var stream = new MemoryStream ())
  1298. {
  1299. var writer = new StreamWriter (stream);
  1300. writer.Write (text);
  1301. writer.Flush ();
  1302. stream.Position = 0;
  1303. var tv = new TextView ();
  1304. tv.Load (stream);
  1305. Assert.Equal (7, text.Length);
  1306. Assert.Equal (text.Length, tv.Text.Length);
  1307. Assert.Equal (text, tv.Text);
  1308. Assert.False (tv.IsDirty);
  1309. }
  1310. }
  1311. [Fact]
  1312. public void LoadStream_IsDirty_With_Null_On_The_Text ()
  1313. {
  1314. var text = "Test\0ing";
  1315. using (var stream = new MemoryStream ())
  1316. {
  1317. var writer = new StreamWriter (stream);
  1318. writer.Write (text);
  1319. writer.Flush ();
  1320. stream.Position = 0;
  1321. var tv = new TextView ();
  1322. tv.Load (stream);
  1323. Assert.Equal (8, text.Length);
  1324. Assert.Equal (text.Length, tv.Text.Length);
  1325. Assert.Equal (8, text.Length);
  1326. Assert.Equal (8, tv.Text.Length);
  1327. Assert.Equal (text, tv.Text);
  1328. Assert.False (tv.IsDirty);
  1329. Assert.Equal ((Rune)'\u2400', ((Rune)tv.Text [4]).MakePrintable ());
  1330. }
  1331. }
  1332. [Fact]
  1333. public void LoadStream_LF ()
  1334. {
  1335. var text = "This is the first line.\nThis is the second line.\n";
  1336. var tv = new TextView ();
  1337. tv.Load (new MemoryStream (Encoding.ASCII.GetBytes (text)));
  1338. Assert.Equal (
  1339. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}",
  1340. tv.Text
  1341. );
  1342. }
  1343. [Fact]
  1344. public void LoadStream_Stream_Is_Empty ()
  1345. {
  1346. var tv = new TextView ();
  1347. tv.Load (new MemoryStream ());
  1348. Assert.Equal ("", tv.Text);
  1349. }
  1350. [Fact]
  1351. public void LoadStream_Throws_If_Stream_Is_Null ()
  1352. {
  1353. var tv = new TextView ();
  1354. Assert.Throws<ArgumentNullException> (() => tv.Load ((Stream)null));
  1355. }
  1356. [Fact]
  1357. public void ReplaceAllText_Does_Not_Throw_Exception ()
  1358. {
  1359. var textToFind = "hello! hello!";
  1360. var textToReplace = "hello!";
  1361. var tv = new TextView { Width = 20, Height = 3, Text = textToFind };
  1362. Exception exception = Record.Exception (() => tv.ReplaceAllText (textToFind, false, false, textToReplace));
  1363. Assert.Null (exception);
  1364. Assert.Equal (textToReplace, tv.Text);
  1365. }
  1366. [Fact]
  1367. public void StringToRunes_Slipts_CRLF ()
  1368. {
  1369. var text = "This is the first line.\r\nThis is the second line.\r\n";
  1370. var tv = new TextView ();
  1371. tv.Text = text;
  1372. Assert.Equal (
  1373. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}",
  1374. tv.Text
  1375. );
  1376. }
  1377. [Fact]
  1378. public void StringToRunes_Slipts_LF ()
  1379. {
  1380. var text = "This is the first line.\nThis is the second line.\n";
  1381. var tv = new TextView ();
  1382. tv.Text = text;
  1383. Assert.Equal (
  1384. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}",
  1385. tv.Text
  1386. );
  1387. }
  1388. [Fact]
  1389. public void TextView_MultiLine_But_Without_Tabs ()
  1390. {
  1391. var view = new TextView ();
  1392. // the default for TextView
  1393. Assert.True (view.Multiline);
  1394. view.AllowsTab = false;
  1395. Assert.False (view.AllowsTab);
  1396. Assert.True (view.Multiline);
  1397. }
  1398. [Fact]
  1399. public void WordBackward_WordForward_Limits_Return_Null ()
  1400. {
  1401. var model = new TextModel ();
  1402. model.LoadString ("Test");
  1403. (int col, int row)? newPos = model.WordBackward (0, 0, false);
  1404. Assert.Null (newPos);
  1405. newPos = model.WordForward (4, 0, false);
  1406. Assert.Null (newPos);
  1407. }
  1408. [Fact]
  1409. public void WordWrap_Gets_Sets ()
  1410. {
  1411. var tv = new TextView { WordWrap = true };
  1412. Assert.True (tv.WordWrap);
  1413. tv.WordWrap = false;
  1414. Assert.False (tv.WordWrap);
  1415. }
  1416. [Fact]
  1417. public void WordWrap_True_Text_Always_Returns_Unwrapped ()
  1418. {
  1419. var text = "This is the first line.\nThis is the second line.\n";
  1420. var tv = new TextView { Width = 10 };
  1421. tv.Text = text;
  1422. Assert.Equal (
  1423. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}",
  1424. tv.Text
  1425. );
  1426. tv.WordWrap = true;
  1427. Assert.Equal (
  1428. $"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}",
  1429. tv.Text
  1430. );
  1431. }
  1432. [Fact]
  1433. public void HotKey_Command_SetsFocus ()
  1434. {
  1435. var view = new TextView ();
  1436. view.CanFocus = true;
  1437. Assert.False (view.HasFocus);
  1438. view.InvokeCommand (Command.HotKey);
  1439. Assert.True (view.HasFocus);
  1440. }
  1441. [Fact]
  1442. public void HotKey_Command_Does_Not_Accept ()
  1443. {
  1444. var view = new TextView ();
  1445. var accepted = false;
  1446. view.Accepting += OnAccept;
  1447. view.InvokeCommand (Command.HotKey);
  1448. Assert.False (accepted);
  1449. return;
  1450. void OnAccept (object sender, CommandEventArgs e) { accepted = true; }
  1451. }
  1452. [Theory]
  1453. [InlineData (false, 1)]
  1454. [InlineData (true, 1)]
  1455. public void Accepted_Command_Raises_Accepted_Regardles_Of_AllowsReturn (bool allowsReturn, int expectedAcceptEvents)
  1456. {
  1457. var view = new TextView
  1458. {
  1459. AllowsReturn = allowsReturn
  1460. };
  1461. var acceptedEvents = 0;
  1462. view.Accepting += Accept;
  1463. view.InvokeCommand (Command.Accept);
  1464. Assert.Equal (expectedAcceptEvents, acceptedEvents);
  1465. return;
  1466. void Accept (object sender, CommandEventArgs e) { acceptedEvents++; }
  1467. }
  1468. [Theory]
  1469. [InlineData (false, 1)]
  1470. [InlineData (true, 0)]
  1471. public void Enter_Key_Fires_Accepted_BasedOn_AllowsReturn (bool allowsReturn, int expectedAccepts)
  1472. {
  1473. var view = new TextView
  1474. {
  1475. Multiline = allowsReturn
  1476. };
  1477. var accepted = 0;
  1478. view.Accepting += Accept;
  1479. view.NewKeyDownEvent (Key.Enter);
  1480. Assert.Equal (expectedAccepts, accepted);
  1481. return;
  1482. void Accept (object sender, CommandEventArgs e) { accepted++; }
  1483. }
  1484. [Theory]
  1485. [InlineData (false, 1)]
  1486. [InlineData (true, 0)]
  1487. public void Enter_Key_Fires_Accepted_BasedOn_Multiline (bool multiline, int expectedAccepts)
  1488. {
  1489. var view = new TextView
  1490. {
  1491. Multiline = multiline
  1492. };
  1493. var accepted = 0;
  1494. view.Accepting += Accept;
  1495. view.NewKeyDownEvent (Key.Enter);
  1496. Assert.Equal (expectedAccepts, accepted);
  1497. return;
  1498. void Accept (object sender, CommandEventArgs e) { accepted++; }
  1499. }
  1500. [Fact]
  1501. public void Space_Key_Types_Space ()
  1502. {
  1503. var view = new TextView ();
  1504. view.NewKeyDownEvent (Key.Space);
  1505. Assert.Equal (" ", view.Text);
  1506. }
  1507. [Theory]
  1508. [InlineData (false, false, 1, 1)]
  1509. [InlineData (false, true, 1, 0)]
  1510. [InlineData (true, false, 0, 0)]
  1511. [InlineData (true, true, 0, 0)]
  1512. public void Accepted_Event_Handled_Prevents_Default_Button_Accept (bool multiline, bool handleAccept, int expectedAccepts, int expectedButtonAccepts)
  1513. {
  1514. var superView = new Window ();
  1515. var tv = new TextView
  1516. {
  1517. Multiline = multiline
  1518. };
  1519. var button = new Button
  1520. {
  1521. IsDefault = true
  1522. };
  1523. superView.Add (tv, button);
  1524. var buttonAccept = 0;
  1525. button.Accepting += ButtonAccept;
  1526. var textViewAccept = 0;
  1527. tv.Accepting += TextViewAccept;
  1528. tv.SetFocus ();
  1529. Assert.True (tv.HasFocus);
  1530. superView.NewKeyDownEvent (Key.Enter);
  1531. Assert.Equal (expectedAccepts, textViewAccept);
  1532. Assert.Equal (expectedButtonAccepts, buttonAccept);
  1533. button.SetFocus ();
  1534. superView.NewKeyDownEvent (Key.Enter);
  1535. Assert.Equal (expectedAccepts, textViewAccept);
  1536. Assert.Equal (expectedButtonAccepts + 1, buttonAccept);
  1537. return;
  1538. void TextViewAccept (object sender, CommandEventArgs e)
  1539. {
  1540. textViewAccept++;
  1541. e.Handled = handleAccept;
  1542. }
  1543. void ButtonAccept (object sender, CommandEventArgs e) { buttonAccept++; }
  1544. }
  1545. [Theory]
  1546. [InlineData (true, 0)]
  1547. [InlineData (false, 1)]
  1548. public void Accepted_No_Handler_Enables_Default_Button_Accept (bool multiline, int expectedButtonAccept)
  1549. {
  1550. var superView = new Window ();
  1551. var tv = new TextView
  1552. {
  1553. Multiline = multiline
  1554. };
  1555. var button = new Button
  1556. {
  1557. IsDefault = true
  1558. };
  1559. superView.Add (tv, button);
  1560. var buttonAccept = 0;
  1561. button.Accepting += ButtonAccept;
  1562. tv.SetFocus ();
  1563. Assert.True (tv.HasFocus);
  1564. superView.NewKeyDownEvent (Key.Enter);
  1565. Assert.Equal (expectedButtonAccept, buttonAccept);
  1566. button.SetFocus ();
  1567. superView.NewKeyDownEvent (Key.Enter);
  1568. Assert.Equal (expectedButtonAccept + 1, buttonAccept);
  1569. return;
  1570. void ButtonAccept (object sender, CommandEventArgs e) { buttonAccept++; }
  1571. }
  1572. [Fact]
  1573. public void Autocomplete_Popup_Added_To_SuperView_On_Init ()
  1574. {
  1575. View superView = new ()
  1576. {
  1577. CanFocus = true
  1578. };
  1579. TextView t = new ();
  1580. superView.Add (t);
  1581. Assert.Single (superView.SubViews);
  1582. superView.BeginInit ();
  1583. superView.EndInit ();
  1584. Assert.Equal (2, superView.SubViews.Count);
  1585. }
  1586. [Fact]
  1587. public void Autocomplete__Added_To_SuperView_On_Add ()
  1588. {
  1589. View superView = new ()
  1590. {
  1591. CanFocus = true,
  1592. Id = "superView"
  1593. };
  1594. superView.BeginInit ();
  1595. superView.EndInit ();
  1596. Assert.Empty (superView.SubViews);
  1597. TextView t = new ()
  1598. {
  1599. Id = "t"
  1600. };
  1601. superView.Add (t);
  1602. Assert.Equal (2, superView.SubViews.Count);
  1603. }
  1604. [Fact]
  1605. public void Autocomplete_Visible_False_By_Default ()
  1606. {
  1607. View superView = new ()
  1608. {
  1609. CanFocus = true
  1610. };
  1611. TextView t = new ();
  1612. superView.Add (t);
  1613. superView.BeginInit ();
  1614. superView.EndInit ();
  1615. Assert.Equal (2, superView.SubViews.Count);
  1616. Assert.True (t.Visible);
  1617. Assert.False (t.Autocomplete.Visible);
  1618. }
  1619. [Fact]
  1620. public void Right_CursorAtEnd_WithSelection_ShouldClearSelection ()
  1621. {
  1622. var tv = new TextView
  1623. {
  1624. Text = "Hello"
  1625. };
  1626. tv.SetFocus ();
  1627. tv.NewKeyDownEvent (Key.End.WithShift);
  1628. Assert.Equal (5, tv.CursorPosition.X);
  1629. // When there is selected text and the cursor is at the end of the text field
  1630. Assert.Equal ("Hello", tv.SelectedText);
  1631. // Pressing right should not move focus, instead it should clear selection
  1632. Assert.True (tv.NewKeyDownEvent (Key.CursorRight));
  1633. Assert.Empty (tv.SelectedText);
  1634. // Now that the selection is cleared another right keypress should move focus
  1635. Assert.False (tv.NewKeyDownEvent (Key.CursorRight));
  1636. }
  1637. [Fact]
  1638. public void Left_CursorAtStart_WithSelection_ShouldClearSelection ()
  1639. {
  1640. var tv = new TextView
  1641. {
  1642. Text = "Hello"
  1643. };
  1644. tv.SetFocus ();
  1645. tv.NewKeyDownEvent (Key.CursorRight);
  1646. tv.NewKeyDownEvent (Key.CursorRight);
  1647. Assert.Equal (2, tv.CursorPosition.X);
  1648. Assert.True (tv.NewKeyDownEvent (Key.CursorLeft.WithShift));
  1649. Assert.True (tv.NewKeyDownEvent (Key.CursorLeft.WithShift));
  1650. // When there is selected text and the cursor is at the start of the text field
  1651. Assert.Equal ("He", tv.SelectedText);
  1652. // Pressing left should not move focus, instead it should clear selection
  1653. Assert.True (tv.NewKeyDownEvent (Key.CursorLeft));
  1654. Assert.Empty (tv.SelectedText);
  1655. // When clearing selected text with left the cursor should be at the start of the selection
  1656. Assert.Equal (0, tv.CursorPosition.X);
  1657. // Now that the selection is cleared another left keypress should move focus
  1658. Assert.False (tv.NewKeyDownEvent (Key.CursorLeft));
  1659. }
  1660. [Fact]
  1661. public void Equals_True ()
  1662. {
  1663. var c1 = new Cell ();
  1664. var c2 = new Cell ();
  1665. Assert.True (c1.Equals (c2));
  1666. Assert.True (c2.Equals (c1));
  1667. c1.Grapheme = new ("a");
  1668. c1.Attribute = new ();
  1669. c2.Grapheme = new ("a");
  1670. c2.Attribute = new ();
  1671. Assert.True (c1.Equals (c2));
  1672. Assert.True (c2.Equals (c1));
  1673. }
  1674. [Fact]
  1675. public void Cell_LoadCells_Without_Scheme_Is_Never_Null ()
  1676. {
  1677. List<Cell> cells = new ()
  1678. {
  1679. new () { Grapheme = new ("T") },
  1680. new () { Grapheme = new ("e") },
  1681. new () { Grapheme = new ("s") },
  1682. new () { Grapheme = new ("t") }
  1683. };
  1684. TextView tv = CreateTextView ();
  1685. var top = new Runnable ();
  1686. top.Add (tv);
  1687. tv.Load (cells);
  1688. for (var i = 0; i < tv.Lines; i++)
  1689. {
  1690. List<Cell> line = tv.GetLine (i);
  1691. foreach (Cell c in line)
  1692. {
  1693. Assert.NotNull (c.Attribute);
  1694. }
  1695. }
  1696. }
  1697. [Theory]
  1698. [InlineData ("", false, "")]
  1699. [InlineData ("", true, "")]
  1700. [InlineData (" ", false, "")]
  1701. [InlineData (" ", true, "")]
  1702. [InlineData (" ", false, "")]
  1703. [InlineData (" ", true, "")]
  1704. [InlineData ("a", false, "")]
  1705. [InlineData ("a", true, "")]
  1706. [InlineData ("a ", false, "")]
  1707. [InlineData ("a ", true, "")]
  1708. [InlineData (" a ", false, "a ", "")]
  1709. [InlineData (" a ", true, "a ", "")]
  1710. [InlineData (" H1 ", false, "H1 ", "")]
  1711. [InlineData (" H1 ", true, "H1 ", "")]
  1712. [InlineData ("a$", false, "$", "")]
  1713. [InlineData ("a$", true, "$", "")]
  1714. [InlineData ("a$#", false, "$#", "")]
  1715. [InlineData ("a$#", true, "$#", "#", "")]
  1716. [InlineData (" a$# ", false, "a$# ", "$# ", "")]
  1717. [InlineData (" a$# ", true, "a$# ", "$# ", "# ", "")]
  1718. [InlineData ("\"$schema\"", false, "schema\"", "\"", "")]
  1719. [InlineData ("\"$schema\"", true, "$schema\"", "schema\"", "\"", "")]
  1720. [InlineData ("\": \"", false, "\"", "")]
  1721. [InlineData ("\": \"", true, "\"", "")]
  1722. [InlineData ("\"$schema\": \"", false, "schema\": \"", "\": \"", "\"", "")]
  1723. [InlineData ("\"$schema\": \"", true, "$schema\": \"", "schema\": \"", "\": \"", "\"", "")]
  1724. [InlineData ("1ºªA", false, "")]
  1725. [InlineData ("1ºªA", true, "")]
  1726. [InlineData (
  1727. "ºª\\!\"#%&/()?'«»*;,:._-@{[]}]|$=+´`~^<>£€¨",
  1728. false,
  1729. "\\!\"#%&/()?'«»*;,:._-@{[]}]|$=+´`~^<>£€¨",
  1730. "")]
  1731. [InlineData (
  1732. "ºª\\!\"#%&/()?'«»*;,:._-@{[]}]|$=+´`~^<>£€¨",
  1733. true,
  1734. "\\!\"#%&/()?'«»*;,:._-@{[]}]|$=+´`~^<>£€¨",
  1735. "|$=+´`~^<>£€¨",
  1736. "")]
  1737. [InlineData (
  1738. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1739. false,
  1740. "\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1741. " \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1742. "\"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1743. "schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1744. "\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1745. "\"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1746. "https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1747. "://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1748. "gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1749. "-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1750. "cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1751. ".github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1752. "github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1753. ".io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1754. "io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1755. "/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1756. "Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1757. ".Gui/schemas/tui-config-schema.json\"\r\n}",
  1758. "Gui/schemas/tui-config-schema.json\"\r\n}",
  1759. "/schemas/tui-config-schema.json\"\r\n}",
  1760. "schemas/tui-config-schema.json\"\r\n}",
  1761. "/tui-config-schema.json\"\r\n}",
  1762. "tui-config-schema.json\"\r\n}",
  1763. "-config-schema.json\"\r\n}",
  1764. "config-schema.json\"\r\n}",
  1765. "-schema.json\"\r\n}",
  1766. "schema.json\"\r\n}",
  1767. ".json\"\r\n}",
  1768. "json\"\r\n}",
  1769. "\"\r\n}",
  1770. "\r\n}",
  1771. "}",
  1772. "")]
  1773. [InlineData (
  1774. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1775. true,
  1776. "\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1777. " \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1778. "\"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1779. "$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1780. "schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1781. "\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1782. "\"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1783. "https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1784. "://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1785. "gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1786. "-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1787. "cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1788. ".github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1789. "github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1790. ".io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1791. "io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1792. "/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1793. "Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1794. ".Gui/schemas/tui-config-schema.json\"\r\n}",
  1795. "Gui/schemas/tui-config-schema.json\"\r\n}",
  1796. "/schemas/tui-config-schema.json\"\r\n}",
  1797. "schemas/tui-config-schema.json\"\r\n}",
  1798. "/tui-config-schema.json\"\r\n}",
  1799. "tui-config-schema.json\"\r\n}",
  1800. "-config-schema.json\"\r\n}",
  1801. "config-schema.json\"\r\n}",
  1802. "-schema.json\"\r\n}",
  1803. "schema.json\"\r\n}",
  1804. ".json\"\r\n}",
  1805. "json\"\r\n}",
  1806. "\"\r\n}",
  1807. "\r\n}",
  1808. "}",
  1809. "")]
  1810. public void WordForward_WordWrap_False_True (string text, bool useSameRuneType, params string [] expectedText)
  1811. {
  1812. TextView tv = CreateTextView ();
  1813. tv.UseSameRuneTypeForWords = useSameRuneType;
  1814. ProcessDeleteWithCtrl ();
  1815. tv.WordWrap = true;
  1816. ProcessDeleteWithCtrl ();
  1817. void ProcessDeleteWithCtrl ()
  1818. {
  1819. tv.Text = text;
  1820. var idx = 0;
  1821. while (!string.IsNullOrEmpty (tv.Text))
  1822. {
  1823. tv.NewKeyDownEvent (Key.Delete.WithCtrl);
  1824. Assert.Equal (expectedText [idx].Replace ("\r\n", Environment.NewLine), tv.Text);
  1825. idx++;
  1826. }
  1827. }
  1828. }
  1829. [Theory]
  1830. [InlineData ("", false, "")]
  1831. [InlineData ("", true, "")]
  1832. [InlineData (" ", false, "")]
  1833. [InlineData (" ", true, "")]
  1834. [InlineData (" ", false, "")]
  1835. [InlineData (" ", true, "")]
  1836. [InlineData ("a", false, "")]
  1837. [InlineData ("a", true, "")]
  1838. [InlineData ("a ", false, "")]
  1839. [InlineData ("a ", true, "")]
  1840. [InlineData (" a ", false, " ", "")]
  1841. [InlineData (" a ", true, " ", "")]
  1842. [InlineData (" H1 ", false, " ", "")]
  1843. [InlineData (" H1 ", true, " ", "")]
  1844. [InlineData ("a$", false, "a", "")]
  1845. [InlineData ("a$", true, "a", "")]
  1846. [InlineData ("a$#", false, "a", "")]
  1847. [InlineData ("a$#", true, "a$", "a", "")]
  1848. [InlineData (" a$# ", false, " a", " ", "")]
  1849. [InlineData (" a$# ", true, " a$", " a", " ", "")]
  1850. [InlineData ("\"$schema\"", false, "\"$schema", "\"$", "")]
  1851. [InlineData ("\"$schema\"", true, "\"$schema", "\"$", "\"", "")]
  1852. [InlineData ("\"$schema\": \"", false, "\"$schema\": ", "\"$schema", "\"$", "")]
  1853. [InlineData ("\"$schema\": \"", true, "\"$schema\": ", "\"$schema", "\"$", "\"", "")]
  1854. [InlineData ("1ºªA", false, "")]
  1855. [InlineData ("1ºªA", true, "")]
  1856. [InlineData (
  1857. "ºª\\!\"#%&/()?'«»*;,:._-@{[]}]|$=+´`~^<>£€¨",
  1858. false,
  1859. "ºª",
  1860. "")]
  1861. [InlineData (
  1862. "ºª\\!\"#%&/()?'«»*;,:._-@{[]}]|$=+´`~^<>£€¨",
  1863. true,
  1864. "ºª\\!\"#%&/()?'«»*;,:._-@{[]}]",
  1865. "ºª",
  1866. "")]
  1867. [InlineData (
  1868. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1869. false,
  1870. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n",
  1871. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"",
  1872. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json",
  1873. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.",
  1874. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema",
  1875. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-",
  1876. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config",
  1877. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-",
  1878. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui",
  1879. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/",
  1880. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas",
  1881. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/",
  1882. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui",
  1883. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.",
  1884. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal",
  1885. "{\r\n \"$schema\": \"https://gui-cs.github.io/",
  1886. "{\r\n \"$schema\": \"https://gui-cs.github.io",
  1887. "{\r\n \"$schema\": \"https://gui-cs.github.",
  1888. "{\r\n \"$schema\": \"https://gui-cs.github",
  1889. "{\r\n \"$schema\": \"https://gui-cs.",
  1890. "{\r\n \"$schema\": \"https://gui-cs",
  1891. "{\r\n \"$schema\": \"https://gui-",
  1892. "{\r\n \"$schema\": \"https://gui",
  1893. "{\r\n \"$schema\": \"https://",
  1894. "{\r\n \"$schema\": \"https",
  1895. "{\r\n \"$schema\": \"",
  1896. "{\r\n \"$schema\": ",
  1897. "{\r\n \"$schema",
  1898. "{\r\n \"$",
  1899. "{\r\n ",
  1900. "{\r\n",
  1901. "{",
  1902. "")]
  1903. [InlineData (
  1904. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n}",
  1905. true,
  1906. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"\r\n",
  1907. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json\"",
  1908. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json",
  1909. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.",
  1910. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema",
  1911. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-",
  1912. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-config",
  1913. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui-",
  1914. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/tui",
  1915. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas/",
  1916. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/schemas",
  1917. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui/",
  1918. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.Gui",
  1919. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal.",
  1920. "{\r\n \"$schema\": \"https://gui-cs.github.io/Terminal",
  1921. "{\r\n \"$schema\": \"https://gui-cs.github.io/",
  1922. "{\r\n \"$schema\": \"https://gui-cs.github.io",
  1923. "{\r\n \"$schema\": \"https://gui-cs.github.",
  1924. "{\r\n \"$schema\": \"https://gui-cs.github",
  1925. "{\r\n \"$schema\": \"https://gui-cs.",
  1926. "{\r\n \"$schema\": \"https://gui-cs",
  1927. "{\r\n \"$schema\": \"https://gui-",
  1928. "{\r\n \"$schema\": \"https://gui",
  1929. "{\r\n \"$schema\": \"https://",
  1930. "{\r\n \"$schema\": \"https",
  1931. "{\r\n \"$schema\": \"",
  1932. "{\r\n \"$schema\": ",
  1933. "{\r\n \"$schema",
  1934. "{\r\n \"$",
  1935. "{\r\n \"",
  1936. "{\r\n ",
  1937. "{\r\n",
  1938. "{",
  1939. "")]
  1940. public void WordBackward_WordWrap_False_True (string text, bool useSameRuneType, params string [] expectedText)
  1941. {
  1942. TextView tv = CreateTextView ();
  1943. tv.UseSameRuneTypeForWords = useSameRuneType;
  1944. ProcessBackspaceWithCtrl ();
  1945. tv.WordWrap = true;
  1946. ProcessBackspaceWithCtrl ();
  1947. void ProcessBackspaceWithCtrl ()
  1948. {
  1949. tv.Text = text;
  1950. tv.MoveEnd ();
  1951. var idx = 0;
  1952. while (!string.IsNullOrEmpty (tv.Text))
  1953. {
  1954. tv.NewKeyDownEvent (Key.Backspace.WithCtrl);
  1955. Assert.Equal (expectedText [idx].Replace ("\r\n", Environment.NewLine), tv.Text);
  1956. idx++;
  1957. }
  1958. }
  1959. }
  1960. [Theory]
  1961. [InlineData ("", 0, false, "")]
  1962. [InlineData ("", 0, true, "")]
  1963. [InlineData ("a", 0, false, "a")]
  1964. [InlineData ("a", 0, true, "a")]
  1965. [InlineData ("a:", 0, false, "a")]
  1966. [InlineData ("a:", 0, true, "a")]
  1967. [InlineData ("a:", 1, false, ":")]
  1968. [InlineData ("a:", 1, true, ":")]
  1969. [InlineData ("a ", 0, false, "a ")]
  1970. [InlineData ("a ", 0, true, "a")]
  1971. [InlineData ("a ", 1, false, "a ")]
  1972. [InlineData ("a ", 1, true, "a")]
  1973. [InlineData ("a b", 0, false, "a ")]
  1974. [InlineData ("a b", 0, true, "a")]
  1975. [InlineData ("a b", 1, false, "a ")]
  1976. [InlineData ("a b", 1, true, "a")]
  1977. [InlineData ("a b ", 2, false, "b ")]
  1978. [InlineData ("a b ", 2, true, "b")]
  1979. [InlineData ("a b ", 3, false, "b ")]
  1980. [InlineData ("a b ", 3, true, "b")]
  1981. [InlineData (" a b ", 0, false, " ")]
  1982. [InlineData (" a b ", 0, true, " ")]
  1983. [InlineData (" a b ", 2, false, " ")]
  1984. [InlineData (" a b ", 2, true, " ")]
  1985. [InlineData (" a b ", 3, false, " ")]
  1986. [InlineData (" a b ", 3, true, " ")]
  1987. [InlineData (" H1$&#2you ", 2, false, "H1")]
  1988. [InlineData (" H1$&#2you ", 2, true, "H1")]
  1989. [InlineData (" H1$&#2you ", 3, false, "$&#")]
  1990. [InlineData (" H1$&#2you ", 3, true, "$&#")]
  1991. [InlineData (" H1$&#2you ", 4, false, "$&#")]
  1992. [InlineData (" H1$&#2you ", 4, true, "$&#")]
  1993. [InlineData (" H1$&#2you ", 5, false, "$&#")]
  1994. [InlineData (" H1$&#2you ", 5, true, "$&#")]
  1995. [InlineData (" H1$&#2you ", 6, false, "2you ")]
  1996. [InlineData (" H1$&#2you ", 6, true, "2you")]
  1997. public void ProcessDoubleClickSelection_False_True (string text, int col, bool selectWordOnly, string expectedText)
  1998. {
  1999. TextView tv = CreateTextView ();
  2000. tv.Text = text;
  2001. tv.SelectWordOnlyOnDoubleClick = selectWordOnly;
  2002. Assert.True (tv.NewMouseEvent (new () { Position = new (col, 0), Flags = MouseFlags.Button1DoubleClicked }));
  2003. Assert.Equal (expectedText, tv.SelectedText);
  2004. }
  2005. [Fact]
  2006. public void ReadOnly_True_Move_Right_Moves_Until_The_End_Of_Text_More_One_Column ()
  2007. {
  2008. TextView tv = CreateTextView ();
  2009. tv.Text = "Hi";
  2010. tv.ReadOnly = true;
  2011. Assert.Equal (0, tv.CurrentColumn);
  2012. Assert.True (tv.NewKeyDownEvent (Key.CursorRight.WithShift));
  2013. Assert.Equal (1, tv.CurrentColumn);
  2014. Assert.Equal ("H", tv.SelectedText);
  2015. Assert.True (tv.NewKeyDownEvent (Key.CursorRight.WithShift));
  2016. Assert.Equal (2, tv.CurrentColumn);
  2017. Assert.Equal ("Hi", tv.SelectedText);
  2018. }
  2019. [Fact]
  2020. public void LeftColumn_Treat_Negative_Width_As_One_Column ()
  2021. {
  2022. TextView tv = new () { Width = 2, Height = 1, Text = "\u001B[" };
  2023. Assert.Equal (0, tv.LeftColumn);
  2024. Assert.Equal (new (0, 0), tv.CursorPosition);
  2025. Assert.True (tv.NewKeyDownEvent (Key.CursorRight));
  2026. Assert.Equal (0, tv.LeftColumn);
  2027. Assert.Equal (new (1, 0), tv.CursorPosition);
  2028. Assert.True (tv.NewKeyDownEvent (Key.CursorRight));
  2029. Assert.Equal (1, tv.LeftColumn);
  2030. Assert.Equal (new (2, 0), tv.CursorPosition);
  2031. Assert.False (tv.NewKeyDownEvent (Key.CursorRight));
  2032. Assert.Equal (1, tv.LeftColumn);
  2033. Assert.Equal (new (2, 0), tv.CursorPosition);
  2034. }
  2035. private TextView CreateTextView () { return new () { Width = 30, Height = 10 }; }
  2036. }