From db20e5f34e398ad40330b771244533c77d51fc0f Mon Sep 17 00:00:00 2001 From: kfwong Date: Sun, 16 Oct 2016 18:45:43 +0800 Subject: [PATCH 1/9] Created interface to support Redo function. --- .../harmony/mastermind/logic/commands/Redoable.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/harmony/mastermind/logic/commands/Redoable.java diff --git a/src/main/java/harmony/mastermind/logic/commands/Redoable.java b/src/main/java/harmony/mastermind/logic/commands/Redoable.java new file mode 100644 index 000000000000..b5963d17dee4 --- /dev/null +++ b/src/main/java/harmony/mastermind/logic/commands/Redoable.java @@ -0,0 +1,11 @@ +package harmony.mastermind.logic.commands; + +public interface Redoable { + /** + * Specify the redo operation according to the nature of the corresponding class. + * + * @return CommandResult, the Object contains details & feedback about the redo operation. + */ + //@@author A0138862W + public CommandResult redo(); +} From 4f0f4f27121003f3319390e6aeae4ac1ba0c3cd7 Mon Sep 17 00:00:00 2001 From: kfwong Date: Sun, 16 Oct 2016 19:01:15 +0800 Subject: [PATCH 2/9] - Added support redo command for AddCommand. - Parser now recognize redo. - Added redoHistory stack in ModelManager to keep track of redo history. --- .../mastermind/logic/commands/AddCommand.java | 19 +++++++++- .../logic/commands/RedoCommand.java | 36 +++++++++++++++++++ .../mastermind/logic/parser/Parser.java | 3 ++ .../java/harmony/mastermind/model/Model.java | 7 ++++ .../mastermind/model/ModelManager.java | 22 ++++++++++++ 5 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/main/java/harmony/mastermind/logic/commands/RedoCommand.java diff --git a/src/main/java/harmony/mastermind/logic/commands/AddCommand.java b/src/main/java/harmony/mastermind/logic/commands/AddCommand.java index 2171a2e86bbc..af3e23a67e86 100644 --- a/src/main/java/harmony/mastermind/logic/commands/AddCommand.java +++ b/src/main/java/harmony/mastermind/logic/commands/AddCommand.java @@ -25,7 +25,7 @@ * */ // @@author A0138862W -public class AddCommand extends Command implements Undoable { +public class AddCommand extends Command implements Undoable, Redoable { public static final String COMMAND_KEYWORD_ADD = "add"; public static final String COMMAND_KEYWORD_DO = "do"; @@ -65,6 +65,7 @@ public class AddCommand extends Command implements Undoable { public static final String MESSAGE_SUCCESS = "New task added: %1$s"; public static final String MESSAGE_UNDO_SUCCESS = "[Undo Add Command] Task deleted: %1$s"; + public static final String MESSAGE_REDO_SUCCESS = "[Undo Add Command] Task added: %1$s"; public static final String MESSAGE_DUPLICATE_TASK = "This task already exists in Mastermind"; private final Task toAdd; @@ -130,6 +131,7 @@ public CommandResult undo() { try { // remove the task that's previously added. model.deleteTask(toAdd); + model.pushToRedoHistory(this); return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, toAdd)); } catch (UniqueTaskList.TaskNotFoundException pne) { @@ -137,4 +139,19 @@ public CommandResult undo() { } } + @Override + /** action to perform when ModelManager requested to redo this command**/ + // @@author A0138862W + public CommandResult redo() { + assert model != null; + try { + model.addTask(toAdd); + model.pushToUndoHistory(this); + + return new CommandResult(String.format(MESSAGE_REDO_SUCCESS, toAdd)); + } catch (UniqueTaskList.DuplicateTaskException e) { + return new CommandResult(MESSAGE_DUPLICATE_TASK); + } + } + } diff --git a/src/main/java/harmony/mastermind/logic/commands/RedoCommand.java b/src/main/java/harmony/mastermind/logic/commands/RedoCommand.java new file mode 100644 index 000000000000..59edfc3d54ae --- /dev/null +++ b/src/main/java/harmony/mastermind/logic/commands/RedoCommand.java @@ -0,0 +1,36 @@ +package harmony.mastermind.logic.commands; + +import java.util.EmptyStackException; + +public class RedoCommand extends Command{ + +public static final String COMMAND_WORD = "redo"; + + public static final String MESSAGE_SUCCESS = "Redo successfully."; + public static final String MESSAGE_EMPTY_COMMAND_HISTORY = "There's no more action available to redo."; + public static final String MESSAGE_COMMAND_NOT_UNDOABLE = "This command is not redoable"; + public static final String COMMAND_SUMMARY = "Redoing a command:" + + "\n" + COMMAND_WORD; + + @Override + //@@author A0138862W + public CommandResult execute() { + + try{ + // All Command supports undo operation must implement Redoable interface + + // execute the redo implementation + CommandResult redoResult = model.redo(); + + // display successful message and the details of the undo operations + return new CommandResult( + MESSAGE_SUCCESS + "\n" + + "=====Redo Details=====\n" + + redoResult.feedbackToUser + "\n"+ + "=================="); + }catch(EmptyStackException ex){ + return new CommandResult(MESSAGE_EMPTY_COMMAND_HISTORY); + } + } + +} diff --git a/src/main/java/harmony/mastermind/logic/parser/Parser.java b/src/main/java/harmony/mastermind/logic/parser/Parser.java index 16e7f98df10e..ce6f9642e99b 100644 --- a/src/main/java/harmony/mastermind/logic/parser/Parser.java +++ b/src/main/java/harmony/mastermind/logic/parser/Parser.java @@ -100,6 +100,9 @@ public Command parseCommand(String userInput) { case UndoCommand.COMMAND_WORD: return new UndoCommand(); + case RedoCommand.COMMAND_WORD: + return new RedoCommand(); + case UnmarkCommand.COMMAND_WORD: return prepareUnmark(arguments); diff --git a/src/main/java/harmony/mastermind/model/Model.java b/src/main/java/harmony/mastermind/model/Model.java index abf541789fca..d3d82ef55a56 100644 --- a/src/main/java/harmony/mastermind/model/Model.java +++ b/src/main/java/harmony/mastermind/model/Model.java @@ -6,6 +6,7 @@ import harmony.mastermind.commons.core.UnmodifiableObservableList; import harmony.mastermind.logic.commands.CommandResult; +import harmony.mastermind.logic.commands.Redoable; import harmony.mastermind.logic.commands.Undoable; import harmony.mastermind.model.tag.Tag; import harmony.mastermind.model.task.ArchiveTaskList; @@ -47,6 +48,12 @@ void unmarkTask(Task target) throws UniqueTaskList.DuplicateTaskException, /** undo last action performed, throws EmptyStackException is there's no more action can be undone **/ CommandResult undo() throws EmptyStackException; + + /** push the command to redo history */ + void pushToRedoHistory(Redoable command); + + /** undo last action performed, throws EmptyStackException is there's no more action can be undone **/ + CommandResult redo() throws EmptyStackException; /** Returns the filtered task list as an {@code UnmodifiableObservableList} */ UnmodifiableObservableList getFilteredTaskList(); diff --git a/src/main/java/harmony/mastermind/model/ModelManager.java b/src/main/java/harmony/mastermind/model/ModelManager.java index 742a89fdbc05..3495049da452 100644 --- a/src/main/java/harmony/mastermind/model/ModelManager.java +++ b/src/main/java/harmony/mastermind/model/ModelManager.java @@ -16,6 +16,7 @@ import harmony.mastermind.commons.util.StringUtil; import harmony.mastermind.logic.commands.Command; import harmony.mastermind.logic.commands.CommandResult; +import harmony.mastermind.logic.commands.Redoable; import harmony.mastermind.logic.commands.Undoable; import harmony.mastermind.memory.Memory; import harmony.mastermind.model.tag.Tag; @@ -36,6 +37,8 @@ public class ModelManager extends ComponentManager implements Model { private final TaskManager taskManager; private final FilteredList filteredTasks; private final Stack undoHistory; + private final Stack redoHistory; + /** * Initializes a ModelManager with the given TaskManager @@ -51,6 +54,7 @@ public ModelManager(TaskManager src, UserPrefs userPrefs) { taskManager = new TaskManager(src); filteredTasks = new FilteredList<>(taskManager.getTasks()); undoHistory = new Stack<>(); + redoHistory = new Stack<>(); } public ModelManager() { @@ -61,6 +65,7 @@ public ModelManager(ReadOnlyTaskManager initialData, UserPrefs userPrefs) { taskManager = new TaskManager(initialData); filteredTasks = new FilteredList<>(taskManager.getTasks()); undoHistory = new Stack<>(); + redoHistory = new Stack<>(); } @Override @@ -86,6 +91,7 @@ public void pushToUndoHistory(Undoable command) { } @Override + /** undo last action performed**/ //@@author A0138862W public CommandResult undo() throws EmptyStackException{ @@ -94,6 +100,22 @@ public CommandResult undo() throws EmptyStackException{ indicateTaskManagerChanged(); return commandResult; } + + @Override + //@@author A0138862W + public void pushToRedoHistory(Redoable command){ + redoHistory.push(command); + } + + @Override + /** redo the action that being undone function**/ + //@@author A0138862W + public CommandResult redo() throws EmptyStackException{ + CommandResult commandResult = redoHistory.pop().redo(); + updateFilteredListToShowAll(); + indicateTaskManagerChanged(); + return commandResult; + } @Override public synchronized void deleteTask(ReadOnlyTask target) throws TaskNotFoundException { From e867b473ac1e5075a13c2e35c07b8685eb844adc Mon Sep 17 00:00:00 2001 From: kfwong Date: Sun, 16 Oct 2016 21:00:26 +0800 Subject: [PATCH 3/9] - Refactor to extract common logic in execute() and redo() - post command execution should push itself to appropriate stack (undoHistory / redoHistory) --- .../mastermind/logic/commands/AddCommand.java | 18 +++- .../logic/commands/EditCommand.java | 101 +++++++++++------- .../java/harmony/mastermind/model/Model.java | 4 + .../mastermind/model/ModelManager.java | 7 ++ 4 files changed, 91 insertions(+), 39 deletions(-) diff --git a/src/main/java/harmony/mastermind/logic/commands/AddCommand.java b/src/main/java/harmony/mastermind/logic/commands/AddCommand.java index af3e23a67e86..c00a7c7d8ed7 100644 --- a/src/main/java/harmony/mastermind/logic/commands/AddCommand.java +++ b/src/main/java/harmony/mastermind/logic/commands/AddCommand.java @@ -19,6 +19,7 @@ import harmony.mastermind.model.tag.Tag; import harmony.mastermind.model.tag.UniqueTagList; import harmony.mastermind.model.task.*; +import harmony.mastermind.model.task.UniqueTaskList.DuplicateTaskException; /** * Adds a task to the task manager. @@ -114,8 +115,14 @@ public AddCommand(String name, Set tags) throws IllegalValueException, P public CommandResult execute() { assert model != null; try { - model.addTask(toAdd); + executeAdd(); + + // push this command into undoHistory model.pushToUndoHistory(this); + + // this is a new command entered by user (not undo/redo) + // need to clear the redoHistory Stack + model.clearRedoHistory(); return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd)); } catch (UniqueTaskList.DuplicateTaskException e) { @@ -131,6 +138,7 @@ public CommandResult undo() { try { // remove the task that's previously added. model.deleteTask(toAdd); + model.pushToRedoHistory(this); return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, toAdd)); @@ -145,7 +153,8 @@ public CommandResult undo() { public CommandResult redo() { assert model != null; try { - model.addTask(toAdd); + executeAdd(); + model.pushToUndoHistory(this); return new CommandResult(String.format(MESSAGE_REDO_SUCCESS, toAdd)); @@ -153,5 +162,10 @@ public CommandResult redo() { return new CommandResult(MESSAGE_DUPLICATE_TASK); } } + + /** extract method since it's reusable for execute() and redo()**/ + private void executeAdd() throws DuplicateTaskException { + model.addTask(toAdd); + } } diff --git a/src/main/java/harmony/mastermind/logic/commands/EditCommand.java b/src/main/java/harmony/mastermind/logic/commands/EditCommand.java index 16e2bad9be0a..0aba527865cb 100644 --- a/src/main/java/harmony/mastermind/logic/commands/EditCommand.java +++ b/src/main/java/harmony/mastermind/logic/commands/EditCommand.java @@ -23,7 +23,7 @@ * Edits a task in task manager * */ -public class EditCommand extends Command implements Undoable{ +public class EditCommand extends Command implements Undoable, Redoable { public static final String COMMAND_KEYWORD_EDIT = "edit"; public static final String COMMAND_KEYWORD_UPDATE = "update"; @@ -55,8 +55,9 @@ public class EditCommand extends Command implements Undoable{ public static final String MESSAGE_EDIT_TASK_PROMPT = "Edit the following task: %1$s"; public static final String MESSAGE_EDIT_TASK_SUCCESS = "Task successfully edited: %1$s"; - + public static final String MESSAGE_UNDO_SUCCESS = "[Undo Edit Command] Task reverted: %1$s"; + public static final String MESSAGE_REDO_SUCCESS = "[Redo Edit Command] Edit the following task: %1$s"; // private MainWindow window; private ReadOnlyTask originalTask; @@ -79,15 +80,71 @@ public EditCommand(int targetIndex, Optional name, Optional star @Override public CommandResult execute() { - // grabbing the origin task (before edit) + try { + // grabbing the origin task (before edit) + executeEdit(); + + model.pushToUndoHistory(this); + + // this is a new command entered by user (not undo/redo) + // need to clear the redoHistory Stack + model.clearRedoHistory(); + + return new CommandResult(String.format(MESSAGE_EDIT_TASK_PROMPT, originalTask)); + + } catch (TaskNotFoundException | DuplicateTaskException | IndexOutOfBoundsException ie ) { + return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } + + } + + @Override + //@@author A0138862W + public CommandResult undo() { + + try { + // remove the task that's previously edited + model.deleteTask(editedTask); + + // add back the original task + model.addTask((Task) originalTask); + + model.pushToRedoHistory(this); + + return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, originalTask)); + } catch (UniqueTaskList.TaskNotFoundException pne) { + return new CommandResult(Messages.MESSAGE_TASK_NOT_IN_MASTERMIND); + } catch (DuplicateTaskException e) { + return new CommandResult(AddCommand.MESSAGE_DUPLICATE_TASK); + } + } + + + @Override + //@@author A0138862W + public CommandResult redo() { + + try { + executeEdit(); + + model.pushToUndoHistory(this); + + return new CommandResult(String.format(MESSAGE_REDO_SUCCESS, originalTask)); + } catch (TaskNotFoundException | DuplicateTaskException | IndexOutOfBoundsException ie) { + return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } + } + + + private void executeEdit() throws TaskNotFoundException, DuplicateTaskException, IndexOutOfBoundsException { UnmodifiableObservableList lastShownList = model.getFilteredTaskList(); if (lastShownList.size() < targetIndex) { indicateAttemptToExecuteIncorrectCommand(); - return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + throw new IndexOutOfBoundsException(); } originalTask = lastShownList.get(targetIndex - - 1); + - 1); // if user provides explicit field and value, we change them // otherwise, all user omitted field are preserve from the original @@ -110,38 +167,8 @@ public CommandResult execute() { // initialize the new task with edited values this.editedTask = new Task(toEditName, toEditStartDate, toEditEndDate, toEditTags); - try { - model.deleteTask(originalTask); - model.addTask(editedTask); - - model.pushToUndoHistory(this); - // - return new CommandResult(String.format(MESSAGE_EDIT_TASK_PROMPT, originalTask)); - - } catch (TaskNotFoundException | DuplicateTaskException ie) { - return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); - } - + model.deleteTask(originalTask); + model.addTask(editedTask); } - @Override - //@@author A0138862W - public CommandResult undo() { - - try { - // remove the task that's previously edited - model.deleteTask(editedTask); - - // add back the original task - model.addTask((Task)originalTask); - - return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, originalTask)); - } catch (UniqueTaskList.TaskNotFoundException pne) { - return new CommandResult(Messages.MESSAGE_TASK_NOT_IN_MASTERMIND); - } catch (DuplicateTaskException e) { - return new CommandResult(AddCommand.MESSAGE_DUPLICATE_TASK); - } - } - - } diff --git a/src/main/java/harmony/mastermind/model/Model.java b/src/main/java/harmony/mastermind/model/Model.java index d3d82ef55a56..aeb065757941 100644 --- a/src/main/java/harmony/mastermind/model/Model.java +++ b/src/main/java/harmony/mastermind/model/Model.java @@ -54,6 +54,10 @@ void unmarkTask(Task target) throws UniqueTaskList.DuplicateTaskException, /** undo last action performed, throws EmptyStackException is there's no more action can be undone **/ CommandResult redo() throws EmptyStackException; + + /** empty redoHistory **/ + // required when a new command is entered, model should throw away all remaining commands in the redo history + void clearRedoHistory(); /** Returns the filtered task list as an {@code UnmodifiableObservableList} */ UnmodifiableObservableList getFilteredTaskList(); diff --git a/src/main/java/harmony/mastermind/model/ModelManager.java b/src/main/java/harmony/mastermind/model/ModelManager.java index 3495049da452..34f88768609f 100644 --- a/src/main/java/harmony/mastermind/model/ModelManager.java +++ b/src/main/java/harmony/mastermind/model/ModelManager.java @@ -116,6 +116,13 @@ public CommandResult redo() throws EmptyStackException{ indicateTaskManagerChanged(); return commandResult; } + + @Override + /** This method should only be called when the user entered a new command other than redo/undo **/ + //@@author A0138862W + public void clearRedoHistory(){ + redoHistory.clear(); + } @Override public synchronized void deleteTask(ReadOnlyTask target) throws TaskNotFoundException { From 4652b323044de547f16a309ccd209a04b1e2c933 Mon Sep 17 00:00:00 2001 From: kfwong Date: Sun, 16 Oct 2016 21:14:08 +0800 Subject: [PATCH 4/9] - fix potential bug that delete and edit might undo/redo at wrong index --- .../mastermind/logic/commands/AddCommand.java | 2 +- .../logic/commands/DeleteCommand.java | 79 +++++++++++++------ .../logic/commands/EditCommand.java | 33 ++++---- 3 files changed, 74 insertions(+), 40 deletions(-) diff --git a/src/main/java/harmony/mastermind/logic/commands/AddCommand.java b/src/main/java/harmony/mastermind/logic/commands/AddCommand.java index c00a7c7d8ed7..9e6939b94705 100644 --- a/src/main/java/harmony/mastermind/logic/commands/AddCommand.java +++ b/src/main/java/harmony/mastermind/logic/commands/AddCommand.java @@ -66,7 +66,7 @@ public class AddCommand extends Command implements Undoable, Redoable { public static final String MESSAGE_SUCCESS = "New task added: %1$s"; public static final String MESSAGE_UNDO_SUCCESS = "[Undo Add Command] Task deleted: %1$s"; - public static final String MESSAGE_REDO_SUCCESS = "[Undo Add Command] Task added: %1$s"; + public static final String MESSAGE_REDO_SUCCESS = "[Redo Add Command] Task added: %1$s"; public static final String MESSAGE_DUPLICATE_TASK = "This task already exists in Mastermind"; private final Task toAdd; diff --git a/src/main/java/harmony/mastermind/logic/commands/DeleteCommand.java b/src/main/java/harmony/mastermind/logic/commands/DeleteCommand.java index 0c3b4d513a30..5f749d823946 100644 --- a/src/main/java/harmony/mastermind/logic/commands/DeleteCommand.java +++ b/src/main/java/harmony/mastermind/logic/commands/DeleteCommand.java @@ -9,63 +9,63 @@ import harmony.mastermind.model.task.UniqueTaskList.TaskNotFoundException; /** - * Deletes a task identified using it's last displayed index from the task manager. + * Deletes a task identified using it's last displayed index from the task + * manager. */ -public class DeleteCommand extends Command implements Undoable{ +public class DeleteCommand extends Command implements Undoable, Redoable { public static final String COMMAND_WORD = "delete"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Deletes the task identified by the index number used in the last task listing.\n" - + "Parameters: INDEX (must be a positive integer)\n" - + "Example: " + COMMAND_WORD + " 1"; + + ": Deletes the task identified by the index number used in the last task listing.\n" + + "Parameters: INDEX (must be a positive integer)\n" + + "Example: " + + COMMAND_WORD + + " 1"; public static final String MESSAGE_DELETE_TASK_SUCCESS = "Deleted Task: %1$s"; public static final String COMMAND_SUMMARY = "Deleting a task:" - + "\n" + COMMAND_WORD + " INDEX"; - + + "\n" + + COMMAND_WORD + + " INDEX"; + public static final String MESSAGE_UNDO_SUCCESS = "[Undo Delete Command] Task added: %1$s"; + public static final String MESSAGE_REDO_SUCCESS = "[Redo Delete Command] Deleted Task: %1$s"; public final int targetIndex; - + private ReadOnlyTask toDelete; public DeleteCommand(int targetIndex) { this.targetIndex = targetIndex; } - @Override public CommandResult execute() { - UnmodifiableObservableList lastShownList = model.getFilteredTaskList(); + try { + executeDelete(); - if (lastShownList.size() < targetIndex) { - indicateAttemptToExecuteIncorrectCommand(); - return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); - } + model.pushToUndoHistory(this); - toDelete = lastShownList.get(targetIndex - 1); + model.clearRedoHistory(); - try { - model.deleteTask(toDelete); - model.pushToUndoHistory(this); - - } catch (TaskNotFoundException tnfe) { + } catch (TaskNotFoundException | IndexOutOfBoundsException tnfe) { assert false : "The target task cannot be missing"; } return new CommandResult(String.format(MESSAGE_DELETE_TASK_SUCCESS, toDelete)); } - @Override - /** action to perform when ModelManager requested to undo this command**/ - //@@author A0138862W + /** action to perform when ModelManager requested to undo this command **/ + // @@author A0138862W public CommandResult undo() { try { // add back the task that's previously added. - model.addTask((Task)toDelete); + model.addTask((Task) toDelete); + + model.pushToRedoHistory(this); return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, toDelete)); } catch (DuplicateTaskException e) { @@ -73,4 +73,35 @@ public CommandResult undo() { } } + @Override + // @@author A0138862W + public CommandResult redo() { + try { + executeDelete(); + + model.pushToUndoHistory(this); + + } catch (TaskNotFoundException | IndexOutOfBoundsException tnfe) { + assert false : "The target task cannot be missing"; + } + + return new CommandResult(String.format(MESSAGE_REDO_SUCCESS, toDelete)); + } + + private void executeDelete() throws TaskNotFoundException, IndexOutOfBoundsException { + UnmodifiableObservableList lastShownList = model.getFilteredTaskList(); + + if (lastShownList.size() < targetIndex) { + indicateAttemptToExecuteIncorrectCommand(); + throw new IndexOutOfBoundsException(); + } + + if (toDelete == null) { + toDelete = lastShownList.get(targetIndex + - 1); + } + + model.deleteTask(toDelete); + } + } diff --git a/src/main/java/harmony/mastermind/logic/commands/EditCommand.java b/src/main/java/harmony/mastermind/logic/commands/EditCommand.java index 0aba527865cb..0f7818a14320 100644 --- a/src/main/java/harmony/mastermind/logic/commands/EditCommand.java +++ b/src/main/java/harmony/mastermind/logic/commands/EditCommand.java @@ -83,23 +83,23 @@ public CommandResult execute() { try { // grabbing the origin task (before edit) executeEdit(); - + model.pushToUndoHistory(this); - + // this is a new command entered by user (not undo/redo) - // need to clear the redoHistory Stack + // need to clear the redoHistory Stack model.clearRedoHistory(); - + return new CommandResult(String.format(MESSAGE_EDIT_TASK_PROMPT, originalTask)); - } catch (TaskNotFoundException | DuplicateTaskException | IndexOutOfBoundsException ie ) { + } catch (TaskNotFoundException | DuplicateTaskException | IndexOutOfBoundsException ie) { return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); } } @Override - //@@author A0138862W + // @@author A0138862W public CommandResult undo() { try { @@ -108,7 +108,7 @@ public CommandResult undo() { // add back the original task model.addTask((Task) originalTask); - + model.pushToRedoHistory(this); return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, originalTask)); @@ -119,14 +119,13 @@ public CommandResult undo() { } } - @Override - //@@author A0138862W + // @@author A0138862W public CommandResult redo() { - + try { executeEdit(); - + model.pushToUndoHistory(this); return new CommandResult(String.format(MESSAGE_REDO_SUCCESS, originalTask)); @@ -134,7 +133,6 @@ public CommandResult redo() { return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); } } - private void executeEdit() throws TaskNotFoundException, DuplicateTaskException, IndexOutOfBoundsException { UnmodifiableObservableList lastShownList = model.getFilteredTaskList(); @@ -143,8 +141,11 @@ private void executeEdit() throws TaskNotFoundException, DuplicateTaskException, indicateAttemptToExecuteIncorrectCommand(); throw new IndexOutOfBoundsException(); } - originalTask = lastShownList.get(targetIndex - - 1); + + if (originalTask == null) { + originalTask = lastShownList.get(targetIndex + - 1); + } // if user provides explicit field and value, we change them // otherwise, all user omitted field are preserve from the original @@ -165,7 +166,9 @@ private void executeEdit() throws TaskNotFoundException, DuplicateTaskException, }).orElse(originalTask.getTags().toSet())); // initialize the new task with edited values - this.editedTask = new Task(toEditName, toEditStartDate, toEditEndDate, toEditTags); + if (editedTask == null) { + editedTask = new Task(toEditName, toEditStartDate, toEditEndDate, toEditTags); + } model.deleteTask(originalTask); model.addTask(editedTask); From 56235db9aeb5640fc0454a9f6aef4ef9085c7fc9 Mon Sep 17 00:00:00 2001 From: kfwong Date: Sun, 16 Oct 2016 21:27:57 +0800 Subject: [PATCH 5/9] Added support for redo MarkCommand. --- .../TaskAlreadyMarkedException.java | 9 +++ .../logic/commands/MarkCommand.java | 78 +++++++++++++------ 2 files changed, 65 insertions(+), 22 deletions(-) create mode 100644 src/main/java/harmony/mastermind/commons/exceptions/TaskAlreadyMarkedException.java diff --git a/src/main/java/harmony/mastermind/commons/exceptions/TaskAlreadyMarkedException.java b/src/main/java/harmony/mastermind/commons/exceptions/TaskAlreadyMarkedException.java new file mode 100644 index 000000000000..effe74eadac2 --- /dev/null +++ b/src/main/java/harmony/mastermind/commons/exceptions/TaskAlreadyMarkedException.java @@ -0,0 +1,9 @@ +package harmony.mastermind.commons.exceptions; + +public class TaskAlreadyMarkedException extends Exception { + + //@@author A0138862W + public TaskAlreadyMarkedException(){ + super(); + } +} diff --git a/src/main/java/harmony/mastermind/logic/commands/MarkCommand.java b/src/main/java/harmony/mastermind/logic/commands/MarkCommand.java index fd87890d7546..c75b2048e5cd 100644 --- a/src/main/java/harmony/mastermind/logic/commands/MarkCommand.java +++ b/src/main/java/harmony/mastermind/logic/commands/MarkCommand.java @@ -1,6 +1,7 @@ package harmony.mastermind.logic.commands; import harmony.mastermind.commons.core.Messages; +import harmony.mastermind.commons.exceptions.TaskAlreadyMarkedException; import harmony.mastermind.model.task.Task; import harmony.mastermind.model.task.UniqueTaskList; import harmony.mastermind.model.task.UniqueTaskList.DuplicateTaskException; @@ -8,7 +9,7 @@ import javafx.collections.ObservableList; //@@author A0124797R -public class MarkCommand extends Command implements Undoable { +public class MarkCommand extends Command implements Undoable, Redoable { public static final String COMMAND_WORD = "mark"; @@ -28,6 +29,7 @@ public class MarkCommand extends Command implements Undoable { public static final String MESSAGE_MARKED_TASK = "%1$s is already marked"; public static final String MESSAGE_UNDO_SUCCESS = "[Undo Mark Command] %1$s has been unmarked"; + public static final String MESSAGE_REDO_SUCCESS = "[Redo Mark Command] %1$s has been archived"; public final int targetIndex; @@ -39,37 +41,30 @@ public MarkCommand(int targetIndex) { @Override public CommandResult execute() { - ObservableList lastShownList = model.getListToMark(); - - if (lastShownList.size() < targetIndex) { - indicateAttemptToExecuteIncorrectCommand(); - return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); - } - - taskToMark = lastShownList.get(targetIndex - - 1); - - if (taskToMark.isMarked()) { - return new CommandResult(String.format(MESSAGE_MARKED_TASK, taskToMark)); - } - try { - model.markTask(taskToMark); - } catch (TaskNotFoundException pnfe) { - assert false : "The target task cannot be missing"; + executeMark(); + + model.pushToUndoHistory(this); + + model.clearRedoHistory(); + + return new CommandResult(String.format(MESSAGE_SUCCESS, taskToMark)); + } catch (TaskAlreadyMarkedException ex) { + return new CommandResult(String.format(MESSAGE_MARKED_TASK, taskToMark)); + } catch (IndexOutOfBoundsException ex) { + return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); } - model.pushToUndoHistory(this); - - return new CommandResult(String.format(MESSAGE_SUCCESS, taskToMark)); } @Override - // @@author A0138862W + //@@author A0138862W public CommandResult undo() { try { // remove the task that's previously added. model.unmarkTask(taskToMark); + + model.pushToRedoHistory(this); return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, taskToMark)); } catch (DuplicateTaskException e) { @@ -79,4 +74,43 @@ public CommandResult undo() { } } + @Override + //@@author A0138862W + public CommandResult redo() { + try { + executeMark(); + + model.pushToUndoHistory(this); + + return new CommandResult(String.format(MESSAGE_REDO_SUCCESS, taskToMark)); + } catch (TaskAlreadyMarkedException ex) { + return new CommandResult(String.format(MESSAGE_MARKED_TASK, taskToMark)); + } catch (IndexOutOfBoundsException ex) { + return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } + } + + private void executeMark() throws TaskAlreadyMarkedException, IndexOutOfBoundsException { + ObservableList lastShownList = model.getListToMark(); + + if (lastShownList.size() < targetIndex) { + indicateAttemptToExecuteIncorrectCommand(); + throw new IndexOutOfBoundsException(); + } + + if (taskToMark == null) { + taskToMark = lastShownList.get(targetIndex + - 1); + } + + if (taskToMark.isMarked()) { + throw new TaskAlreadyMarkedException(); + } + + try { + model.markTask(taskToMark); + } catch (TaskNotFoundException pnfe) { + assert false : "The target task cannot be missing"; + } + } } From 7fafbff0798b0904e90bcf075dfe0a212f00939c Mon Sep 17 00:00:00 2001 From: kfwong Date: Sun, 16 Oct 2016 21:41:10 +0800 Subject: [PATCH 6/9] - Added support for undo UnmarkCommand. - Refactor code. --- .../TaskAlreadyUnmarkedException.java | 8 ++ .../logic/commands/UnmarkCommand.java | 100 ++++++++++++------ 2 files changed, 77 insertions(+), 31 deletions(-) create mode 100644 src/main/java/harmony/mastermind/commons/exceptions/TaskAlreadyUnmarkedException.java diff --git a/src/main/java/harmony/mastermind/commons/exceptions/TaskAlreadyUnmarkedException.java b/src/main/java/harmony/mastermind/commons/exceptions/TaskAlreadyUnmarkedException.java new file mode 100644 index 000000000000..2d879db95fa5 --- /dev/null +++ b/src/main/java/harmony/mastermind/commons/exceptions/TaskAlreadyUnmarkedException.java @@ -0,0 +1,8 @@ +package harmony.mastermind.commons.exceptions; + +public class TaskAlreadyUnmarkedException extends Exception{ + + public TaskAlreadyUnmarkedException(){ + super(); + } +} diff --git a/src/main/java/harmony/mastermind/logic/commands/UnmarkCommand.java b/src/main/java/harmony/mastermind/logic/commands/UnmarkCommand.java index 3cc06303dd33..12d79fdbb4ea 100644 --- a/src/main/java/harmony/mastermind/logic/commands/UnmarkCommand.java +++ b/src/main/java/harmony/mastermind/logic/commands/UnmarkCommand.java @@ -2,6 +2,7 @@ import harmony.mastermind.commons.core.Messages; import harmony.mastermind.commons.core.UnmodifiableObservableList; +import harmony.mastermind.commons.exceptions.TaskAlreadyUnmarkedException; import harmony.mastermind.model.task.ReadOnlyTask; import harmony.mastermind.model.task.Task; import harmony.mastermind.model.task.UniqueTaskList; @@ -10,70 +11,107 @@ import javafx.collections.ObservableList; //@@author A0124797R -public class UnmarkCommand extends Command implements Undoable{ +public class UnmarkCommand extends Command implements Undoable, Redoable{ public static final String COMMAND_WORD = "unmark"; + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": undo marking of task as done" + + "Parameters: INDEX (must be a positive integer)\n" + + "Example: " + + COMMAND_WORD + + " 1"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": undo marking of task as done" - + "Parameters: INDEX (must be a positive integer)\n" - + "Example: " + COMMAND_WORD + " 1"; - public static final String COMMAND_SUMMARY = "marks a task as not complete:" - + "\n" + COMMAND_WORD + " INDEX"; + + "\n" + + COMMAND_WORD + + " INDEX"; public static final String MESSAGE_SUCCESS = "%1$s has been unmarked"; public static final String MESSAGE_UNMARKED_TASK = "%1$s has not been completed"; public static final String MESSAGE_DUPLICATE_UNMARK_TASK = "%1$s already exist in not completed list"; public static final String MESSAGE_UNDO_SUCCESS = "[Undo Unmark Command] %1$s has been archived"; + public static final String MESSAGE_REDO_SUCCESS = "[Redo Unmark Command] %1$s has been unmarked"; public final int targetIndex; - + ReadOnlyTask taskToUnmark; public UnmarkCommand(int targetIndex) { this.targetIndex = targetIndex; } - + @Override public CommandResult execute() { - UnmodifiableObservableList lastShownList = model.getFilteredArchiveList(); + try { + executeUnmark(); + + model.pushToUndoHistory(this); + + model.clearRedoHistory(); - if (lastShownList.size() < targetIndex) { - indicateAttemptToExecuteIncorrectCommand(); + return new CommandResult(String.format(MESSAGE_SUCCESS, taskToUnmark)); + } catch (IndexOutOfBoundsException iobe) { return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); - } - - taskToUnmark = lastShownList.get(targetIndex - 1); - - if (!taskToUnmark.isMarked()) { + } catch (TaskAlreadyUnmarkedException tau) { return new CommandResult(String.format(MESSAGE_UNMARKED_TASK, taskToUnmark)); - } - - try { - model.unmarkTask((Task)taskToUnmark); - } catch (TaskNotFoundException pnfe) { - assert false : "The target task cannot be missing"; - } catch (DuplicateTaskException e) { + } catch (DuplicateTaskException dte) { return new CommandResult(String.format(MESSAGE_DUPLICATE_UNMARK_TASK, taskToUnmark)); } - - model.pushToUndoHistory(this); - - return new CommandResult(String.format(MESSAGE_SUCCESS, taskToUnmark)); } - + @Override - // @@author A0138862W + //@@author A0138862W public CommandResult undo() { try { // remove the task that's previously added. - model.markTask((Task)taskToUnmark); + model.markTask((Task) taskToUnmark); return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, taskToUnmark)); } catch (UniqueTaskList.TaskNotFoundException e) { return new CommandResult(Messages.MESSAGE_TASK_NOT_IN_MASTERMIND); } } - + + @Override + //@@author A0138862W + public CommandResult redo() { + try { + executeUnmark(); + + model.pushToUndoHistory(this); + + return new CommandResult(String.format(MESSAGE_SUCCESS, taskToUnmark)); + } catch (IndexOutOfBoundsException iobe) { + return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } catch (TaskAlreadyUnmarkedException tau) { + return new CommandResult(String.format(MESSAGE_UNMARKED_TASK, taskToUnmark)); + } catch (DuplicateTaskException dte) { + return new CommandResult(String.format(MESSAGE_DUPLICATE_UNMARK_TASK, taskToUnmark)); + } + } + + private void executeUnmark() throws IndexOutOfBoundsException, TaskAlreadyUnmarkedException, DuplicateTaskException { + UnmodifiableObservableList lastShownList = model.getFilteredArchiveList(); + + if (lastShownList.size() < targetIndex) { + indicateAttemptToExecuteIncorrectCommand(); + throw new IndexOutOfBoundsException(); + } + + if (taskToUnmark == null) { + taskToUnmark = lastShownList.get(targetIndex + - 1); + } + + if (!taskToUnmark.isMarked()) { + throw new TaskAlreadyUnmarkedException(); + } + + try { + model.unmarkTask((Task) taskToUnmark); + } catch (TaskNotFoundException pnfe) { + assert false : "The target task cannot be missing"; + } + } } From 1f321232bf32557f26c4817189492a6e5d433a9d Mon Sep 17 00:00:00 2001 From: kfwong Date: Sun, 16 Oct 2016 22:17:36 +0800 Subject: [PATCH 7/9] Fix the assertion that makes the test case fail. --- .../harmony/mastermind/logic/commands/DeleteCommand.java | 7 ++++++- src/test/java/guitests/DeleteCommandTest.java | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/harmony/mastermind/logic/commands/DeleteCommand.java b/src/main/java/harmony/mastermind/logic/commands/DeleteCommand.java index 5f749d823946..fada042d4139 100644 --- a/src/main/java/harmony/mastermind/logic/commands/DeleteCommand.java +++ b/src/main/java/harmony/mastermind/logic/commands/DeleteCommand.java @@ -51,7 +51,12 @@ public CommandResult execute() { model.clearRedoHistory(); } catch (TaskNotFoundException | IndexOutOfBoundsException tnfe) { - assert false : "The target task cannot be missing"; + // by A0138862W: + // uncommented this line because it makes the DeleteCommandTest fail at line 33 + // should return invalid message for UI to display otherwise it'll display null + //assert false : "The target task cannot be missing"; + + return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); } return new CommandResult(String.format(MESSAGE_DELETE_TASK_SUCCESS, toDelete)); diff --git a/src/test/java/guitests/DeleteCommandTest.java b/src/test/java/guitests/DeleteCommandTest.java index 69680b6c4a28..feccadff41da 100644 --- a/src/test/java/guitests/DeleteCommandTest.java +++ b/src/test/java/guitests/DeleteCommandTest.java @@ -27,9 +27,9 @@ public void delete() { currentList = TestUtil.removeTaskFromList(currentList, targetIndex); targetIndex = currentList.length/2; assertDeleteSuccess(targetIndex, currentList); - + //invalid index - commandBox.runCommand("delete " + currentList.length + 1); + commandBox.runCommand("delete " + (currentList.length + 1)); assertResultMessage("The task index provided is invalid"); } From cf960dd559a2d0f3974a949fe09a3de783d951d6 Mon Sep 17 00:00:00 2001 From: kfwong Date: Mon, 17 Oct 2016 20:09:58 +0800 Subject: [PATCH 8/9] Update redo test cases. --- .../logic/commands/DeleteCommand.java | 2 +- .../mastermind/logic/LogicManagerTest.java | 30 ++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/main/java/harmony/mastermind/logic/commands/DeleteCommand.java b/src/main/java/harmony/mastermind/logic/commands/DeleteCommand.java index fada042d4139..66b9dc27d8a2 100644 --- a/src/main/java/harmony/mastermind/logic/commands/DeleteCommand.java +++ b/src/main/java/harmony/mastermind/logic/commands/DeleteCommand.java @@ -87,7 +87,7 @@ public CommandResult redo() { model.pushToUndoHistory(this); } catch (TaskNotFoundException | IndexOutOfBoundsException tnfe) { - assert false : "The target task cannot be missing"; + return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); } return new CommandResult(String.format(MESSAGE_REDO_SUCCESS, toDelete)); diff --git a/src/test/java/harmony/mastermind/logic/LogicManagerTest.java b/src/test/java/harmony/mastermind/logic/LogicManagerTest.java index 8763ba258468..cb5138d274eb 100644 --- a/src/test/java/harmony/mastermind/logic/LogicManagerTest.java +++ b/src/test/java/harmony/mastermind/logic/LogicManagerTest.java @@ -178,12 +178,11 @@ public void execute_add_successful() throws Exception { @Test //@@author A0138862W - public void execute_undo_add() throws Exception{ + public void execute_undoAndRedo_add() throws Exception{ TestDataHelper helper = new TestDataHelper(); Task toBeAdded = helper.task(); - System.out.println(helper.generateAddCommand(toBeAdded)); - System.out.println(logic.execute(helper.generateAddCommand(toBeAdded)).feedbackToUser); + logic.execute(helper.generateAddCommand(toBeAdded)); assertCommandBehavior("undo", "Undo successfully.\n" + "=====Undo Details=====\n" @@ -191,11 +190,18 @@ public void execute_undo_add() throws Exception{ + "==================", model.getTaskManager(), model.getTaskManager().getTaskList()); + + assertCommandBehavior("redo", "Redo successfully.\n" + + "=====Redo Details=====\n" + + "[Redo Add Command] Task added: task Tags: [tag1],[tag2]\n" + + "==================", + model.getTaskManager(), + model.getTaskManager().getTaskList()); } @Test //@@author A0138862W - public void execute_undo_edit() throws Exception{ + public void execute_undoAndRedo_edit() throws Exception{ TestDataHelper helper = new TestDataHelper(); Task toBeEdited = helper.task(); List onePerson = helper.generateTaskList(toBeEdited); @@ -213,6 +219,14 @@ public void execute_undo_edit() throws Exception{ + "==================", expectedTM, expectedList); + + assertCommandBehavior("redo", + "Redo successfully.\n" + + "=====Redo Details=====\n" + + "[Redo Edit Command] Edit the following task: task Tags: [tag1],[tag2]\n" + + "==================", + expectedTM, + expectedList); } @Test @@ -235,6 +249,14 @@ public void execute_undo_delete() throws Exception{ + "==================", expectedTM, expectedList); + + assertCommandBehavior("redo", + "Redo successfully.\n" + + "=====Redo Details=====\n" + + "[Redo Delete Command] Deleted Task: task Tags: [tag1],[tag2]\n" + + "==================", + model.getTaskManager(), + model.getListToMark()); } @Test From 089d541a369acef6487f09abd28107120210113d Mon Sep 17 00:00:00 2001 From: kfwong Date: Mon, 17 Oct 2016 21:32:05 +0800 Subject: [PATCH 9/9] update more test cases for mark and unmark command. --- .../logic/commands/MarkCommand.java | 28 +++++++++---------- .../logic/commands/UnmarkCommand.java | 2 ++ .../mastermind/logic/LogicManagerTest.java | 16 +++++++++++ 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/main/java/harmony/mastermind/logic/commands/MarkCommand.java b/src/main/java/harmony/mastermind/logic/commands/MarkCommand.java index c75b2048e5cd..8c3791529723 100644 --- a/src/main/java/harmony/mastermind/logic/commands/MarkCommand.java +++ b/src/main/java/harmony/mastermind/logic/commands/MarkCommand.java @@ -43,27 +43,29 @@ public MarkCommand(int targetIndex) { public CommandResult execute() { try { executeMark(); - + model.pushToUndoHistory(this); - + model.clearRedoHistory(); - + return new CommandResult(String.format(MESSAGE_SUCCESS, taskToMark)); } catch (TaskAlreadyMarkedException ex) { return new CommandResult(String.format(MESSAGE_MARKED_TASK, taskToMark)); } catch (IndexOutOfBoundsException ex) { return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } catch (TaskNotFoundException pnfe) { + return new CommandResult(Messages.MESSAGE_TASK_NOT_IN_MASTERMIND); } } @Override - //@@author A0138862W + // @@author A0138862W public CommandResult undo() { try { // remove the task that's previously added. model.unmarkTask(taskToMark); - + model.pushToRedoHistory(this); return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, taskToMark)); @@ -75,22 +77,24 @@ public CommandResult undo() { } @Override - //@@author A0138862W + // @@author A0138862W public CommandResult redo() { try { executeMark(); - + model.pushToUndoHistory(this); - + return new CommandResult(String.format(MESSAGE_REDO_SUCCESS, taskToMark)); } catch (TaskAlreadyMarkedException ex) { return new CommandResult(String.format(MESSAGE_MARKED_TASK, taskToMark)); } catch (IndexOutOfBoundsException ex) { return new CommandResult(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } catch (TaskNotFoundException pnfe) { + return new CommandResult(Messages.MESSAGE_TASK_NOT_IN_MASTERMIND); } } - private void executeMark() throws TaskAlreadyMarkedException, IndexOutOfBoundsException { + private void executeMark() throws TaskAlreadyMarkedException, IndexOutOfBoundsException, TaskNotFoundException { ObservableList lastShownList = model.getListToMark(); if (lastShownList.size() < targetIndex) { @@ -107,10 +111,6 @@ private void executeMark() throws TaskAlreadyMarkedException, IndexOutOfBoundsEx throw new TaskAlreadyMarkedException(); } - try { - model.markTask(taskToMark); - } catch (TaskNotFoundException pnfe) { - assert false : "The target task cannot be missing"; - } + model.markTask(taskToMark); } } diff --git a/src/main/java/harmony/mastermind/logic/commands/UnmarkCommand.java b/src/main/java/harmony/mastermind/logic/commands/UnmarkCommand.java index 12d79fdbb4ea..25fe965fbfe0 100644 --- a/src/main/java/harmony/mastermind/logic/commands/UnmarkCommand.java +++ b/src/main/java/harmony/mastermind/logic/commands/UnmarkCommand.java @@ -66,6 +66,8 @@ public CommandResult undo() { try { // remove the task that's previously added. model.markTask((Task) taskToUnmark); + + model.pushToRedoHistory(this); return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, taskToUnmark)); } catch (UniqueTaskList.TaskNotFoundException e) { diff --git a/src/test/java/harmony/mastermind/logic/LogicManagerTest.java b/src/test/java/harmony/mastermind/logic/LogicManagerTest.java index cb5138d274eb..3266a3e522b1 100644 --- a/src/test/java/harmony/mastermind/logic/LogicManagerTest.java +++ b/src/test/java/harmony/mastermind/logic/LogicManagerTest.java @@ -279,6 +279,14 @@ public void execute_undo_mark() throws Exception{ + "==================", expectedTM, expectedList); + + assertCommandBehavior("redo", + "Redo successfully.\n" + + "=====Redo Details=====\n" + + "[Redo Mark Command] task Tags: [tag1],[tag2] has been archived\n" + + "==================", + model.getTaskManager(), + model.getListToMark()); } @Test @@ -303,6 +311,14 @@ public void execute_undo_unmark() throws Exception{ + "==================", model.getTaskManager(), model.getListToMark()); + + assertCommandBehavior("redo", + "Redo successfully.\n" + + "=====Redo Details=====\n" + + "task Tags: [tag1],[tag2] has been unmarked\n" + + "==================", + model.getTaskManager(), + model.getListToMark()); } @Test