public void CommandifiedListSortWithUndoTest() { Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); CommandifiedList <string> toTest = new CommandifiedList <string>() { "aaa", "aab", "aba", "baa" }; // use command to sort the list, so it's undoable. CQManager.EnqueueAndRunCommand(new Command <string>(() => toTest.Sort(SortAlgorithm.ShellSort, SortDirection.Descending))); Assert.AreEqual("baa", toTest[0]); Assert.AreEqual("aba", toTest[1]); Assert.AreEqual("aab", toTest[2]); Assert.AreEqual("aaa", toTest[3]); // undo the sort CQManager.UndoLastCommand(); Assert.AreEqual("aaa", toTest[0]); Assert.AreEqual("aab", toTest[1]); Assert.AreEqual("aba", toTest[2]); Assert.AreEqual("baa", toTest[3]); CQManager.ActivateCommandQueueStack(Guid.Empty); }
public void CommandifiedListClearTest() { Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); CommandifiedList <string> toTest = new CommandifiedList <string>() { "Foo", "Bar", "Blah" }; Assert.AreEqual(3, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); Assert.AreEqual("Blah", toTest[2]); // perform a clear operation. We'll undo this later on. toTest.Clear(); Assert.AreEqual(0, toTest.Count); // undo operation. CQManager.UndoLastCommand(); Assert.AreEqual(3, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); Assert.AreEqual("Blah", toTest[2]); CQManager.ActivateCommandQueueStack(Guid.Empty); }
private void MultiThreadedSyncedCommandifiedListAccessTest_ThreadA(CommandifiedList <string> list, WaitHandle waitHandle, Action <Exception> handler) { Console.WriteLine("Thread A started"); try { var random = new Random((int)DateTime.Now.Ticks); for (int i = 0; i < 500; i++) { //Console.WriteLine("\tThread A: iteration: {0}", i); var countBefore = list.Count; var index = random.Next(0, countBefore); list.RemoveAt(index); Assert.AreEqual(countBefore - 1, list.Count); CQManager.UndoLastCommand(); Assert.AreEqual(countBefore, list.Count); Thread.Sleep(1); CQManager.RedoLastCommand(); Assert.AreEqual(countBefore - 1, list.Count); Thread.Sleep(2); CQManager.UndoLastCommand(); Assert.AreEqual(countBefore, list.Count); } } catch (Exception e) { handler(e); } finally { ((AutoResetEvent)waitHandle).Set(); } Console.WriteLine("Thread A ended"); }
public void MultiThreadedSyncedCommandifiedListAccessTest() { // set up our session. Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); var toTest = new CommandifiedList <string>(isSynchronized: true); for (int i = 0; i < 10; i++) { toTest.Add(i.ToString()); } var waitHandles = new WaitHandle[] { new AutoResetEvent(false), new AutoResetEvent(false) }; Exception caughtException = null; Console.WriteLine("Starting threads..."); var threadA = new Thread(() => MultiThreadedSyncedCommandifiedListAccessTest_ThreadA(toTest, waitHandles[0], (e) => caughtException = e)); var threadB = new Thread(() => MultiThreadedSyncedCommandifiedListAccessTest_ThreadB(toTest, waitHandles[1], (e) => caughtException = e)); threadA.Start(); threadB.Start(); Console.WriteLine("Threads started... waiting for handles"); WaitHandle.WaitAll(waitHandles); if (caughtException != null) { throw caughtException; } Console.WriteLine("All completed."); }
public void CancelableEventsOnCommandifiedListTests() { CommandifiedList <int> list = new CommandifiedList <int>() { 1, 2, 3 }; EventHandler <CancelableListModificationEventArgs <int> > cancelableHandler = delegate(object sender, CancelableListModificationEventArgs <int> e) { e.Cancel = true; }; list.ElementAdding += cancelableHandler; list.ElementRemoving += cancelableHandler; list.ListClearing += cancelableHandler; // reset command queue manager, so it will only undo commands issued after this reset CommandQueueManagerSingleton.GetInstance().ResetActiveCommandQueue(); list.Add(4); Assert.AreEqual(3, list.Count); Assert.IsFalse(list.Contains(4)); // undo shouldn't have any effect CommandQueueManagerSingleton.GetInstance().UndoLastCommand(); Assert.AreEqual(3, list.Count); Assert.IsFalse(list.Contains(4)); list.Clear(); Assert.AreEqual(3, list.Count); // undo shouldn't have any effect CommandQueueManagerSingleton.GetInstance().UndoLastCommand(); Assert.AreEqual(3, list.Count); list.Remove(1); Assert.AreEqual(3, list.Count); Assert.IsTrue(list.Contains(1)); // undo shouldn't have any effect CommandQueueManagerSingleton.GetInstance().UndoLastCommand(); Assert.AreEqual(3, list.Count); Assert.IsTrue(list.Contains(1)); list.ElementAdding -= cancelableHandler; list.ElementRemoving -= cancelableHandler; list.ListClearing -= cancelableHandler; list.Add(4); Assert.AreEqual(4, list.Count); Assert.IsTrue(list.Contains(4)); list.Remove(1); Assert.AreEqual(3, list.Count); Assert.IsFalse(list.Contains(1)); list.Clear(); Assert.AreEqual(0, list.Count); }
private void MultiThreadedSyncedCommandifiedListAccessTest_ThreadB(CommandifiedList <string> list, WaitHandle waitHandle, Action <Exception> handler) { Console.WriteLine("Thread B started"); try { for (int i = 0; i < 500; i++) { //Console.WriteLine("\tThread B: iteration: {0}", i); bool lockTaken = false; object syncRoot = list.SyncRoot; try { if (list.IsSynchronized) { Monitor.Enter(syncRoot); lockTaken = true; } int countBefore = list.Count; int count = 0; foreach (var v in list) { count++; } Assert.AreEqual(countBefore, count, "Count after enumeration differs from initial count of list"); } finally { if (lockTaken) { Monitor.Exit(syncRoot); } } Thread.Sleep(7); } } catch (Exception e) { handler(e); } finally { ((AutoResetEvent)waitHandle).Set(); } Console.WriteLine("Thread B ended"); }
public void CommandifiedListSetItemTest() { Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); CommandifiedList <string> toTest = new CommandifiedList <string>() { "Foo", "Bar" }; Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); // perform a set index operation. We'll undo this later on. toTest[0] = "Blah"; Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Blah", toTest[0]); // undo operation. CQManager.UndoLastCommand(); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); // use a library extension method to swap two items. We want to roll back the swap call completely, so the SwapValues call is seen // as an atomic action. We therefore have to create a command to make it undoable as an atomic action. It doesn't have an undo action, // it relies on the actions it executes by itself to undo. CQManager.EnqueueAndRunCommand(new Command <string>(() => toTest.SwapValues(0, 1))); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Bar", toTest[0]); Assert.AreEqual("Foo", toTest[1]); // undo operation. This is undoing the call to SwapValues, which by undoing that, will undo all the actions SwapValues took, i.e. setting 2 items at // 2 indexes. CQManager.UndoLastCommand(); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); CQManager.ActivateCommandQueueStack(Guid.Empty); }
public void CommandifiedListInsertTest() { Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); CommandifiedList <string> toTest = new CommandifiedList <string>() { "Foo", "Bar" }; Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); // perform an insert operation, this can be triggered by both 'Add' and 'Insert'. We'll undo this later on. toTest.Add("Blah"); Assert.AreEqual(3, toTest.Count); Assert.AreEqual("Blah", toTest[2]); // undo operation. CQManager.UndoLastCommand(); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); toTest.Insert(1, "Blah"); Assert.AreEqual(3, toTest.Count); Assert.AreEqual("Blah", toTest[1]); Assert.AreEqual("Bar", toTest[2]); // undo operation. CQManager.UndoLastCommand(); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); CQManager.ActivateCommandQueueStack(Guid.Empty); }
public void CommandifiedListRemoveTest() { Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); CommandifiedList <string> toTest = new CommandifiedList <string>() { "Foo", "Bar" }; Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); // perform a remove operation. We'll undo this later on. toTest.Remove("Foo"); Assert.AreEqual(1, toTest.Count); Assert.AreEqual("Bar", toTest[0]); // undo operation. CQManager.UndoLastCommand(); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); toTest.RemoveAt(1); Assert.AreEqual(1, toTest.Count); Assert.AreEqual("Foo", toTest[0]); // undo operation. CQManager.UndoLastCommand(); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); CQManager.ActivateCommandQueueStack(Guid.Empty); }
public void MoveItemInCommandifiedListTest() { CommandifiedList <int> list = new CommandifiedList <int> { 1, 2, 3, 4 }; int oldIndexInEvent = -1; int newIndexInEvent = -1; bool eventRaised = false; list.ListChanged += (sender, e) => { eventRaised = true; oldIndexInEvent = e.OldIndex; newIndexInEvent = e.NewIndex; }; // move item at position 0 to position 1 list.MoveElement(0, 1); Assert.IsTrue(eventRaised); Assert.AreEqual(0, oldIndexInEvent); Assert.AreEqual(1, newIndexInEvent); Assert.AreEqual(2, list[0]); Assert.AreEqual(1, list[1]); }
public void CommandifiedListInsertTest() { Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); CommandifiedList<string> toTest = new CommandifiedList<string>() { "Foo", "Bar"}; Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); // perform an insert operation, this can be triggered by both 'Add' and 'Insert'. We'll undo this later on. toTest.Add("Blah"); Assert.AreEqual(3, toTest.Count); Assert.AreEqual("Blah", toTest[2]); // undo operation. CQManager.UndoLastCommand(); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); toTest.Insert(1, "Blah"); Assert.AreEqual(3, toTest.Count); Assert.AreEqual("Blah", toTest[1]); Assert.AreEqual("Bar", toTest[2]); // undo operation. CQManager.UndoLastCommand(); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); CQManager.ActivateCommandQueueStack(Guid.Empty); }
public void CancelableEventsOnCommandifiedListTests() { CommandifiedList<int> list = new CommandifiedList<int>() { 1, 2, 3 }; EventHandler<CancelableListModificationEventArgs<int>> cancelableHandler = delegate(object sender, CancelableListModificationEventArgs<int> e) { e.Cancel = true; }; list.ElementAdding += cancelableHandler; list.ElementRemoving += cancelableHandler; list.ListClearing += cancelableHandler; // reset command queue manager, so it will only undo commands issued after this reset CommandQueueManagerSingleton.GetInstance().ResetActiveCommandQueue(); list.Add(4); Assert.AreEqual(3, list.Count); Assert.IsFalse(list.Contains(4)); // undo shouldn't have any effect CommandQueueManagerSingleton.GetInstance().UndoLastCommand(); Assert.AreEqual(3, list.Count); Assert.IsFalse(list.Contains(4)); list.Clear(); Assert.AreEqual(3, list.Count); // undo shouldn't have any effect CommandQueueManagerSingleton.GetInstance().UndoLastCommand(); Assert.AreEqual(3, list.Count); list.Remove(1); Assert.AreEqual(3, list.Count); Assert.IsTrue(list.Contains(1)); // undo shouldn't have any effect CommandQueueManagerSingleton.GetInstance().UndoLastCommand(); Assert.AreEqual(3, list.Count); Assert.IsTrue(list.Contains(1)); list.ElementAdding -= cancelableHandler; list.ElementRemoving -= cancelableHandler; list.ListClearing -= cancelableHandler; list.Add(4); Assert.AreEqual(4, list.Count); Assert.IsTrue(list.Contains(4)); list.Remove(1); Assert.AreEqual(3, list.Count); Assert.IsFalse(list.Contains(1)); list.Clear(); Assert.AreEqual(0, list.Count); }
public void CommandifiedListRemoveTest() { Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); CommandifiedList<string> toTest = new CommandifiedList<string>() { "Foo", "Bar" }; Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); // perform a remove operation. We'll undo this later on. toTest.Remove("Foo"); Assert.AreEqual(1, toTest.Count); Assert.AreEqual("Bar", toTest[0]); // undo operation. CQManager.UndoLastCommand(); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); toTest.RemoveAt(1); Assert.AreEqual(1, toTest.Count); Assert.AreEqual("Foo", toTest[0]); // undo operation. CQManager.UndoLastCommand(); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); CQManager.ActivateCommandQueueStack(Guid.Empty); }
public void CommandifiedListSetItemTest() { Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); CommandifiedList<string> toTest = new CommandifiedList<string>() { "Foo", "Bar" }; Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); // perform a set index operation. We'll undo this later on. toTest[0] = "Blah"; Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Blah", toTest[0]); // undo operation. CQManager.UndoLastCommand(); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); // use a library extension method to swap two items. We want to roll back the swap call completely, so the SwapValues call is seen // as an atomic action. We therefore have to create a command to make it undoable as an atomic action. It doesn't have an undo action, // it relies on the actions it executes by itself to undo. CQManager.EnqueueAndRunCommand(new Command<string>(() => toTest.SwapValues(0, 1))); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Bar", toTest[0]); Assert.AreEqual("Foo", toTest[1]); // undo operation. This is undoing the call to SwapValues, which by undoing that, will undo all the actions SwapValues took, i.e. setting 2 items at // 2 indexes. CQManager.UndoLastCommand(); Assert.AreEqual(2, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); CQManager.ActivateCommandQueueStack(Guid.Empty); }
public void CommandifiedListSortWithUndoTest() { Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); CommandifiedList<string> toTest = new CommandifiedList<string>() { "aaa", "aab", "aba", "baa" }; // use command to sort the list, so it's undoable. CQManager.EnqueueAndRunCommand(new Command<string>(() => toTest.Sort(SortAlgorithm.ShellSort, SortDirection.Descending))); Assert.AreEqual("baa", toTest[0]); Assert.AreEqual("aba", toTest[1]); Assert.AreEqual("aab", toTest[2]); Assert.AreEqual("aaa", toTest[3]); // undo the sort CQManager.UndoLastCommand(); Assert.AreEqual("aaa", toTest[0]); Assert.AreEqual("aab", toTest[1]); Assert.AreEqual("aba", toTest[2]); Assert.AreEqual("baa", toTest[3]); CQManager.ActivateCommandQueueStack(Guid.Empty); }
public void MoveItemInCommandifiedListTest() { CommandifiedList<int> list = new CommandifiedList<int> { 1, 2, 3, 4 }; int oldIndexInEvent = -1; int newIndexInEvent = -1; bool eventRaised = false; list.ListChanged += (sender, e) => { eventRaised = true; oldIndexInEvent = e.OldIndex; newIndexInEvent = e.NewIndex; }; // move item at position 0 to position 1 list.MoveElement(0, 1); Assert.IsTrue(eventRaised); Assert.AreEqual(0, oldIndexInEvent); Assert.AreEqual(1, newIndexInEvent); Assert.AreEqual(2, list[0]); Assert.AreEqual(1, list[1]); }
public void CommandifiedListClearTest() { Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); CommandifiedList<string> toTest = new CommandifiedList<string>() { "Foo", "Bar", "Blah" }; Assert.AreEqual(3, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); Assert.AreEqual("Blah", toTest[2]); // perform a clear operation. We'll undo this later on. toTest.Clear(); Assert.AreEqual(0, toTest.Count); // undo operation. CQManager.UndoLastCommand(); Assert.AreEqual(3, toTest.Count); Assert.AreEqual("Foo", toTest[0]); Assert.AreEqual("Bar", toTest[1]); Assert.AreEqual("Blah", toTest[2]); CQManager.ActivateCommandQueueStack(Guid.Empty); }