Browse Source

integrated tznind's stuff

Tig Kindel 2 years ago
parent
commit
18ec9a2a70

+ 41 - 41
Terminal.Gui/Core/Command.cs

@@ -10,54 +10,54 @@ namespace Terminal.Gui {
 	public enum Command {
 
 		/// <summary>
-		/// Moves the caret down one line.
+		/// Moves down one item (cell, line, etc...).
 		/// </summary>
 		LineDown,
 
 		/// <summary>
-		/// Extends the selection down one line.
+		/// Extends the selection down one (cell, line, etc...).
 		/// </summary>
 		LineDownExtend,
 
 		/// <summary>
-		/// Moves the caret down to the last child node of the branch that holds the current selection
+		/// Moves down to the last child node of the branch that holds the current selection.
 		/// </summary>
 		LineDownToLastBranch,
 
 		/// <summary>
-		/// Scrolls down one line (without changing the selection).
+		/// Scrolls down one (cell, line, etc...) (without changing the selection).
 		/// </summary>
 		ScrollDown,
 
 		// --------------------------------------------------------------------
 
 		/// <summary>
-		/// Moves the caret up one line.
+		/// Moves up one (cell, line, etc...).
 		/// </summary>
 		LineUp,
 
 		/// <summary>
-		/// Extends the selection up one line.
+		/// Extends the selection up one item (cell, line, etc...).
 		/// </summary>
 		LineUpExtend,
 
 		/// <summary>
-		/// Moves the caret up to the first child node of the branch that holds the current selection
+		/// Moves up to the first child node of the branch that holds the current selection.
 		/// </summary>
 		LineUpToFirstBranch,
 
 		/// <summary>
-		/// Scrolls up one line (without changing the selection).
+		/// Scrolls up one item (cell, line, etc...) (without changing the selection).
 		/// </summary>
 		ScrollUp,
 
 		/// <summary>
-		/// Moves the selection left one by the minimum increment supported by the view e.g. single character, cell, item etc.
+		/// Moves the selection left one by the minimum increment supported by the <see cref="View"/> e.g. single character, cell, item etc.
 		/// </summary>
 		Left,
 
 		/// <summary>
-		/// Scrolls one character to the left
+		/// Scrolls one item (cell, character, etc...) to the left
 		/// </summary>
 		ScrollLeft,
 
@@ -72,7 +72,7 @@ namespace Terminal.Gui {
 		Right,
 
 		/// <summary>
-		/// Scrolls one character to the right.
+		/// Scrolls one item (cell, character, etc...) to the right.
 		/// </summary>
 		ScrollRight,
 
@@ -102,12 +102,12 @@ namespace Terminal.Gui {
 		WordRightExtend,
 
 		/// <summary>
-		/// Deletes and copies to the clipboard the characters from the current position to the end of the line.
+		/// Cuts to the clipboard the characters from the current position to the end of the line.
 		/// </summary>
 		CutToEndLine,
 
 		/// <summary>
-		/// Deletes and copies to the clipboard the characters from the current position to the start of the line.
+		/// Cuts to the clipboard the characters from the current position to the start of the line.
 		/// </summary>
 		CutToStartLine,
 
@@ -140,47 +140,47 @@ namespace Terminal.Gui {
 		DisableOverwrite,
 
 		/// <summary>
-		/// Move the page down.
+		/// Move one page down.
 		/// </summary>
 		PageDown,
 
 		/// <summary>
-		/// Move the page down increase selection area to cover revealed objects/characters.
+		/// Move one page page extending the selection to cover revealed objects/characters.
 		/// </summary>
 		PageDownExtend,
 
 		/// <summary>
-		/// Move the page up.
+		/// Move one page up.
 		/// </summary>
 		PageUp,
 
 		/// <summary>
-		/// Move the page up increase selection area to cover revealed objects/characters.
+		/// Move one page up extending the selection to cover revealed objects/characters.
 		/// </summary>
 		PageUpExtend,
 
 		/// <summary>
-		/// Moves to top begin.
+		/// Moves to the top/home.
 		/// </summary>
 		TopHome,
 
 		/// <summary>
-		/// Extends the selection to the top begin.
+		/// Extends the selection to the top/home.
 		/// </summary>
 		TopHomeExtend,
 
 		/// <summary>
-		/// Moves to bottom end.
+		/// Moves to the bottom/end.
 		/// </summary>
 		BottomEnd,
 
 		/// <summary>
-		/// Extends the selection to the bottom end.
+		/// Extends the selection to the bottom/end.
 		/// </summary>
 		BottomEndExtend,
 
 		/// <summary>
-		/// Open selected item.
+		/// Open the selected item.
 		/// </summary>
 		OpenSelectedItem,
 
@@ -190,43 +190,43 @@ namespace Terminal.Gui {
 		ToggleChecked,
 
 		/// <summary>
-		/// Accepts the current state (e.g. selection, button press etc)
+		/// Accepts the current state (e.g. selection, button press etc).
 		/// </summary>
 		Accept,
 
 		/// <summary>
-		/// Toggles the Expanded or collapsed state of a a list or item (with subitems)
+		/// Toggles the Expanded or collapsed state of a a list or item (with subitems).
 		/// </summary>
 		ToggleExpandCollapse,
 
 		/// <summary>
-		/// Expands a list or item (with subitems)
+		/// Expands a list or item (with subitems).
 		/// </summary>
 		Expand,
 
 		/// <summary>
-		/// Recursively Expands all child items and their child items (if any)
+		/// Recursively Expands all child items and their child items (if any).
 		/// </summary>
 		ExpandAll,
 
 		/// <summary>
-		/// Collapses a list or item (with subitems)
+		/// Collapses a list or item (with subitems).
 		/// </summary>
 		Collapse,
 
 		/// <summary>
-		/// Recursively collapses a list items of their children (if any)
+		/// Recursively collapses a list items of their children (if any).
 		/// </summary>
 		CollapseAll,
 
 		/// <summary>
-		/// Cancels any current temporary states on the control e.g. expanding
-		/// a combo list
+		/// Cancels an action or any temporary states on the control e.g. expanding
+		/// a combo list.
 		/// </summary>
 		Cancel,
 
 		/// <summary>
-		/// Unix emulation
+		/// Unix emulation.
 		/// </summary>
 		UnixEmulation,
 
@@ -241,12 +241,12 @@ namespace Terminal.Gui {
 		DeleteCharLeft,
 
 		/// <summary>
-		/// Selects all objects in the control.
+		/// Selects all objects.
 		/// </summary>
 		SelectAll,
 
 		/// <summary>
-		/// Deletes all objects in the control.
+		/// Deletes all objects.
 		/// </summary>
 		DeleteAll,
 
@@ -336,7 +336,7 @@ namespace Terminal.Gui {
 		Paste,
 
 		/// <summary>
-		/// Quit a toplevel.
+		/// Quit a <see cref="Toplevel"/>.
 		/// </summary>
 		QuitToplevel,
 
@@ -356,37 +356,37 @@ namespace Terminal.Gui {
 		PreviousView,
 
 		/// <summary>
-		/// Moves focus to the next view or toplevel (case of Mdi).
+		/// Moves focus to the next view or toplevel (case of MDI).
 		/// </summary>
 		NextViewOrTop,
 
 		/// <summary>
-		/// Moves focus to the next previous or toplevel (case of Mdi).
+		/// Moves focus to the next previous or toplevel (case of MDI).
 		/// </summary>
 		PreviousViewOrTop,
 
 		/// <summary>
-		/// Refresh the application.
+		/// Refresh.
 		/// </summary>
 		Refresh,
 
 		/// <summary>
-		/// Toggles the extended selection.
+		/// Toggles the selection.
 		/// </summary>
 		ToggleExtend,
 
 		/// <summary>
-		/// Inserts a new line.
+		/// Inserts a new item.
 		/// </summary>
 		NewLine,
 
 		/// <summary>
-		/// Inserts a tab.
+		/// Tabs to the next item.
 		/// </summary>
 		Tab,
 
 		/// <summary>
-		/// Inserts a shift tab.
+		/// Tabs back to the previous item.
 		/// </summary>
 		BackTab
 	}

+ 16 - 4
Terminal.Gui/Core/SearchCollectionNavigator.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.Linq;
 
 namespace Terminal.Gui {
@@ -11,11 +12,17 @@ namespace Terminal.Gui {
 		DateTime lastKeystroke = DateTime.MinValue;
 		const int TypingDelay = 250;
 		public StringComparer Comparer { get; set; } = StringComparer.InvariantCultureIgnoreCase;
+		private IEnumerable<string> Collection { get => _collection; set => _collection = value; }
 
-		public int CalculateNewIndex (string [] collection, int currentIndex, char keyStruck)
+		private IEnumerable<string> _collection;
+
+		public SearchCollectionNavigator (IEnumerable<string> collection) { _collection = collection; }
+
+
+		public int CalculateNewIndex (IEnumerable<string> collection, int currentIndex, char keyStruck)
 		{
-			// if user presses a letter key
-			if (char.IsLetterOrDigit (keyStruck) || char.IsPunctuation (keyStruck)) {
+			// if user presses a key
+			if (true) {//char.IsLetterOrDigit (keyStruck) || char.IsPunctuation (keyStruck) || char.IsSymbol(keyStruck)) {
 
 				// maybe user pressed 'd' and now presses 'd' again.
 				// a candidate search is things that begin with "dd"
@@ -73,7 +80,12 @@ namespace Terminal.Gui {
 			}
 		}
 
-		private int GetNextIndexMatching (string [] collection, int currentIndex, string search, bool preferNotToMoveToNewIndexes = false)
+		public int CalculateNewIndex (int currentIndex, char keyStruck)
+		{
+			return CalculateNewIndex (Collection, currentIndex, keyStruck);
+		}
+
+		private int GetNextIndexMatching (IEnumerable<string> collection, int currentIndex, string search, bool preferNotToMoveToNewIndexes = false)
 		{
 			if (string.IsNullOrEmpty (search)) {
 				return -1;

+ 20 - 24
Terminal.Gui/Views/ListView.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using NStack;
@@ -179,6 +180,12 @@ namespace Terminal.Gui {
 			get => allowsMarking;
 			set {
 				allowsMarking = value;
+				if (allowsMarking) {
+					AddKeyBinding (Key.Space, Command.ToggleChecked);
+				} else {
+					ClearKeybinding (Key.Space);
+				}
+
 				SetNeedsDisplay ();
 			}
 		}
@@ -353,8 +360,6 @@ namespace Terminal.Gui {
 			AddKeyBinding (Key.End, Command.BottomEnd);
 
 			AddKeyBinding (Key.Enter, Command.OpenSelectedItem);
-
-			AddKeyBinding (Key.Space, Command.ToggleChecked);
 		}
 
 		///<inheritdoc/>
@@ -416,39 +421,30 @@ namespace Terminal.Gui {
 		/// </summary>
 		public event Action<ListViewRowEventArgs> RowRender;
 
-		private string search { get; set; }
+		private SearchCollectionNavigator navigator;
 
 		///<inheritdoc/>
 		public override bool ProcessKey (KeyEvent kb)
 		{
-			if (source == null)
+			if (source == null) {
 				return base.ProcessKey (kb);
+			}
 
 			var result = InvokeKeybindings (kb);
-			if (result != null)
+			if (result != null) {
 				return (bool)result;
+			}
 
 			// Enable user to find & select an item by typing text
-			if (source is IListDataSourceSearchable && 
-				!(kb.IsCapslock && kb.IsCtrl && kb.IsAlt && kb.IsScrolllock && kb.IsNumlock && kb.IsCapslock)) {
-				if (kb.KeyValue >= 32 && kb.KeyValue < 127) {
-					if (searchTimer == null) {
-						searchTimer = new System.Timers.Timer (500);
-						searchTimer.Elapsed += (o, e) => {
-							searchTimer.Stop ();
-							searchTimer = null;
-							search = "";
-						};
-						searchTimer.Start ();
-					}
-					search += (char)kb.KeyValue;
-					var found = ((IListDataSourceSearchable)source).StartsWith (search);
-					if (found != -1) {
-						SelectedItem = found;
-						SetNeedsDisplay ();
-					}
-					return true;
+			if (!kb.IsAlt && !kb.IsCapslock && !kb.IsCtrl && !kb.IsScrolllock && !kb.IsNumlock) {
+				if (navigator == null) {
+					// BUGBUG: If items change this needs to be recreated.
+					navigator = new SearchCollectionNavigator (source.ToList().Cast<string>());
 				}
+				SelectedItem = navigator.CalculateNewIndex (SelectedItem, (char)kb.KeyValue);
+				EnsuresVisibilitySelectedItem ();
+				SetNeedsDisplay ();
+				return true;
 			}
 
 			return false;

+ 4 - 0
UICatalog/Properties/launchSettings.json

@@ -26,6 +26,10 @@
     "Issue1719Repro": {
       "commandName": "Project",
       "commandLineArgs": "\"ProgressBar Styles\""
+    },
+    "SearchCollectionNavTester": {
+      "commandName": "Project",
+      "commandLineArgs": "\"Search Collection Nav\""
     }
   }
 }

+ 218 - 0
UICatalog/Scenarios/SearchCollectionNavigatorTester.cs

@@ -0,0 +1,218 @@
+using System;
+using System.IO;
+using System.Linq;
+using Terminal.Gui;
+using Terminal.Gui.Trees;
+
+namespace UICatalog.Scenarios {
+
+	[ScenarioMetadata (Name: "Search Collection Nav", Description: "Demonstrates & tests SearchCollectionNavigator.")]
+	[ScenarioCategory ("Controls"), ScenarioCategory ("ListView")]
+	public class SearchCollectionNavigatorTester : Scenario {
+		TabView tabView;
+
+		private int numbeOfNewTabs = 1;
+
+		// Don't create a Window, just return the top-level view
+		public override void Init (Toplevel top, ColorScheme colorScheme)
+		{
+			Application.Init ();
+			Top = top != null ? top : Application.Top;
+			Top.ColorScheme = Colors.Base;
+		}
+
+		public override void Setup ()
+		{
+			var allowMarking = new MenuItem ("Allow _Marking", "", null) {
+				CheckType = MenuItemCheckStyle.Checked,
+				Checked = false
+			};
+			allowMarking.Action = () => allowMarking.Checked = _listView.AllowsMarking = !_listView.AllowsMarking;
+
+			var allowMultiSelection = new MenuItem ("Allow Multi _Selection", "", null) {
+				CheckType = MenuItemCheckStyle.Checked,
+				Checked = false
+			};
+			allowMultiSelection.Action = () => allowMultiSelection.Checked = _listView.AllowsMultipleSelection = !_listView.AllowsMultipleSelection;
+			allowMultiSelection.CanExecute = () => allowMarking.Checked;
+
+			var menu = new MenuBar (new MenuBarItem [] {
+				new MenuBarItem ("_Configure", new MenuItem [] {
+					allowMarking,
+					allowMultiSelection,
+					null,
+					new MenuItem ("_Quit", "", () => Quit(), null, null, Key.Q | Key.CtrlMask),
+				}),
+				new MenuBarItem("_Quit", "CTRL-Q", () => Quit())
+			});
+
+			Top.Add (menu);
+
+			CreateListView ();
+			var vsep = new LineView (Terminal.Gui.Graphs.Orientation.Vertical) {
+				X = Pos.Right (_listView),
+				Y = 1,
+				Height = Dim.Fill ()
+			};
+			Top.Add (vsep);
+
+		}
+
+		ListView _listView = null;
+
+		private void CreateListView ()
+		{
+			var label = new Label () {
+				Text = "ListView",
+				TextAlignment = TextAlignment.Centered,
+				X = 0,
+				Y = 1, // for menu
+				Width = Dim.Percent (50),
+				Height = 1,
+			};
+			Top.Add (label);
+
+			_listView = new ListView () {
+				X = 0,
+				Y = Pos.Bottom(label), 
+				Width = Dim.Percent (50) - 1,
+				Height = Dim.Fill (),
+				AllowsMarking = false,
+				AllowsMultipleSelection = false,
+				ColorScheme = Colors.TopLevel
+			};
+			Top.Add (_listView);
+
+			System.Collections.Generic.List<string> items = new string [] {
+				"a",
+				"b",
+				"bb",
+				"c",
+				"ccc",
+				"ccc",
+				"cccc",
+				"ddd",
+				"dddd",
+				"dddd",
+				"ddddd",
+				"dddddd",
+				"ddddddd",
+				"this",
+				"this is a test",
+				"this was a test",
+				"this and",
+				"that and that",
+				"the",
+				"think",
+				"thunk",
+				"thunks",
+				"zip",
+				"zap",
+				"zoo",
+				"@jack",
+				"@sign",
+				"@at",
+				"@ateme",
+				"n@",
+				"n@brown",
+				".net",
+				"$100.00",
+				"$101.00",
+				"$101.10",
+				"$101.11",
+				"appricot",
+				"arm",
+				"丗丙业丞",
+				"丗丙丛",
+				"text",
+				"egg",
+				"candle",
+				" <- space",
+				"q",
+				"quit",
+				"quitter"
+			}.ToList<string> ();
+			items.Sort (StringComparer.OrdinalIgnoreCase);
+			_listView.SetSource (items);
+		}
+
+		TreeView<string> _treeView = null;
+
+		private void CreateTreeView ()
+		{
+			var label = new Label () {
+				Text = "TreeView",
+				TextAlignment = TextAlignment.Centered,
+				X = Pos.Right(_listView) + 2,
+				Y = 1, // for menu
+				Width = Dim.Percent (50),
+				Height = 1,
+			};
+			Top.Add (label);
+
+			_treeView = new TreeView<string> () {
+				X = Pos.Right (_listView) + 2,
+				Y = Pos.Bottom (label),
+				Width = Dim.Percent (50) - 1,
+				Height = Dim.Fill (),
+				ColorScheme = Colors.TopLevel
+			};
+			Top.Add (_treeView);
+
+			System.Collections.Generic.List<string> items = new string [] {                         "a",
+				"b",
+				"bb",
+				"c",
+				"ccc",
+				"ccc",
+				"cccc",
+				"ddd",
+				"dddd",
+				"dddd",
+				"ddddd",
+				"dddddd",
+				"ddddddd",
+				"this",
+				"this is a test",
+				"this was a test",
+				"this and",
+				"that and that",
+				"the",
+				"think",
+				"thunk",
+				"thunks",
+				"zip",
+				"zap",
+				"zoo",
+				"@jack",
+				"@sign",
+				"@at",
+				"@ateme",
+				"n@",
+				"n@brown",
+				".net",
+				"$100.00",
+				"$101.00",
+				"$101.10",
+				"$101.11",
+				"appricot",
+				"arm",
+				"丗丙业丞",
+				"丗丙丛",
+				"text",
+				"egg",
+				"candle",
+				" <- space",
+				"q",
+				"quit",
+				"quitter"
+			}.ToList<string> ();
+			items.Sort (StringComparer.OrdinalIgnoreCase);
+			_treeView.AddObjects (items);
+		}
+		private void Quit ()
+		{
+			Application.RequestStop ();
+		}
+	}
+}

+ 28 - 28
UnitTests/SearchCollectionNavigatorTests.cs

@@ -1,13 +1,13 @@
 using Terminal.Gui;
 using Xunit;
 
-namespace UnitTests {
+namespace Terminal.Gui.Core {
 	public class SearchCollectionNavigatorTests {
 
 		[Fact]
 		public void TestSearchCollectionNavigator_Cycling ()
 		{
-			var s = new string []{
+			var strings = new string []{
     "appricot",
     "arm",
     "bat",
@@ -15,12 +15,12 @@ namespace UnitTests {
     "candle"
   };
 
-			var n = new SearchCollectionNavigator ();
-			Assert.Equal (2, n.CalculateNewIndex (s, 0, 'b'));
-			Assert.Equal (3, n.CalculateNewIndex (s, 2, 'b'));
+			var n = new SearchCollectionNavigator (strings);
+			Assert.Equal (2, n.CalculateNewIndex ( 0, 'b'));
+			Assert.Equal (3, n.CalculateNewIndex ( 2, 'b'));
 
 			// if 4 (candle) is selected it should loop back to bat
-			Assert.Equal (2, n.CalculateNewIndex (s, 4, 'b'));
+			Assert.Equal (2, n.CalculateNewIndex ( 4, 'b'));
 
 		}
 
@@ -28,7 +28,7 @@ namespace UnitTests {
 		[Fact]
 		public void TestSearchCollectionNavigator_ToSearchText ()
 		{
-			var s = new string []{
+			var strings = new string []{
     "appricot",
     "arm",
     "bat",
@@ -37,19 +37,19 @@ namespace UnitTests {
     "candle"
   };
 
-			var n = new SearchCollectionNavigator ();
-			Assert.Equal (2, n.CalculateNewIndex (s, 0, 'b'));
-			Assert.Equal (4, n.CalculateNewIndex (s, 2, 'b'));
+			var n = new SearchCollectionNavigator (strings);
+			Assert.Equal (2, n.CalculateNewIndex (0, 'b'));
+			Assert.Equal (4, n.CalculateNewIndex (2, 'b'));
 
 			// another 'b' means searching for "bbb" which does not exist
 			// so we go back to looking for "b" as a fresh key strike
-			Assert.Equal (4, n.CalculateNewIndex (s, 2, 'b'));
+			Assert.Equal (4, n.CalculateNewIndex (2, 'b'));
 		}
 
 		[Fact]
 		public void TestSearchCollectionNavigator_FullText ()
 		{
-			var s = new string []{
+			var strings = new string []{
     "appricot",
     "arm",
     "ta",
@@ -59,23 +59,23 @@ namespace UnitTests {
     "candle"
   };
 
-			var n = new SearchCollectionNavigator ();
-			Assert.Equal (2, n.CalculateNewIndex (s, 0, 't'));
+			var n = new SearchCollectionNavigator (strings);
+			Assert.Equal (2, n.CalculateNewIndex (0, 't'));
 
 			// should match "te" in "text"
-			Assert.Equal (4, n.CalculateNewIndex (s, 2, 'e'));
+			Assert.Equal (4, n.CalculateNewIndex (2, 'e'));
 
 			// still matches text
-			Assert.Equal (4, n.CalculateNewIndex (s, 4, 'x'));
+			Assert.Equal (4, n.CalculateNewIndex (4, 'x'));
 
 			// nothing starts texa so it jumps to a for appricot
-			Assert.Equal (0, n.CalculateNewIndex (s, 4, 'a'));
+			Assert.Equal (0, n.CalculateNewIndex (4, 'a'));
 		}
 
 		[Fact]
 		public void TestSearchCollectionNavigator_Unicode ()
 		{
-			var s = new string []{
+			var strings = new string []{
     "appricot",
     "arm",
     "ta",
@@ -86,27 +86,27 @@ namespace UnitTests {
     "candle"
   };
 
-			var n = new SearchCollectionNavigator ();
-			Assert.Equal (3, n.CalculateNewIndex (s, 0, '丗'));
+			var n = new SearchCollectionNavigator (strings);
+			Assert.Equal (3, n.CalculateNewIndex (0, '丗'));
 
 			// 丗丙业丞 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 (3, n.CalculateNewIndex (s, 3, '丙'));
+			Assert.Equal (3, n.CalculateNewIndex (3, '丙'));
 
 			// No longer matches 丗丙业丞 and now only matches 丗丙丛
 			// so we should move to the new match
-			Assert.Equal (4, n.CalculateNewIndex (s, 3, '丛'));
+			Assert.Equal (4, n.CalculateNewIndex (3, '丛'));
 
 			// nothing starts "丗丙丛a" so it jumps to a for appricot
-			Assert.Equal (0, n.CalculateNewIndex (s, 4, 'a'));
+			Assert.Equal (0, n.CalculateNewIndex (4, 'a'));
 		}
 
 		[Fact]
 		public void TestSearchCollectionNavigator_AtSymbol ()
 		{
-			var s = new string []{
+			var strings = new string []{
     "appricot",
     "arm",
     "ta",
@@ -117,10 +117,10 @@ namespace UnitTests {
     "candle"
   };
 
-			var n = new SearchCollectionNavigator ();
-			Assert.Equal (3, n.CalculateNewIndex (s, 0, '@'));
-			Assert.Equal (3, n.CalculateNewIndex (s, 3, 'b'));
-			Assert.Equal (4, n.CalculateNewIndex (s, 3, 'b'));
+			var n = new SearchCollectionNavigator (strings);
+			Assert.Equal (3, n.CalculateNewIndex (0, '@'));
+			Assert.Equal (3, n.CalculateNewIndex (3, 'b'));
+			Assert.Equal (4, n.CalculateNewIndex (3, 'b'));
 		}
 	}
 }