Skip to content

Commit

Permalink
Merge pull request #74 from dedsecrattle/features/undo
Browse files Browse the repository at this point in the history
Implement Undo Command
  • Loading branch information
Austintjh19 authored Mar 26, 2024
2 parents fc5d6d5 + 9c245ab commit 959a238
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 5 deletions.
1 change: 0 additions & 1 deletion src/main/java/seedu/edulink/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public CommandResult execute(String commandText) throws CommandException, ParseE
CommandResult commandResult;
Command command = addressBookParser.parseCommand(commandText);
commandResult = command.execute(model);

try {
storage.saveAddressBook(model.getAddressBook());
} catch (AccessDeniedException e) {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/seedu/edulink/logic/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class Messages {
public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s";
public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The student index provided is invalid";
public static final String MESSAGE_STUDENT_NOT_FOUND = "Student with given ID does not exist!";
public static final String MESSAGE_NO_HISTORY_FOUND = "No History available to Undo";
public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!";
public static final String MESSAGE_DUPLICATE_FIELDS =
"Multiple values specified for the following single-valued field(s): ";
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/seedu/edulink/logic/commands/UndoCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package seedu.edulink.logic.commands;

import seedu.edulink.logic.Messages;
import seedu.edulink.logic.commands.exceptions.CommandException;
import seedu.edulink.model.Model;

/**
* Undo the most recent command and revert back to previous state
*/
public class UndoCommand extends Command {
public static final String COMMAND_WORD = "undo";
public static final String MESSAGE_USAGE = "Usage: " + COMMAND_WORD;
public static final String MESSAGE_SUCCESS = "Undo Command done Successfully";

@Override
public CommandResult execute(Model model) throws CommandException {
if (model.resetToPreviousState()) {
model.updateFilteredPersonList(Model.PREDICATE_SHOW_ALL_PERSONS);
return new CommandResult(MESSAGE_SUCCESS);
} else {
throw new CommandException(Messages.MESSAGE_NO_HISTORY_FOUND);
}
}

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

/**
Expand Down Expand Up @@ -78,9 +79,11 @@ public Command parseCommand(String userInput) throws ParseException {
case HelpCommand.COMMAND_WORD:
return new HelpCommand();

case UndoCommand.COMMAND_WORD:
return new UndoCommand();

case TagCommand.COMMAND_WORD:
return new TagCommandParser().parse(arguments);

default:
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/seedu/edulink/model/AddressBook.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ public void addPerson(Student p) {
*/
public void setPerson(Student target, Student editedStudent) {
requireNonNull(editedStudent);

persons.setPerson(target, editedStudent);
}

Expand Down Expand Up @@ -128,4 +127,5 @@ public boolean equals(Object other) {
public int hashCode() {
return persons.hashCode();
}

}
2 changes: 2 additions & 0 deletions src/main/java/seedu/edulink/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,6 @@ public interface Model {
* @throws NullPointerException if {@code predicate} is null.
*/
void updateFilteredPersonList(Predicate<Student> predicate);

boolean resetToPreviousState();
}
22 changes: 21 additions & 1 deletion src/main/java/seedu/edulink/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import static seedu.edulink.commons.util.CollectionUtil.requireAllNonNull;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.function.Predicate;
import java.util.logging.Logger;

Expand All @@ -22,6 +25,7 @@ public class ModelManager implements Model {
private final AddressBook addressBook;
private final UserPrefs userPrefs;
private final FilteredList<Student> filteredStudents;
private final Stack<List<Student>> previousStates;

/**
* Initializes a ModelManager with the given addressBook and userPrefs.
Expand All @@ -34,6 +38,7 @@ public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs
this.addressBook = new AddressBook(addressBook);
this.userPrefs = new UserPrefs(userPrefs);
filteredStudents = new FilteredList<>(this.addressBook.getPersonList());
previousStates = new Stack<>();
}

public ModelManager() {
Expand Down Expand Up @@ -95,19 +100,24 @@ public boolean hasPerson(Student student) {

@Override
public void deletePerson(Student target) {
List<Student> prev = new ArrayList<>(addressBook.getPersonList());
previousStates.push(prev);
addressBook.removePerson(target);
}

@Override
public void addPerson(Student student) {
List<Student> prev = new ArrayList<>(addressBook.getPersonList());
previousStates.push(prev);
addressBook.addPerson(student);
updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
}

@Override
public void setPerson(Student target, Student editedStudent) {
List<Student> prev = new ArrayList<>(addressBook.getPersonList());
previousStates.push(prev);
requireAllNonNull(target, editedStudent);

addressBook.setPerson(target, editedStudent);
}

Expand All @@ -128,6 +138,16 @@ public void updateFilteredPersonList(Predicate<Student> predicate) {
filteredStudents.setPredicate(predicate);
}

@Override
public boolean resetToPreviousState() {
if (previousStates.isEmpty()) {
return false;
} else {
addressBook.setPersons(previousStates.pop());
return true;
}
}

@Override
public boolean equals(Object other) {
if (other == this) {
Expand Down
1 change: 0 additions & 1 deletion src/main/java/seedu/edulink/ui/MainWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ private CommandResult executeCommand(String commandText) throws CommandException
if (commandResult.isExit()) {
handleExit();
}

return commandResult;
} catch (CommandException | ParseException e) {
logger.info("An error occurred while executing command: " + commandText);
Expand Down
1 change: 1 addition & 0 deletions src/main/java/seedu/edulink/ui/UiManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public UiManager(Logic logic) {
this.logic = logic;
}


@Override
public void start(Stage primaryStage) {
logger.info("Starting UI...");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ public ObservableList<Student> getFilteredPersonList() {
public void updateFilteredPersonList(Predicate<Student> predicate) {
throw new AssertionError("This method should not be called.");
}

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

/**
Expand Down
45 changes: 45 additions & 0 deletions src/test/java/seedu/edulink/logic/commands/UndoCommandTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package seedu.edulink.logic.commands;

import static seedu.edulink.logic.commands.CommandTestUtil.assertCommandFailure;
import static seedu.edulink.logic.commands.CommandTestUtil.assertCommandSuccess;

import org.junit.jupiter.api.Test;

import seedu.edulink.logic.Messages;
import seedu.edulink.model.Model;
import seedu.edulink.model.ModelManager;
import seedu.edulink.testutil.TypicalPersons;

public class UndoCommandTest {
private Model model = new ModelManager();

@Test
public void undo_command_failure() {
assertCommandFailure(new UndoCommand(), model, Messages.MESSAGE_NO_HISTORY_FOUND);
}

@Test
public void add_success() {
model.addPerson(TypicalPersons.ALICE);
Model expected = new ModelManager();
assertCommandSuccess(new UndoCommand(), model, new CommandResult(UndoCommand.MESSAGE_SUCCESS), expected);
}

@Test
public void edit_success() {
model.addPerson(TypicalPersons.ALICE);
model.setPerson(TypicalPersons.ALICE, TypicalPersons.BOB);
Model expected = new ModelManager();
expected.addPerson(TypicalPersons.ALICE);
assertCommandSuccess(new UndoCommand(), model, new CommandResult(UndoCommand.MESSAGE_SUCCESS), expected);
}

@Test
public void delete_success() {
model.addPerson(TypicalPersons.ALICE);
model.deletePerson(TypicalPersons.ALICE);
Model expected = new ModelManager();
expected.addPerson(TypicalPersons.ALICE);
assertCommandSuccess(new UndoCommand(), model, new CommandResult(UndoCommand.MESSAGE_SUCCESS), expected);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import seedu.edulink.logic.commands.FindCommand;
import seedu.edulink.logic.commands.HelpCommand;
import seedu.edulink.logic.commands.ListCommand;
import seedu.edulink.logic.commands.UndoCommand;
import seedu.edulink.logic.parser.exceptions.ParseException;
import seedu.edulink.model.student.IdAndNameContainsQueryIdAndNamePredicate;
import seedu.edulink.model.student.IdContainsQueryIdPredicate;
Expand Down Expand Up @@ -89,6 +90,12 @@ public void parseCommand_help() throws Exception {
assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD + " 3") instanceof HelpCommand);
}

@Test
public void parseCommand_undo() throws Exception {
assertTrue(parser.parseCommand(UndoCommand.COMMAND_WORD) instanceof UndoCommand);
assertTrue(parser.parseCommand(UndoCommand.COMMAND_WORD + " 3") instanceof UndoCommand);
}

@Test
public void parseCommand_list() throws Exception {
assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD) instanceof ListCommand);
Expand Down
8 changes: 8 additions & 0 deletions src/test/java/seedu/edulink/model/ModelManagerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException
assertThrows(UnsupportedOperationException.class, () -> modelManager.getFilteredPersonList().remove(0));
}

@Test
public void resetToPreviousState() {
Model testModel = new ModelManager();
assertFalse(testModel.resetToPreviousState());
testModel.addPerson(ALICE);
assertTrue(testModel.resetToPreviousState());
}

@Test
public void equals() {
AddressBook addressBook = new AddressBookBuilder().withPerson(ALICE).withPerson(BENSON).build();
Expand Down

0 comments on commit 959a238

Please sign in to comment.