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); }
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); }