Skip to content

Commit

Permalink
Implement Undo Command
Browse files Browse the repository at this point in the history
  • Loading branch information
FionaQY committed Oct 27, 2024
1 parent 9973876 commit 029b8ac
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 10 deletions.
28 changes: 28 additions & 0 deletions src/main/java/seedu/address/logic/commands/UndoCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package seedu.address.logic.commands;

import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.AgentAssist;
import seedu.address.model.Model;

import static java.util.Objects.requireNonNull;

/**
* Clears the address book.
*/
public class UndoCommand extends Command {

public static final String COMMAND_WORD = "undo";
public static final String MESSAGE_SUCCESS = "Your latest command has been undone.";
public static final String MESSAGE_NO_COMMAND_TO_UNDO = "Please input a command first in order to undo it.";

@Override
protected CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
if (!model.hasPreviousCommand()) {
throw new CommandException(MESSAGE_NO_COMMAND_TO_UNDO);
}
model.undoCommand();
return new CommandResult(MESSAGE_SUCCESS);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import seedu.address.logic.commands.FilterCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.commands.UndoCommand;
import seedu.address.logic.commands.ViewCommand;
import seedu.address.logic.parser.exceptions.ParseException;

Expand Down Expand Up @@ -86,6 +87,9 @@ public Command parseCommand(String userInput) throws ParseException {
case CloseCommand.COMMAND_WORD:
return new CloseCommand();

case UndoCommand.COMMAND_WORD:
return new UndoCommand();

default:
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/seedu/address/model/AgentAssist.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ public void removePerson(Person key) {
persons.remove(key);
}

/**
* Gets a copy of the current AgentAssist.
*/
public AgentAssist getCopy() {
AgentAssist newAgentAssist = new AgentAssist();
newAgentAssist.setPersons(this.getPersonList());
return newAgentAssist;
}

//// util methods

@Override
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ public interface Model {
*/
void setPerson(Person target, Person editedPerson);

/**
* Undos previous command by setting currentAddressBook to historyAddressBook.
*/
void undoCommand();

/**
* Returns true if a command has been executed before.
*/
boolean hasPreviousCommand();

/** Returns an unmodifiable view of the filtered person list */
ObservableList<Person> getFilteredPersonList();

Expand Down
42 changes: 32 additions & 10 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
public class ModelManager implements Model {
private static final Logger logger = LogsCenter.getLogger(ModelManager.class);

private final AgentAssist agentAssist;
private AgentAssist historyAgentAssist = null;
private AgentAssist currentAgentAssist;
private final UserPrefs userPrefs;
private final FilteredList<Person> filteredPersons;
private final SimpleObjectProperty<Person> selectedPerson = new SimpleObjectProperty<>();
Expand All @@ -37,15 +38,22 @@ public ModelManager(ReadOnlyAgentAssist agentAssist, ReadOnlyUserPrefs userPrefs

logger.fine("Initializing with address book: " + agentAssist + " and user prefs " + userPrefs);

this.agentAssist = new AgentAssist(agentAssist);
this.currentAgentAssist = new AgentAssist(agentAssist);
this.userPrefs = new UserPrefs(userPrefs);
filteredPersons = new FilteredList<>(this.agentAssist.getPersonList());
filteredPersons = new FilteredList<>(this.currentAgentAssist.getPersonList());
}

public ModelManager() {
this(new AgentAssist(), new UserPrefs());
}

/**
* Save the history of the AgentAssist.
*/
private void safeHistory() {
historyAgentAssist = currentAgentAssist.getCopy();
}


//=========== UserPrefs ==================================================================================

Expand Down Expand Up @@ -86,36 +94,50 @@ public void setAgentAssistFilePath(Path agentAssistFilePath) {

@Override
public void setAgentAssist(ReadOnlyAgentAssist agentAssist) {
this.agentAssist.resetData(agentAssist);
safeHistory();
this.currentAgentAssist.resetData(agentAssist);
}

@Override
public ReadOnlyAgentAssist getAgentAssist() {
return agentAssist;
return currentAgentAssist;
}

@Override
public boolean hasPerson(Person person) {
requireNonNull(person);
return agentAssist.hasPerson(person);
return currentAgentAssist.hasPerson(person);
}

@Override
public void deletePerson(Person target) {
agentAssist.removePerson(target);
safeHistory();
currentAgentAssist.removePerson(target);
}

@Override
public void addPerson(Person person) {
agentAssist.addPerson(person);
safeHistory();
currentAgentAssist.addPerson(person);
updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
}

@Override
public void setPerson(Person target, Person editedPerson) {
requireAllNonNull(target, editedPerson);
safeHistory();
currentAgentAssist.setPerson(target, editedPerson);
}

agentAssist.setPerson(target, editedPerson);
@Override
public void undoCommand() {
requireNonNull(this.historyAgentAssist);
this.setAgentAssist(this.historyAgentAssist);
}

@Override
public boolean hasPreviousCommand() {
return this.historyAgentAssist != null;
}

//=========== Selected Person ===========================================================================
Expand Down Expand Up @@ -185,7 +207,7 @@ public boolean equals(Object other) {
}

ModelManager otherModelManager = (ModelManager) other;
return agentAssist.equals(otherModelManager.agentAssist)
return currentAgentAssist.equals(otherModelManager.currentAgentAssist)
&& userPrefs.equals(otherModelManager.userPrefs)
&& filteredPersons.equals(otherModelManager.filteredPersons);
}
Expand Down
10 changes: 10 additions & 0 deletions src/test/java/seedu/address/logic/commands/AddCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,16 @@ public void setPerson(Person target, Person editedPerson) {
throw new AssertionError("This method should not be called.");
}

@Override
public void undoCommand() {
throw new AssertionError("This method should not be called.");
}

@Override
public boolean hasPreviousCommand() {
throw new AssertionError("This method should not be called.");
}

@Override
public ObservableList<Person> getFilteredPersonList() {
throw new AssertionError("This method should not be called.");
Expand Down
46 changes: 46 additions & 0 deletions src/test/java/seedu/address/logic/commands/UndoCommandTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package seedu.address.logic.commands;

import org.junit.jupiter.api.Test;
import seedu.address.logic.Messages;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.AgentAssist;
import seedu.address.model.Model;
import seedu.address.model.ModelManager;
import seedu.address.model.UserPrefs;
import seedu.address.model.person.Person;
import seedu.address.testutil.EditPersonDescriptorBuilder;
import seedu.address.testutil.PersonBuilder;

import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
import static seedu.address.testutil.TypicalPersons.getTypicalAgentAssist;

public class UndoCommandTest {

private Model model = new ModelManager(getTypicalAgentAssist(), new UserPrefs());

@Test
public void execute_undo_success() {
Person editedPerson = new PersonBuilder().build();
EditCommand.EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(editedPerson).build();
EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, descriptor);
try {
CommandResult result = editCommand.execute(model);
} catch (CommandException ce) {
throw new AssertionError("Execution of command should not fail.", ce);
}

UndoCommand undoCommand = new UndoCommand();
Model expectedModel = new ModelManager(getTypicalAgentAssist(), new UserPrefs());

assertCommandSuccess(undoCommand, model, UndoCommand.MESSAGE_SUCCESS, expectedModel);
}

@Test
public void execute_noPreviousCommand_failure() {
Model model = new ModelManager();
assertCommandFailure(new UndoCommand(), model, UndoCommand.MESSAGE_NO_COMMAND_TO_UNDO);
}

}

0 comments on commit 029b8ac

Please sign in to comment.