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); }
public void MultipleUndoOfSingleCommandLevelTest() { // set up our session. Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); HelperClass h = new HelperClass(); h.Name = "Foo"; Assert.AreEqual("Foo", h.Name); h.Name = "Bar"; Assert.AreEqual("Bar", h.Name); CQManager.UndoLastCommand(); Assert.AreEqual("Foo", h.Name); CQManager.UndoLastCommand(); Assert.AreEqual(string.Empty, h.Name); // we're now back at the beginstate, with the exception that the queue is currently filled with undone commands. // these have to be overwritten with the new ones. h.Name = "Foo"; Assert.AreEqual("Foo", h.Name); h.Name = "Bar"; Assert.AreEqual("Bar", h.Name); CQManager.UndoLastCommand(); Assert.AreEqual("Foo", h.Name); CQManager.UndoLastCommand(); Assert.AreEqual(string.Empty, h.Name); 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 SingleUndoOfMultiCommandLevelTest() { // set up our session. Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); HelperClass h = new HelperClass(); // set the property through a command. As the property name change also spawns a command, it will create a 2-level command set. // it doesn't use an undo function, as it doesn't change state itself, that's delegated to another command. Typically one wouldn't do it this way, // as this would assume knowledge of how e.Name's setter works, however for the test it's ok. Command <string> nameSetter = new Command <string>(() => h.Name = "Foo"); CQManager.EnqueueAndRunCommand(nameSetter); Assert.AreEqual("Foo", h.Name); CQManager.UndoLastCommand(); Assert.AreEqual(string.Empty, h.Name); // equal to the test above, but now with an undo function. The undo function will try to undo the state as well. e.Name therefore has to check // whether the value is different, otherwise the undo call will spawn a new command nameSetter = new Command <string>(() => h.Name = "Foo", () => h.Name, v => h.Name = v); CQManager.EnqueueAndRunCommand(nameSetter); Assert.AreEqual("Foo", h.Name); CQManager.UndoLastCommand(); Assert.AreEqual(string.Empty, h.Name); 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"); }
private void MultiThreadedSyncedGraphAccessTest_ThreadA(DirectedGraph <int, DirectedEdge <int> > graph, WaitHandle waitHandle, Action <Exception> handler) { Console.WriteLine("Thread A started"); try { for (int i = 0; i < 100; i++) { var vertexCountBefore = graph.VertexCount; var index = _random.Next(0, vertexCountBefore); graph.Remove(index); Assert.AreEqual(vertexCountBefore - 1, graph.VertexCount); CQManager.UndoLastCommand(); Assert.AreEqual(vertexCountBefore, graph.VertexCount); Thread.Sleep(1); CQManager.RedoLastCommand(); Assert.AreEqual(vertexCountBefore - 1, graph.VertexCount); Thread.Sleep(2); CQManager.UndoLastCommand(); Assert.AreEqual(vertexCountBefore, graph.VertexCount); } } catch (Exception e) { handler(e); } finally { ((AutoResetEvent)waitHandle).Set(); } Console.WriteLine("Thread A ended"); }
public void SingleUndoOfSingleCommandLevelTest() { // set up our session. Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); HelperClass h = new HelperClass(); string name = "Foo"; h.Name = name; Assert.AreEqual(name, h.Name); CQManager.UndoLastCommand(); Assert.AreEqual(string.Empty, h.Name); 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 MultiUndoRedoOfMultiCommandLevelWithBeforeAfterActionCallsTest() { // set up our session. Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); HelperClass h = new HelperClass(); int beforeDoCounter = 0; int afterDoCounter = 0; int beforeUndoCounter = 0; int afterUndoCounter = 0; // set the property through a command. As the property name change also spawns a command, it will create a 2-level command set. // it doesn't use an undo function, as it doesn't change state itself, that's delegated to another command. Typically one wouldn't do it this way, // as this would assume knowledge of how e.Name's setter works, however for the test it's ok. Command <string> nameSetter = new Command <string>(() => h.Name = "Foo") { AfterDoAction = () => afterDoCounter++, AfterUndoAction = () => afterUndoCounter++, BeforeDoAction = () => beforeDoCounter++, BeforeUndoAction = () => beforeUndoCounter++ }; CQManager.EnqueueAndRunCommand(nameSetter); Assert.AreEqual("Foo", h.Name); CQManager.UndoLastCommand(); Assert.AreEqual(string.Empty, h.Name); CQManager.RedoLastCommand(); CQManager.UndoLastCommand(); CQManager.RedoLastCommand(); CQManager.UndoLastCommand(); // we called do 3 times, and undo also 3 times Assert.AreEqual(3, beforeDoCounter); Assert.AreEqual(3, beforeUndoCounter); Assert.AreEqual(3, afterDoCounter); Assert.AreEqual(3, afterUndoCounter); CQManager.ActivateCommandQueueStack(Guid.Empty); }
public void CommandifiedGraphAddRemoveVertexWithUndoTest() { Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); DirectedGraph <int, DirectedEdge <int> > graph = new DirectedGraph <int, DirectedEdge <int> >(true); graph.Add(42); Assert.IsTrue(graph.Contains(42)); CQManager.UndoLastCommand(); Assert.IsFalse(graph.Contains(42)); Assert.AreEqual(0, graph.VertexCount); graph.Add(42); graph.Add(13); graph.Add(10); Assert.IsTrue(graph.Contains(42)); Assert.IsTrue(graph.Contains(13)); Assert.IsTrue(graph.Contains(10)); graph.Add(new DirectedEdge <int>(42, 13)); // 42 -> 13 graph.Add(new DirectedEdge <int>(42, 10)); // 42 -> 10 Assert.AreEqual(2, graph.EdgeCount); Assert.IsTrue(graph.ContainsEdge(42, 13)); Assert.IsTrue(graph.ContainsEdge(42, 10)); graph.Remove(42); Assert.IsFalse(graph.Contains(42)); Assert.AreEqual(0, graph.EdgeCount); Assert.AreEqual(2, graph.VertexCount); // undo removal of 42. This should re-add 42, but also re-add the edges CQManager.UndoLastCommand(); Assert.AreEqual(2, graph.EdgeCount); Assert.IsTrue(graph.ContainsEdge(42, 13)); Assert.IsTrue(graph.ContainsEdge(42, 10)); Assert.IsTrue(graph.Contains(42)); 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 CommandifiedGraphAddRemoveGraphAndEdgesWithUndoTest() { Guid sessionId = Guid.NewGuid(); CQManager.ActivateCommandQueueStack(sessionId); DirectedGraph <int, DirectedEdge <int> > graph = new DirectedGraph <int, DirectedEdge <int> >(true); graph.Add(42); graph.Add(13); graph.Add(10); graph.Add(new DirectedEdge <int>(42, 13)); // 42 -> 13 graph.Add(new DirectedEdge <int>(42, 10)); // 42 -> 10 Assert.IsTrue(graph.Contains(42)); Assert.IsTrue(graph.Contains(13)); Assert.IsTrue(graph.Contains(10)); Assert.AreEqual(2, graph.EdgeCount); Assert.IsTrue(graph.ContainsEdge(42, 13)); Assert.IsTrue(graph.ContainsEdge(42, 10)); // create graph to add to this graph. Doesn't have to be a commandified graph, as we're not rolling back the actions on that graph. DirectedGraph <int, DirectedEdge <int> > graphToAdd = new DirectedGraph <int, DirectedEdge <int> >(); graphToAdd.Add(1); graphToAdd.Add(2); graphToAdd.Add(3); graphToAdd.Add(new DirectedEdge <int>(1, 2)); // 1 -> 2 graphToAdd.Add(new DirectedEdge <int>(1, 3)); // 1 -> 3 graphToAdd.Add(new DirectedEdge <int>(2, 3)); // 2 -> 3 Assert.AreEqual(3, graphToAdd.VertexCount); Assert.AreEqual(3, graphToAdd.EdgeCount); // add this graph to the main graph. This is an undoable action. graph.Add(graphToAdd); Assert.AreEqual(6, graph.VertexCount); Assert.AreEqual(5, graph.EdgeCount); Assert.IsTrue(graph.Contains(1)); Assert.IsTrue(graph.Contains(2)); Assert.IsTrue(graph.Contains(3)); Assert.IsTrue(graph.ContainsEdge(1, 2)); Assert.IsTrue(graph.ContainsEdge(1, 3)); Assert.IsTrue(graph.ContainsEdge(2, 3)); // undo add CQManager.UndoLastCommand(); Assert.AreEqual(3, graph.VertexCount); Assert.AreEqual(2, graph.EdgeCount); Assert.IsFalse(graph.Contains(1)); Assert.IsFalse(graph.Contains(2)); Assert.IsFalse(graph.Contains(3)); Assert.IsFalse(graph.ContainsEdge(1, 2)); Assert.IsFalse(graph.ContainsEdge(1, 3)); Assert.IsFalse(graph.ContainsEdge(2, 3)); // redo CQManager.RedoLastCommand(); Assert.AreEqual(6, graph.VertexCount); Assert.AreEqual(5, graph.EdgeCount); Assert.IsTrue(graph.Contains(1)); Assert.IsTrue(graph.Contains(2)); Assert.IsTrue(graph.Contains(3)); Assert.IsTrue(graph.ContainsEdge(1, 2)); Assert.IsTrue(graph.ContainsEdge(1, 3)); Assert.IsTrue(graph.ContainsEdge(2, 3)); // remove the graph we added graph.Remove(graphToAdd); Assert.AreEqual(3, graph.VertexCount); Assert.AreEqual(2, graph.EdgeCount); Assert.IsFalse(graph.Contains(1)); Assert.IsFalse(graph.Contains(2)); Assert.IsFalse(graph.Contains(3)); Assert.IsFalse(graph.ContainsEdge(1, 2)); Assert.IsFalse(graph.ContainsEdge(1, 3)); Assert.IsFalse(graph.ContainsEdge(2, 3)); CQManager.UndoLastCommand(); Assert.AreEqual(6, graph.VertexCount); Assert.AreEqual(5, graph.EdgeCount); Assert.IsTrue(graph.Contains(1)); Assert.IsTrue(graph.Contains(2)); Assert.IsTrue(graph.Contains(3)); Assert.IsTrue(graph.ContainsEdge(1, 2)); Assert.IsTrue(graph.ContainsEdge(1, 3)); Assert.IsTrue(graph.ContainsEdge(2, 3)); DirectedEdge <int> newEdge = new DirectedEdge <int>(42, 1); // 42 -> 1 graph.Add(newEdge); Assert.AreEqual(6, graph.EdgeCount); Assert.IsTrue(graph.ContainsEdge(42, 1)); Assert.IsFalse(graph.ContainsEdge(1, 42)); CQManager.UndoLastCommand(); Assert.AreEqual(5, graph.EdgeCount); Assert.IsFalse(graph.ContainsEdge(42, 1)); CQManager.RedoLastCommand(); Assert.AreEqual(6, graph.EdgeCount); Assert.IsTrue(graph.ContainsEdge(42, 1)); graph.Remove(newEdge); Assert.AreEqual(5, graph.EdgeCount); Assert.IsFalse(graph.ContainsEdge(42, 1)); CQManager.UndoLastCommand(); Assert.AreEqual(6, graph.EdgeCount); Assert.IsTrue(graph.ContainsEdge(42, 1)); graph.Disconnect(42, 1, false); Assert.AreEqual(5, graph.EdgeCount); Assert.IsFalse(graph.ContainsEdge(42, 1)); CQManager.UndoLastCommand(); Assert.AreEqual(6, graph.EdgeCount); Assert.IsTrue(graph.ContainsEdge(42, 1)); CQManager.ActivateCommandQueueStack(Guid.Empty); }