123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- using System;
- using System.Threading;
- using Xunit;
- namespace Terminal.Gui.Core {
- public class CollectionNavigatorTests {
- static string [] simpleStrings = new string []{
- "appricot", // 0
- "arm", // 1
- "bat", // 2
- "batman", // 3
- "candle" // 4
- };
- [Fact]
- public void ShouldAcceptNegativeOne ()
- {
- var n = new CollectionNavigator (simpleStrings);
- // Expect that index of -1 (i.e. no selection) should work correctly
- // and select the first entry of the letter 'b'
- Assert.Equal (2, n.GetNextMatchingItem (-1, 'b'));
- }
- [Fact]
- public void OutOfBoundsShouldBeIgnored ()
- {
- var n = new CollectionNavigator (simpleStrings);
- // Expect saying that index 500 is the current selection should not cause
- // error and just be ignored (treated as no selection)
- Assert.Equal (2, n.GetNextMatchingItem (500, 'b'));
- }
- [Fact]
- public void Cycling ()
- {
- var n = new CollectionNavigator (simpleStrings);
- Assert.Equal (2, n.GetNextMatchingItem (0, 'b'));
- Assert.Equal (3, n.GetNextMatchingItem (2, 'b'));
- // if 4 (candle) is selected it should loop back to bat
- Assert.Equal (2, n.GetNextMatchingItem (4, 'b'));
- }
- [Fact]
- public void FullText ()
- {
- var strings = new string []{
- "appricot",
- "arm",
- "ta",
- "target",
- "text",
- "egg",
- "candle"
- };
- var n = new CollectionNavigator (strings);
- int current = 0;
- Assert.Equal (strings.IndexOf ("ta"), current = n.GetNextMatchingItem (current, 't'));
- // should match "te" in "text"
- Assert.Equal (strings.IndexOf ("text"), current = n.GetNextMatchingItem (current, 'e'));
- // still matches text
- Assert.Equal (strings.IndexOf ("text"), current = n.GetNextMatchingItem (current, 'x'));
- // nothing starts texa so it should NOT jump to appricot
- Assert.Equal (strings.IndexOf ("text"), current = n.GetNextMatchingItem (current, 'a'));
- Thread.Sleep (n.TypingDelay + 100);
- // nothing starts "texa". Since were past timedelay we DO jump to appricot
- Assert.Equal (strings.IndexOf ("appricot"), current = n.GetNextMatchingItem (current, 'a'));
- }
- [Fact]
- public void Unicode ()
- {
- var strings = new string []{
- "appricot",
- "arm",
- "ta",
- "丗丙业丞",
- "丗丙丛",
- "text",
- "egg",
- "candle"
- };
- var n = new CollectionNavigator (strings);
- int current = 0;
- Assert.Equal (strings.IndexOf ("丗丙业丞"), current = n.GetNextMatchingItem (current, '丗'));
- // 丗丙业丞 is as good a match as 丗丙丛
- // so when doing multi character searches we should
- // prefer to stay on the same index unless we invalidate
- // our typed text
- Assert.Equal (strings.IndexOf ("丗丙业丞"), current = n.GetNextMatchingItem (current, '丙'));
- // No longer matches 丗丙业丞 and now only matches 丗丙丛
- // so we should move to the new match
- Assert.Equal (strings.IndexOf ("丗丙丛"), current = n.GetNextMatchingItem (current, '丛'));
- // nothing starts "丗丙丛a". Since were still in the timedelay we do not jump to appricot
- Assert.Equal (strings.IndexOf ("丗丙丛"), current = n.GetNextMatchingItem (current, 'a'));
- Thread.Sleep (n.TypingDelay + 100);
- // nothing starts "丗丙丛a". Since were past timedelay we DO jump to appricot
- Assert.Equal (strings.IndexOf ("appricot"), current = n.GetNextMatchingItem (current, 'a'));
- }
- [Fact]
- public void AtSymbol ()
- {
- var strings = new string []{
- "appricot",
- "arm",
- "ta",
- "@bob",
- "@bb",
- "text",
- "egg",
- "candle"
- };
- var n = new CollectionNavigator (strings);
- Assert.Equal (3, n.GetNextMatchingItem (0, '@'));
- Assert.Equal (3, n.GetNextMatchingItem (3, 'b'));
- Assert.Equal (4, n.GetNextMatchingItem (3, 'b'));
- }
- [Fact]
- public void Word ()
- {
- var strings = new string []{
- "appricot",
- "arm",
- "bat",
- "batman",
- "bates hotel",
- "candle"
- };
- int current = 0;
- var n = new CollectionNavigator (strings);
- Assert.Equal (strings.IndexOf ("bat"), current = n.GetNextMatchingItem (current, 'b')); // match bat
- Assert.Equal (strings.IndexOf ("bat"), current = n.GetNextMatchingItem (current, 'a')); // match bat
- Assert.Equal (strings.IndexOf ("bat"), current = n.GetNextMatchingItem (current, 't')); // match bat
- Assert.Equal (strings.IndexOf ("bates hotel"), current = n.GetNextMatchingItem (current, 'e')); // match bates hotel
- Assert.Equal (strings.IndexOf ("bates hotel"), current = n.GetNextMatchingItem (current, 's')); // match bates hotel
- Assert.Equal (strings.IndexOf ("bates hotel"), current = n.GetNextMatchingItem (current, ' ')); // match bates hotel
- }
- [Fact]
- public void Symbols ()
- {
- var strings = new string []{
- "$$",
- "$100.00",
- "$101.00",
- "$101.10",
- "$200.00",
- "appricot"
- };
- int current = 0;
- var n = new CollectionNavigator (strings);
- Assert.Equal (strings.IndexOf ("appricot"), current = n.GetNextMatchingItem (current, 'a'));
- Assert.Equal ("a", n.SearchString);
- Assert.Equal (strings.IndexOf ("$$"), current = n.GetNextMatchingItem (current, '$'));
- Assert.Equal ("$", n.SearchString);
- Assert.Equal (strings.IndexOf ("$100.00"), current = n.GetNextMatchingItem (current, '1'));
- Assert.Equal ("$1", n.SearchString);
- Assert.Equal (strings.IndexOf ("$100.00"), current = n.GetNextMatchingItem (current, '0'));
- Assert.Equal ("$10", n.SearchString);
- Assert.Equal (strings.IndexOf ("$101.00"), current = n.GetNextMatchingItem (current, '1'));
- Assert.Equal ("$101", n.SearchString);
- Assert.Equal (strings.IndexOf ("$101.00"), current = n.GetNextMatchingItem (current, '.'));
- Assert.Equal ("$101.", n.SearchString);
- // stay on the same item becuase still in timedelay
- Assert.Equal (strings.IndexOf ("$101.00"), current = n.GetNextMatchingItem (current, 'a'));
- Assert.Equal ("$101.", n.SearchString);
- Thread.Sleep (n.TypingDelay + 100);
- // another '$' means searching for "$" again
- Assert.Equal (strings.IndexOf ("$101.10"), current = n.GetNextMatchingItem (current, '$'));
- Assert.Equal ("$", n.SearchString);
- Assert.Equal (strings.IndexOf ("$$"), current = n.GetNextMatchingItem (current, '$'));
- Assert.Equal ("$$", n.SearchString);
- }
- [Fact]
- public void Delay ()
- {
- var strings = new string []{
- "$$",
- "$100.00",
- "$101.00",
- "$101.10",
- "$200.00",
- "appricot"
- };
- int current = 0;
- var n = new CollectionNavigator (strings);
- // No delay
- Assert.Equal (strings.IndexOf ("appricot"), current = n.GetNextMatchingItem (current, 'a'));
- Assert.Equal ("a", n.SearchString);
- Assert.Equal (strings.IndexOf ("$$"), current = n.GetNextMatchingItem (current, '$'));
- Assert.Equal ("$", n.SearchString);
- Assert.Equal (strings.IndexOf ("$$"), current = n.GetNextMatchingItem (current, '$'));
- Assert.Equal ("$$", n.SearchString);
- // Delay
- Thread.Sleep (n.TypingDelay + 10);
- Assert.Equal (strings.IndexOf ("appricot"), current = n.GetNextMatchingItem (current, 'a'));
- Assert.Equal ("a", n.SearchString);
- Thread.Sleep (n.TypingDelay + 10);
- Assert.Equal (strings.IndexOf ("$$"), current = n.GetNextMatchingItem (current, '$'));
- Assert.Equal ("$", n.SearchString);
- Thread.Sleep (n.TypingDelay + 10);
- Assert.Equal (strings.IndexOf ("$100.00"), current = n.GetNextMatchingItem (current, '$'));
- Assert.Equal ("$", n.SearchString);
- Thread.Sleep (n.TypingDelay + 10);
- Assert.Equal (strings.IndexOf ("$101.00"), current = n.GetNextMatchingItem (current, '$'));
- Assert.Equal ("$", n.SearchString);
- Thread.Sleep (n.TypingDelay + 10);
- Assert.Equal (strings.IndexOf ("$101.10"), current = n.GetNextMatchingItem (current, '$'));
- Assert.Equal ("$", n.SearchString);
- Thread.Sleep (n.TypingDelay + 10);
- Assert.Equal (strings.IndexOf ("$101.10"), current = n.GetNextMatchingItem (current, '2')); // Shouldn't move
- Assert.Equal ("2", n.SearchString);
- }
- [Fact]
- public void MutliKeySearchPlusWrongKeyStays ()
- {
- var strings = new string []{
- "a",
- "c",
- "can",
- "candle",
- "candy",
- "yellow",
- "zebra"
- };
- int current = 0;
- var n = new CollectionNavigator (strings);
- // https://github.com/gui-cs/Terminal.Gui/pull/2132#issuecomment-1298425573
- // One thing that it currently does that is different from Explorer is that as soon as you hit a wrong key then it jumps to that index.
- // So if you type cand then z it jumps you to something beginning with z. In the same situation Windows Explorer beeps (not the best!)
- // but remains on candle.
- // We might be able to update the behaviour so that a 'wrong' keypress (z) within 500ms of a 'right' keypress ("can" + 'd') is
- // simply ignored (possibly ending the search process though). That would give a short delay for user to realise the thing
- // they typed doesn't exist and then start a new search (which would be possible 500ms after the last 'good' keypress).
- // This would only apply for 2+ character searches where theres been a successful 2+ character match right before.
- Assert.Equal (strings.IndexOf ("a"), current = n.GetNextMatchingItem (current, 'a'));
- Assert.Equal ("a", n.SearchString);
- Assert.Equal (strings.IndexOf ("c"), current = n.GetNextMatchingItem (current, 'c'));
- Assert.Equal ("c", n.SearchString);
- Assert.Equal (strings.IndexOf ("can"), current = n.GetNextMatchingItem (current, 'a'));
- Assert.Equal ("ca", n.SearchString);
- Assert.Equal (strings.IndexOf ("can"), current = n.GetNextMatchingItem (current, 'n'));
- Assert.Equal ("can", n.SearchString);
- Assert.Equal (strings.IndexOf ("candle"), current = n.GetNextMatchingItem (current, 'd'));
- Assert.Equal ("cand", n.SearchString);
- // Same as above, but with a 'wrong' key (z)
- Thread.Sleep (n.TypingDelay + 10);
- Assert.Equal (strings.IndexOf ("a"), current = n.GetNextMatchingItem (current, 'a'));
- Assert.Equal ("a", n.SearchString);
- Assert.Equal (strings.IndexOf ("c"), current = n.GetNextMatchingItem (current, 'c'));
- Assert.Equal ("c", n.SearchString);
- Assert.Equal (strings.IndexOf ("can"), current = n.GetNextMatchingItem (current, 'a'));
- Assert.Equal ("ca", n.SearchString);
- Assert.Equal (strings.IndexOf ("can"), current = n.GetNextMatchingItem (current, 'n'));
- Assert.Equal ("can", n.SearchString);
- Assert.Equal (strings.IndexOf ("can"), current = n.GetNextMatchingItem (current, 'z')); // Shouldn't move
- Assert.Equal ("can", n.SearchString); // Shouldn't change
- }
- [Fact]
- public void MinimizeMovement_False_ShouldMoveIfMultipleMatches ()
- {
- var strings = new string [] {
- "$$",
- "$100.00",
- "$101.00",
- "$101.10",
- "$200.00",
- "appricot",
- "c",
- "car",
- "cart",
- };
- int current = 0;
- var n = new CollectionNavigator (strings);
- Assert.Equal (strings.IndexOf ("$$"), current = n.GetNextMatchingItem (current, "$$", false));
- Assert.Equal (strings.IndexOf ("$100.00"), current = n.GetNextMatchingItem (current, "$", false));
- Assert.Equal (strings.IndexOf ("$$"), current = n.GetNextMatchingItem (current, "$$", false)); // back to top
- Assert.Equal (strings.IndexOf ("$100.00"), current = n.GetNextMatchingItem (current, "$", false));
- Assert.Equal (strings.IndexOf ("$101.00"), current = n.GetNextMatchingItem (current, "$", false));
- Assert.Equal (strings.IndexOf ("$101.10"), current = n.GetNextMatchingItem (current, "$", false));
- Assert.Equal (strings.IndexOf ("$200.00"), current = n.GetNextMatchingItem (current, "$", false));
- Assert.Equal (strings.IndexOf ("$$"), current = n.GetNextMatchingItem (current, "$", false)); // back to top
- Assert.Equal (strings.IndexOf ("appricot"), current = n.GetNextMatchingItem (current, "a", false));
- Assert.Equal (strings.IndexOf ("$$"), current = n.GetNextMatchingItem (current, "$", false)); // back to top
- Assert.Equal (strings.IndexOf ("$100.00"), current = n.GetNextMatchingItem (current, "$100.00", false));
- Assert.Equal (strings.IndexOf ("$101.00"), current = n.GetNextMatchingItem (current, "$", false));
- Assert.Equal (strings.IndexOf ("$101.00"), current = n.GetNextMatchingItem (current, "$101.00", false));
- Assert.Equal (strings.IndexOf ("$200.00"), current = n.GetNextMatchingItem (current, "$2", false));
- Assert.Equal (strings.IndexOf ("$200.00"), current = n.GetNextMatchingItem (current, "$200.00", false));
- Assert.Equal (strings.IndexOf ("$101.00"), current = n.GetNextMatchingItem (current, "$101.00", false));
- Assert.Equal (strings.IndexOf ("$200.00"), current = n.GetNextMatchingItem (current, "$2", false));
- Assert.Equal (strings.IndexOf ("$101.00"), current = n.GetNextMatchingItem (current, "$101.00", false));
- Assert.Equal (strings.IndexOf ("$200.00"), current = n.GetNextMatchingItem (current, "$2", false));
- Assert.Equal (strings.IndexOf ("car"), current = n.GetNextMatchingItem (current, "car", false));
- Assert.Equal (strings.IndexOf ("cart"), current = n.GetNextMatchingItem (current, "car", false));
- Assert.Equal (-1, current = n.GetNextMatchingItem (current, "x", false));
- }
- [Fact]
- public void MinimizeMovement_True_ShouldStayOnCurrentIfMultipleMatches ()
- {
- var strings = new string [] {
- "$$",
- "$100.00",
- "$101.00",
- "$101.10",
- "$200.00",
- "appricot",
- "c",
- "car",
- "cart",
- };
- int current = 0;
- var n = new CollectionNavigator (strings);
- Assert.Equal (strings.IndexOf ("$$"), current = n.GetNextMatchingItem (current, "$$", true));
- Assert.Equal (strings.IndexOf ("$$"), current = n.GetNextMatchingItem (current, "$", true));
- Assert.Equal (strings.IndexOf ("$$"), current = n.GetNextMatchingItem (current, "$$", true)); // back to top
- Assert.Equal (strings.IndexOf ("$100.00"), current = n.GetNextMatchingItem (current, "$1", true));
- Assert.Equal (strings.IndexOf ("$100.00"), current = n.GetNextMatchingItem (current, "$", true));
- Assert.Equal (strings.IndexOf ("$100.00"), current = n.GetNextMatchingItem (current, "$", true));
- Assert.Equal (strings.IndexOf ("car"), current = n.GetNextMatchingItem (current, "car", true));
- Assert.Equal (strings.IndexOf ("car"), current = n.GetNextMatchingItem (current, "car", true));
- Assert.Equal (-1, current = n.GetNextMatchingItem (current, "x", true));
- }
- }
- }
|