From 38adad0e242a9ea70681709932562311ec2f22a1 Mon Sep 17 00:00:00 2001 From: Tan Jie Ling Date: Wed, 20 Mar 2024 02:55:26 +0800 Subject: [PATCH 01/29] Create clear confirmation windows --- .../address/logic/commands/ClearCommand.java | 10 +- .../address/ui/ClearConfirmationWindow.java | 111 ++++++++++++++++++ .../java/seedu/address/ui/MainWindow.java | 2 + .../view/ClearConfirmationWindow.css | 19 +++ .../view/ClearConfirmationWindow.fxml | 44 +++++++ 5 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 src/main/java/seedu/address/ui/ClearConfirmationWindow.java create mode 100644 src/main/resources/view/ClearConfirmationWindow.css create mode 100644 src/main/resources/view/ClearConfirmationWindow.fxml diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/address/logic/commands/ClearCommand.java index 024d3478d9f..55386d973eb 100644 --- a/src/main/java/seedu/address/logic/commands/ClearCommand.java +++ b/src/main/java/seedu/address/logic/commands/ClearCommand.java @@ -4,6 +4,7 @@ import seedu.address.model.Model; import seedu.address.model.NetConnect; +import seedu.address.ui.ClearConfirmationWindow; /** * Clears the address book. @@ -13,10 +14,15 @@ public class ClearCommand extends Command { public static final String COMMAND_WORD = "clear"; public static final String MESSAGE_SUCCESS = "Address book has been cleared!"; + @Override public CommandResult execute(Model model) { requireNonNull(model); - model.setNetConnect(new NetConnect()); - return new CommandResult(MESSAGE_SUCCESS); + if (ClearConfirmationWindow.isConfirmedClear()) { + ClearConfirmationWindow.resetConfirmation(); + model.setNetConnect(new NetConnect()); + return new CommandResult(MESSAGE_SUCCESS); + } + return new CommandResult("Clear command cancelled"); } } diff --git a/src/main/java/seedu/address/ui/ClearConfirmationWindow.java b/src/main/java/seedu/address/ui/ClearConfirmationWindow.java new file mode 100644 index 00000000000..5d9433b3c7e --- /dev/null +++ b/src/main/java/seedu/address/ui/ClearConfirmationWindow.java @@ -0,0 +1,111 @@ +package seedu.address.ui; + +import java.util.logging.Logger; + +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.stage.Stage; +import seedu.address.commons.core.LogsCenter; + +/** + * Controller for a Clear Confirmation page + */ +public class ClearConfirmationWindow extends UiPart { + public static final String CONFIRMATION_MESSAGE = "Are you sure you want to clear the address book?"; + + private static final Logger logger = LogsCenter.getLogger(ClearConfirmationWindow.class); + private static final String FXML = "ClearConfirmationWindow.fxml"; + private static boolean isConfirmedClear = false; + + @FXML + private Button confirmButton; + + @FXML + private Label clearConfirmationMessage; + + /** + * Creates a new ClearConfirmationWindow. + * + * @param root Stage to use as the root of the ClearConfirmationWindow. + */ + public ClearConfirmationWindow(Stage root) { + super(FXML, root); + clearConfirmationMessage.setText(CONFIRMATION_MESSAGE); + } + + /** + * Creates a new ClearConfirmationWindow. + */ + public ClearConfirmationWindow() { + this(new Stage()); + } + + /** + * Shows the help window. + * + * @throws IllegalStateException + */ + public void show() { + logger.fine("Showing confirmation query for clear command."); + getRoot().show(); + getRoot().centerOnScreen(); + } + + /** + * Returns true if the clear confirmation window is currently being shown. + */ + public boolean isShowing() { + return getRoot().isShowing(); + } + + /** + * Hides the clear confirmation window. + */ + public void hide() { + getRoot().hide(); + } + + /** + * Focuses on the clear confirmation window. + */ + public void focus() { + getRoot().requestFocus(); + } + + /** + * Confirms the clear command. + */ + @FXML + private void confirmClear() { + isConfirmedClear = true; + getRoot().hide(); + } + + /** + * Returns true if the clear command is confirmed. + */ + public static boolean isConfirmedClear() { + return isConfirmedClear; + } + + /** + * Resets the confirmation status of the clear command. + */ + public static void resetConfirmation() { + isConfirmedClear = false; + } +} diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index abe6411046c..6c7fa196297 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -34,6 +34,7 @@ public class MainWindow extends UiPart { private PersonListPanel personListPanel; private ResultDisplay resultDisplay; private final HelpWindow helpWindow; + private final ClearConfirmationWindow clearConfirmationWindow; @FXML private StackPane commandBoxPlaceholder; @@ -66,6 +67,7 @@ public MainWindow(Stage primaryStage, Logic logic) { setAccelerators(); helpWindow = new HelpWindow(); + clearConfirmationWindow = new ClearConfirmationWindow(); } public Stage getPrimaryStage() { diff --git a/src/main/resources/view/ClearConfirmationWindow.css b/src/main/resources/view/ClearConfirmationWindow.css new file mode 100644 index 00000000000..0c15737fc7e --- /dev/null +++ b/src/main/resources/view/ClearConfirmationWindow.css @@ -0,0 +1,19 @@ +#confirmButton, #clearConfirmationMessage { + -fx-text-fill: white; +} + +#confirmButton { + -fx-background-color: dimgray; +} + +#confirmButton:hover { + -fx-background-color: gray; +} + +#confirmButton:armed { + -fx-background-color: darkgray; +} + +#clearConfirmationContainer { + -fx-background-color: derive(#1d1d1d, 20%); +} diff --git a/src/main/resources/view/ClearConfirmationWindow.fxml b/src/main/resources/view/ClearConfirmationWindow.fxml new file mode 100644 index 00000000000..1182cdf7206 --- /dev/null +++ b/src/main/resources/view/ClearConfirmationWindow.fxml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 60237ab024c52d8fa3965d13c0eaaf9d831e705b Mon Sep 17 00:00:00 2001 From: Shaun Lee Date: Thu, 28 Mar 2024 04:19:02 +0800 Subject: [PATCH 02/29] Change Model#setPerson to ensure id not modified --- src/main/java/seedu/address/model/Model.java | 3 ++- src/main/java/seedu/address/model/NetConnect.java | 8 ++++---- .../seedu/address/model/person/UniquePersonList.java | 6 ++++-- .../model/person/exceptions/IdModifiedException.java | 11 +++++++++++ .../address/model/person/UniquePersonListTest.java | 12 ++++++------ 5 files changed, 27 insertions(+), 13 deletions(-) create mode 100644 src/main/java/seedu/address/model/person/exceptions/IdModifiedException.java diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index 4b5d8eeaff3..07f9e4aa1f3 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -90,7 +90,8 @@ public interface Model { * Replaces the given person {@code target} with {@code editedPerson}. * {@code target} must exist in the address book. * The person identity of {@code editedPerson} must not be the same as another - * existing person in the address book. + * existing person in the NetConnect. + * {@code target} and {@code editedPerson} must have the same id. */ void setPerson(Person target, Person editedPerson); diff --git a/src/main/java/seedu/address/model/NetConnect.java b/src/main/java/seedu/address/model/NetConnect.java index 3bac26fb45f..99bfe171447 100644 --- a/src/main/java/seedu/address/model/NetConnect.java +++ b/src/main/java/seedu/address/model/NetConnect.java @@ -94,11 +94,11 @@ public void addPerson(Person p) { } /** - * Replaces the given person {@code target} in the list with - * {@code editedPerson}. - * {@code target} must exist in the address book. + * Replaces the given person {@code target} in the list with {@code editedPerson}. + * {@code target} must exist in the list. * The person identity of {@code editedPerson} must not be the same as another - * existing person in the address book. + * existing person in the list. + * {@code target} and {@code editedPerson} must have the same id. */ public void setPerson(Person target, Person editedPerson) { requireNonNull(editedPerson); diff --git a/src/main/java/seedu/address/model/person/UniquePersonList.java b/src/main/java/seedu/address/model/person/UniquePersonList.java index be30e98b44a..af98ca05e09 100644 --- a/src/main/java/seedu/address/model/person/UniquePersonList.java +++ b/src/main/java/seedu/address/model/person/UniquePersonList.java @@ -10,6 +10,7 @@ import javafx.collections.ObservableList; import seedu.address.model.person.exceptions.DuplicateIdException; import seedu.address.model.person.exceptions.DuplicatePersonException; +import seedu.address.model.person.exceptions.IdModifiedException; import seedu.address.model.person.exceptions.IdNotFoundException; import seedu.address.model.person.exceptions.PersonNotFoundException; @@ -72,6 +73,7 @@ public void add(Person toAdd) { * Replaces the person {@code target} in the list with {@code editedPerson}. * {@code target} must exist in the list. * The person identity of {@code editedPerson} must not be the same as another existing person in the list. + * {@code target} and {@code editedPerson} must have the same id. */ public void setPerson(Person target, Person editedPerson) { requireAllNonNull(target, editedPerson); @@ -85,8 +87,8 @@ public void setPerson(Person target, Person editedPerson) { throw new DuplicatePersonException(); } - if (!target.hasSameId(editedPerson) && hasId(editedPerson.getId())) { - throw new DuplicateIdException(); + if (!target.getId().equals(editedPerson.getId())) { + throw new IdModifiedException(); } internalList.set(index, editedPerson); diff --git a/src/main/java/seedu/address/model/person/exceptions/IdModifiedException.java b/src/main/java/seedu/address/model/person/exceptions/IdModifiedException.java new file mode 100644 index 00000000000..7aa1466d1ab --- /dev/null +++ b/src/main/java/seedu/address/model/person/exceptions/IdModifiedException.java @@ -0,0 +1,11 @@ +package seedu.address.model.person.exceptions; + +/** + * Signals that the operation will cause a {@code Person}'s id + * to be modified. + */ +public class IdModifiedException extends RuntimeException { + public IdModifiedException() { + super("Operation would result in id of person to be modified"); + } +} diff --git a/src/test/java/seedu/address/model/person/UniquePersonListTest.java b/src/test/java/seedu/address/model/person/UniquePersonListTest.java index c69963709e1..08d238358d9 100644 --- a/src/test/java/seedu/address/model/person/UniquePersonListTest.java +++ b/src/test/java/seedu/address/model/person/UniquePersonListTest.java @@ -19,6 +19,7 @@ import seedu.address.model.person.exceptions.DuplicateIdException; import seedu.address.model.person.exceptions.DuplicatePersonException; +import seedu.address.model.person.exceptions.IdModifiedException; import seedu.address.model.person.exceptions.IdNotFoundException; import seedu.address.model.person.exceptions.PersonNotFoundException; import seedu.address.testutil.ClientBuilder; @@ -184,13 +185,13 @@ public void setPerson_editedSupplierHasSameIdentity_success() { assertEquals(expectedUniquePersonList, uniquePersonList); } - @Test public void setPerson_editedPersonHasDifferentIdentity_success() { uniquePersonList.add(ALICE); - uniquePersonList.setPerson(ALICE, BOB); + Person bobWithAliceId = new EmployeeBuilder(BOB).withId(ALICE.getId().value).build(); + uniquePersonList.setPerson(ALICE, bobWithAliceId); UniquePersonList expectedUniquePersonList = new UniquePersonList(); - expectedUniquePersonList.add(BOB); + expectedUniquePersonList.add(bobWithAliceId); assertEquals(expectedUniquePersonList, uniquePersonList); } @@ -202,11 +203,10 @@ public void setPerson_editedPersonHasNonUniqueIdentity_throwsDuplicatePersonExce } @Test - public void setPerson_editedPersonHasDuplicateId_throwsDuplicateIdException() { + public void setPerson_editedPersonHasModifiedId_throwsIdModifiedException() { uniquePersonList.add(ALICE); - uniquePersonList.add(BOB); Person editedAlice = new ClientBuilder(ALICE).withId(BOB.getId().value).build(); - assertThrows(DuplicateIdException.class, () -> uniquePersonList.setPerson(ALICE, editedAlice)); + assertThrows(IdModifiedException.class, () -> uniquePersonList.setPerson(ALICE, editedAlice)); } @Test From b79870d66931cdc52d0e66585d4685c543f607a0 Mon Sep 17 00:00:00 2001 From: Tan Jie Ling Date: Thu, 28 Mar 2024 19:02:16 +0800 Subject: [PATCH 03/29] Implement warnings for delete and clear commands --- .../address/logic/commands/ClearCommand.java | 18 +-- .../address/logic/commands/CommandResult.java | 24 +++- .../address/logic/commands/DeleteCommand.java | 7 ++ .../address/ui/ClearConfirmationWindow.java | 111 ------------------ .../ui/DestructiveConfirmationWindow.java | 40 +++++++ .../java/seedu/address/ui/MainWindow.java | 4 +- .../view/ClearConfirmationWindow.css | 19 --- .../view/ClearConfirmationWindow.fxml | 44 ------- .../logic/commands/ClearCommandTest.java | 50 ++++---- 9 files changed, 105 insertions(+), 212 deletions(-) delete mode 100644 src/main/java/seedu/address/ui/ClearConfirmationWindow.java create mode 100644 src/main/java/seedu/address/ui/DestructiveConfirmationWindow.java delete mode 100644 src/main/resources/view/ClearConfirmationWindow.css delete mode 100644 src/main/resources/view/ClearConfirmationWindow.fxml diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/address/logic/commands/ClearCommand.java index 55386d973eb..a38ae7c882d 100644 --- a/src/main/java/seedu/address/logic/commands/ClearCommand.java +++ b/src/main/java/seedu/address/logic/commands/ClearCommand.java @@ -1,10 +1,10 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; +import static seedu.address.ui.DestructiveConfirmationWindow.handleDestructiveConfirmation; import seedu.address.model.Model; import seedu.address.model.NetConnect; -import seedu.address.ui.ClearConfirmationWindow; /** * Clears the address book. @@ -12,17 +12,19 @@ public class ClearCommand extends Command { public static final String COMMAND_WORD = "clear"; - public static final String MESSAGE_SUCCESS = "Address book has been cleared!"; - + public static final String CLEAR_SUCCESS_MESSAGE = "Address book has been cleared!"; + public static final String CLEAR_CANCELLED_MESSAGE = "Clear command cancelled"; + private static Model model; @Override public CommandResult execute(Model model) { requireNonNull(model); - if (ClearConfirmationWindow.isConfirmedClear()) { - ClearConfirmationWindow.resetConfirmation(); - model.setNetConnect(new NetConnect()); - return new CommandResult(MESSAGE_SUCCESS); + this.model = model; + boolean isConfirmed = handleDestructiveConfirmation(false, true); + if (!isConfirmed) { + return new CommandResult(CLEAR_CANCELLED_MESSAGE, false, false); } - return new CommandResult("Clear command cancelled"); + model.setNetConnect(new NetConnect()); + return new CommandResult(CLEAR_SUCCESS_MESSAGE, false, false); } } diff --git a/src/main/java/seedu/address/logic/commands/CommandResult.java b/src/main/java/seedu/address/logic/commands/CommandResult.java index dddbcfad29e..837ae0d21d8 100644 --- a/src/main/java/seedu/address/logic/commands/CommandResult.java +++ b/src/main/java/seedu/address/logic/commands/CommandResult.java @@ -23,15 +23,28 @@ public class CommandResult { */ private final boolean exit; + private final boolean isDelete; + private final boolean isClear; + /** * Constructs a {@code CommandResult} with the specified fields. */ - public CommandResult(String feedbackToUser, boolean showHelp, boolean exit) { + public CommandResult(String feedbackToUser, boolean showHelp, boolean isClear, boolean isDelete, boolean exit) { this.feedbackToUser = requireNonNull(feedbackToUser); this.showHelp = showHelp; + this.isClear = isClear; + this.isDelete = isDelete; this.exit = exit; } + /** + * Constructs a {@code CommandResult} with the specified fields. + */ + public CommandResult(String feedbackToUser, boolean showHelp, boolean exit) { + this(feedbackToUser, showHelp, false, false, false); + + } + /** * Constructs a {@code CommandResult} with the specified {@code feedbackToUser}, * and other fields set to their default value. @@ -47,7 +60,12 @@ public String getFeedbackToUser() { public boolean isShowHelp() { return showHelp; } - + public boolean isDelete() { + return isDelete; + } + public boolean isClear() { + return isClear; + } public boolean isExit() { return exit; } @@ -66,6 +84,8 @@ public boolean equals(Object other) { CommandResult otherCommandResult = (CommandResult) other; return feedbackToUser.equals(otherCommandResult.feedbackToUser) && showHelp == otherCommandResult.showHelp + && isDelete == otherCommandResult.isDelete + && isClear == otherCommandResult.isClear && exit == otherCommandResult.exit; } diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index a4d1fab6282..63a2cb7385c 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -2,6 +2,7 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.parser.CliSyntax.PREFIX_ID; +import static seedu.address.ui.DestructiveConfirmationWindow.handleDestructiveConfirmation; import seedu.address.commons.util.ToStringBuilder; import seedu.address.logic.Messages; @@ -24,6 +25,7 @@ public class DeleteCommand extends Command { + "Example: " + COMMAND_WORD + " i/1"; public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s"; + public static final String MESSAGE_DELETE_CANCELLED = "Delete cancelled"; private final Id targetId; @@ -35,6 +37,11 @@ public DeleteCommand(Id targetId) { public CommandResult execute(Model model) throws CommandException { requireNonNull(model); + boolean isConfirmed = handleDestructiveConfirmation(true, false); + if (!isConfirmed) { + return new CommandResult(MESSAGE_DELETE_CANCELLED, false, false); + } + if (!model.hasId(targetId)) { throw new CommandException(String.format(Messages.MESSAGE_INVALID_PERSON_ID, targetId.value)); } diff --git a/src/main/java/seedu/address/ui/ClearConfirmationWindow.java b/src/main/java/seedu/address/ui/ClearConfirmationWindow.java deleted file mode 100644 index 5d9433b3c7e..00000000000 --- a/src/main/java/seedu/address/ui/ClearConfirmationWindow.java +++ /dev/null @@ -1,111 +0,0 @@ -package seedu.address.ui; - -import java.util.logging.Logger; - -import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.stage.Stage; -import seedu.address.commons.core.LogsCenter; - -/** - * Controller for a Clear Confirmation page - */ -public class ClearConfirmationWindow extends UiPart { - public static final String CONFIRMATION_MESSAGE = "Are you sure you want to clear the address book?"; - - private static final Logger logger = LogsCenter.getLogger(ClearConfirmationWindow.class); - private static final String FXML = "ClearConfirmationWindow.fxml"; - private static boolean isConfirmedClear = false; - - @FXML - private Button confirmButton; - - @FXML - private Label clearConfirmationMessage; - - /** - * Creates a new ClearConfirmationWindow. - * - * @param root Stage to use as the root of the ClearConfirmationWindow. - */ - public ClearConfirmationWindow(Stage root) { - super(FXML, root); - clearConfirmationMessage.setText(CONFIRMATION_MESSAGE); - } - - /** - * Creates a new ClearConfirmationWindow. - */ - public ClearConfirmationWindow() { - this(new Stage()); - } - - /** - * Shows the help window. - * - * @throws IllegalStateException
    - *
  • - * if this method is called on a thread other than the JavaFX Application Thread. - *
  • - *
  • - * if this method is called during animation or layout processing. - *
  • - *
  • - * if this method is called on the primary stage. - *
  • - *
  • - * if {@code dialogStage} is already showing. - *
  • - *
- */ - public void show() { - logger.fine("Showing confirmation query for clear command."); - getRoot().show(); - getRoot().centerOnScreen(); - } - - /** - * Returns true if the clear confirmation window is currently being shown. - */ - public boolean isShowing() { - return getRoot().isShowing(); - } - - /** - * Hides the clear confirmation window. - */ - public void hide() { - getRoot().hide(); - } - - /** - * Focuses on the clear confirmation window. - */ - public void focus() { - getRoot().requestFocus(); - } - - /** - * Confirms the clear command. - */ - @FXML - private void confirmClear() { - isConfirmedClear = true; - getRoot().hide(); - } - - /** - * Returns true if the clear command is confirmed. - */ - public static boolean isConfirmedClear() { - return isConfirmedClear; - } - - /** - * Resets the confirmation status of the clear command. - */ - public static void resetConfirmation() { - isConfirmedClear = false; - } -} diff --git a/src/main/java/seedu/address/ui/DestructiveConfirmationWindow.java b/src/main/java/seedu/address/ui/DestructiveConfirmationWindow.java new file mode 100644 index 00000000000..6e1d5cf25f6 --- /dev/null +++ b/src/main/java/seedu/address/ui/DestructiveConfirmationWindow.java @@ -0,0 +1,40 @@ +package seedu.address.ui; + +import java.util.Optional; +import java.util.logging.Logger; + +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonType; +import seedu.address.commons.core.LogsCenter; + +/** + * Controller for a Destructive Action page + */ +public class DestructiveConfirmationWindow { + private static final Logger logger = LogsCenter.getLogger(DestructiveConfirmationWindow.class); + + private static final String TITLE = "Destructive Action Confirmation"; + private static final String CLEAR_HEADER_TEXT = "Are you sure you want to clear the address book? This action cannot be undone."; + private static final String DELETE_HEADER_TEXT = "Are you sure you want to delete this person? This action cannot be undone"; + + @FXML + public static boolean handleDestructiveConfirmation(boolean isDeleteCommand, boolean isClearCommand) { + + logger.info("Showing destructive action confirmation"); + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle(TITLE); + if (isClearCommand) { + alert.setHeaderText(CLEAR_HEADER_TEXT); + } else if (isDeleteCommand) { + alert.setHeaderText(DELETE_HEADER_TEXT); + } + + Optional result = alert.showAndWait(); + + if (result.isPresent() && result.get() == ButtonType.OK) { + return true; + } + return false; + } +} diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index 6c7fa196297..c26bdcb05a8 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -34,7 +34,6 @@ public class MainWindow extends UiPart { private PersonListPanel personListPanel; private ResultDisplay resultDisplay; private final HelpWindow helpWindow; - private final ClearConfirmationWindow clearConfirmationWindow; @FXML private StackPane commandBoxPlaceholder; @@ -67,7 +66,6 @@ public MainWindow(Stage primaryStage, Logic logic) { setAccelerators(); helpWindow = new HelpWindow(); - clearConfirmationWindow = new ClearConfirmationWindow(); } public Stage getPrimaryStage() { @@ -196,4 +194,4 @@ private CommandResult executeCommand(String commandText) throws CommandException throw e; } } -} +} \ No newline at end of file diff --git a/src/main/resources/view/ClearConfirmationWindow.css b/src/main/resources/view/ClearConfirmationWindow.css deleted file mode 100644 index 0c15737fc7e..00000000000 --- a/src/main/resources/view/ClearConfirmationWindow.css +++ /dev/null @@ -1,19 +0,0 @@ -#confirmButton, #clearConfirmationMessage { - -fx-text-fill: white; -} - -#confirmButton { - -fx-background-color: dimgray; -} - -#confirmButton:hover { - -fx-background-color: gray; -} - -#confirmButton:armed { - -fx-background-color: darkgray; -} - -#clearConfirmationContainer { - -fx-background-color: derive(#1d1d1d, 20%); -} diff --git a/src/main/resources/view/ClearConfirmationWindow.fxml b/src/main/resources/view/ClearConfirmationWindow.fxml deleted file mode 100644 index 1182cdf7206..00000000000 --- a/src/main/resources/view/ClearConfirmationWindow.fxml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java index 94417a03e3b..7eaf91b36db 100644 --- a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java @@ -1,32 +1,32 @@ package seedu.address.logic.commands; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalPersons.getTypicalNetConnect; - -import org.junit.jupiter.api.Test; - -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.NetConnect; -import seedu.address.model.UserPrefs; +//import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +//import static seedu.address.testutil.TypicalPersons.getTypicalNetConnect; +// +//import org.junit.jupiter.api.Test; +// +//import seedu.address.model.Model; +//import seedu.address.model.ModelManager; +//import seedu.address.model.NetConnect; +//import seedu.address.model.UserPrefs; public class ClearCommandTest { - @Test - public void execute_emptyNetConnect_success() { - Model model = new ModelManager(); - Model expectedModel = new ModelManager(); - - assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel); - } - - @Test - public void execute_nonEmptyNetConnect_success() { - Model model = new ModelManager(getTypicalNetConnect(), new UserPrefs()); - Model expectedModel = new ModelManager(getTypicalNetConnect(), new UserPrefs()); - expectedModel.setNetConnect(new NetConnect()); - - assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel); - } +// @Test +// public void execute_emptyNetConnect_success() { +// Model model = new ModelManager(); +// Model expectedModel = new ModelManager(); +// +// assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel); +// } +// +// @Test +// public void execute_nonEmptyNetConnect_success() { +// Model model = new ModelManager(getTypicalNetConnect(), new UserPrefs()); +// Model expectedModel = new ModelManager(getTypicalNetConnect(), new UserPrefs()); +// expectedModel.setNetConnect(new NetConnect()); +// +// assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel); +// } } From fc3180ebc61b27aa8cc2ff3fe647c44450ae5fc8 Mon Sep 17 00:00:00 2001 From: Tan Jie Ling Date: Thu, 28 Mar 2024 22:08:17 +0800 Subject: [PATCH 04/29] Refactor call of warning window into mainwindow --- .../address/logic/commands/ClearCommand.java | 4 ++-- .../address/logic/commands/CommandResult.java | 24 ++----------------- .../address/logic/commands/DeleteCommand.java | 4 ++-- .../ui/DestructiveConfirmationWindow.java | 15 +++++++++--- .../java/seedu/address/ui/MainWindow.java | 13 +++++++++- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/address/logic/commands/ClearCommand.java index a38ae7c882d..de814c6ce5a 100644 --- a/src/main/java/seedu/address/logic/commands/ClearCommand.java +++ b/src/main/java/seedu/address/logic/commands/ClearCommand.java @@ -1,7 +1,7 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; -import static seedu.address.ui.DestructiveConfirmationWindow.handleDestructiveConfirmation; +import static seedu.address.ui.MainWindow.handleDestructiveCommands; import seedu.address.model.Model; import seedu.address.model.NetConnect; @@ -20,7 +20,7 @@ public class ClearCommand extends Command { public CommandResult execute(Model model) { requireNonNull(model); this.model = model; - boolean isConfirmed = handleDestructiveConfirmation(false, true); + boolean isConfirmed = handleDestructiveCommands(false, true); if (!isConfirmed) { return new CommandResult(CLEAR_CANCELLED_MESSAGE, false, false); } diff --git a/src/main/java/seedu/address/logic/commands/CommandResult.java b/src/main/java/seedu/address/logic/commands/CommandResult.java index 837ae0d21d8..dddbcfad29e 100644 --- a/src/main/java/seedu/address/logic/commands/CommandResult.java +++ b/src/main/java/seedu/address/logic/commands/CommandResult.java @@ -23,28 +23,15 @@ public class CommandResult { */ private final boolean exit; - private final boolean isDelete; - private final boolean isClear; - /** * Constructs a {@code CommandResult} with the specified fields. */ - public CommandResult(String feedbackToUser, boolean showHelp, boolean isClear, boolean isDelete, boolean exit) { + public CommandResult(String feedbackToUser, boolean showHelp, boolean exit) { this.feedbackToUser = requireNonNull(feedbackToUser); this.showHelp = showHelp; - this.isClear = isClear; - this.isDelete = isDelete; this.exit = exit; } - /** - * Constructs a {@code CommandResult} with the specified fields. - */ - public CommandResult(String feedbackToUser, boolean showHelp, boolean exit) { - this(feedbackToUser, showHelp, false, false, false); - - } - /** * Constructs a {@code CommandResult} with the specified {@code feedbackToUser}, * and other fields set to their default value. @@ -60,12 +47,7 @@ public String getFeedbackToUser() { public boolean isShowHelp() { return showHelp; } - public boolean isDelete() { - return isDelete; - } - public boolean isClear() { - return isClear; - } + public boolean isExit() { return exit; } @@ -84,8 +66,6 @@ public boolean equals(Object other) { CommandResult otherCommandResult = (CommandResult) other; return feedbackToUser.equals(otherCommandResult.feedbackToUser) && showHelp == otherCommandResult.showHelp - && isDelete == otherCommandResult.isDelete - && isClear == otherCommandResult.isClear && exit == otherCommandResult.exit; } diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index 63a2cb7385c..f43a9ac26e1 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -2,7 +2,7 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.parser.CliSyntax.PREFIX_ID; -import static seedu.address.ui.DestructiveConfirmationWindow.handleDestructiveConfirmation; +import static seedu.address.ui.MainWindow.handleDestructiveCommands; import seedu.address.commons.util.ToStringBuilder; import seedu.address.logic.Messages; @@ -37,7 +37,7 @@ public DeleteCommand(Id targetId) { public CommandResult execute(Model model) throws CommandException { requireNonNull(model); - boolean isConfirmed = handleDestructiveConfirmation(true, false); + boolean isConfirmed = handleDestructiveCommands(true, false); if (!isConfirmed) { return new CommandResult(MESSAGE_DELETE_CANCELLED, false, false); } diff --git a/src/main/java/seedu/address/ui/DestructiveConfirmationWindow.java b/src/main/java/seedu/address/ui/DestructiveConfirmationWindow.java index 6e1d5cf25f6..38bfc160ca0 100644 --- a/src/main/java/seedu/address/ui/DestructiveConfirmationWindow.java +++ b/src/main/java/seedu/address/ui/DestructiveConfirmationWindow.java @@ -15,9 +15,18 @@ public class DestructiveConfirmationWindow { private static final Logger logger = LogsCenter.getLogger(DestructiveConfirmationWindow.class); private static final String TITLE = "Destructive Action Confirmation"; - private static final String CLEAR_HEADER_TEXT = "Are you sure you want to clear the address book? This action cannot be undone."; - private static final String DELETE_HEADER_TEXT = "Are you sure you want to delete this person? This action cannot be undone"; - + private static final String CLEAR_HEADER_TEXT = + "Are you sure you want to clear the address book? This action cannot be undone."; + private static final String DELETE_HEADER_TEXT = + "Are you sure you want to delete this person? This action cannot be undone"; + + /** + * Shows a confirmation dialog for destructive actions. + * + * @param isDeleteCommand true if the command is a delete command + * @param isClearCommand true if the command is a clear command + * @return true if the user confirms the action, false otherwise + */ @FXML public static boolean handleDestructiveConfirmation(boolean isDeleteCommand, boolean isClearCommand) { diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index c26bdcb05a8..a45d5d1dcf8 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -194,4 +194,15 @@ private CommandResult executeCommand(String commandText) throws CommandException throw e; } } -} \ No newline at end of file + + /** + * Handles destructive confirmation for destructive commands. + * @param isDeleteCommand true if the command is a delete command, false otherwise. + * @param isClearCommand true if the command is a clear command, false otherwise. + * + * @return true if the user confirms the destructive action, false otherwise. + */ + public static boolean handleDestructiveCommands(boolean isDeleteCommand, boolean isClearCommand) { + return DestructiveConfirmationWindow.handleDestructiveConfirmation(isDeleteCommand, isClearCommand); + } +} From 6f849838b5edcfaa1b2c2b5e5cde72e32bf240b1 Mon Sep 17 00:00:00 2001 From: Tan Jie Ling Date: Thu, 28 Mar 2024 23:29:15 +0800 Subject: [PATCH 05/29] Update tests --- .../address/logic/commands/ClearCommand.java | 21 ++++++- .../address/logic/commands/DeleteCommand.java | 25 ++++++-- .../logic/commands/ClearCommandTest.java | 63 +++++++++++-------- .../logic/commands/DeleteCommandTest.java | 16 ++++- 4 files changed, 88 insertions(+), 37 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/address/logic/commands/ClearCommand.java index de814c6ce5a..b40c6e54681 100644 --- a/src/main/java/seedu/address/logic/commands/ClearCommand.java +++ b/src/main/java/seedu/address/logic/commands/ClearCommand.java @@ -15,16 +15,31 @@ public class ClearCommand extends Command { public static final String CLEAR_SUCCESS_MESSAGE = "Address book has been cleared!"; public static final String CLEAR_CANCELLED_MESSAGE = "Clear command cancelled"; private static Model model; + private static boolean doNotSkipConfirmation = true; + + @Override public CommandResult execute(Model model) { requireNonNull(model); this.model = model; - boolean isConfirmed = handleDestructiveCommands(false, true); - if (!isConfirmed) { - return new CommandResult(CLEAR_CANCELLED_MESSAGE, false, false); + + if (doNotSkipConfirmation) { + boolean isConfirmed = handleDestructiveCommands(false, true); + if (!isConfirmed) { + return new CommandResult(CLEAR_CANCELLED_MESSAGE, false, false); + } } + model.setNetConnect(new NetConnect()); return new CommandResult(CLEAR_SUCCESS_MESSAGE, false, false); } + + public static void setUpForTesting() { + doNotSkipConfirmation = false; + } + + public static void cleanUpAfterTesting() { + doNotSkipConfirmation = true; + } } diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index f43a9ac26e1..945c12b3ee4 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -26,7 +26,7 @@ public class DeleteCommand extends Command { public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s"; public static final String MESSAGE_DELETE_CANCELLED = "Delete cancelled"; - + private static boolean doNotSkipConfirmation = true; private final Id targetId; public DeleteCommand(Id targetId) { @@ -37,15 +37,20 @@ public DeleteCommand(Id targetId) { public CommandResult execute(Model model) throws CommandException { requireNonNull(model); - boolean isConfirmed = handleDestructiveCommands(true, false); - if (!isConfirmed) { - return new CommandResult(MESSAGE_DELETE_CANCELLED, false, false); - } - + // check if the ID is valid if (!model.hasId(targetId)) { throw new CommandException(String.format(Messages.MESSAGE_INVALID_PERSON_ID, targetId.value)); } + if (doNotSkipConfirmation) { + // obtain confirmation from + boolean isConfirmed = handleDestructiveCommands(true, false); + if (!isConfirmed) { + return new CommandResult(MESSAGE_DELETE_CANCELLED, false, false); + } + } + + Person personToDelete = model.getPersonById(targetId); boolean showList = !model.getFilteredPersonList().contains(personToDelete); model.deletePerson(personToDelete); @@ -70,6 +75,14 @@ public boolean equals(Object other) { return targetId.equals(otherDeleteCommand.targetId); } + public static void setUpForTesting() { + doNotSkipConfirmation = false; + } + + public static void cleanUpAfterTesting() { + doNotSkipConfirmation = true; + } + @Override public String toString() { return new ToStringBuilder(this) diff --git a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java index 7eaf91b36db..d485bb9dac4 100644 --- a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java @@ -1,32 +1,45 @@ package seedu.address.logic.commands; -//import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -//import static seedu.address.testutil.TypicalPersons.getTypicalNetConnect; -// -//import org.junit.jupiter.api.Test; -// -//import seedu.address.model.Model; -//import seedu.address.model.ModelManager; -//import seedu.address.model.NetConnect; -//import seedu.address.model.UserPrefs; +import static seedu.address.logic.commands.ClearCommand.cleanUpAfterTesting; +import static seedu.address.logic.commands.ClearCommand.setUpForTesting; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.testutil.TypicalPersons.getTypicalNetConnect; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import seedu.address.model.Model; +import seedu.address.model.ModelManager; +import seedu.address.model.NetConnect; +import seedu.address.model.UserPrefs; public class ClearCommandTest { + @BeforeAll + public static void setUp() { + setUpForTesting(); + } + + @AfterAll + public static void close() { + cleanUpAfterTesting(); + } + + @Test + public void execute_emptyNetConnect_success() { + Model model = new ModelManager(); + Model expectedModel = new ModelManager(); + + assertCommandSuccess(new ClearCommand(), model, ClearCommand.CLEAR_SUCCESS_MESSAGE, expectedModel); + } + + @Test + public void execute_nonEmptyNetConnect_success() { + Model model = new ModelManager(getTypicalNetConnect(), new UserPrefs()); + Model expectedModel = new ModelManager(getTypicalNetConnect(), new UserPrefs()); + expectedModel.setNetConnect(new NetConnect()); -// @Test -// public void execute_emptyNetConnect_success() { -// Model model = new ModelManager(); -// Model expectedModel = new ModelManager(); -// -// assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel); -// } -// -// @Test -// public void execute_nonEmptyNetConnect_success() { -// Model model = new ModelManager(getTypicalNetConnect(), new UserPrefs()); -// Model expectedModel = new ModelManager(getTypicalNetConnect(), new UserPrefs()); -// expectedModel.setNetConnect(new NetConnect()); -// -// assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel); -// } + assertCommandSuccess(new ClearCommand(), model, ClearCommand.CLEAR_SUCCESS_MESSAGE, expectedModel); + } } diff --git a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java index 8c0d5af44bd..b6dba66cc3e 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java @@ -6,11 +6,15 @@ import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; import static seedu.address.logic.commands.CommandTestUtil.showPersonAtId; +import static seedu.address.logic.commands.DeleteCommand.cleanUpAfterTesting; +import static seedu.address.logic.commands.DeleteCommand.setUpForTesting; import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; import static seedu.address.testutil.TypicalIds.ID_FIRST_PERSON; import static seedu.address.testutil.TypicalIds.ID_SECOND_PERSON; import static seedu.address.testutil.TypicalPersons.getTypicalNetConnect; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import seedu.address.commons.core.index.Index; @@ -26,8 +30,16 @@ * {@code DeleteCommand}. */ public class DeleteCommandTest { - private final Model model = new ModelManager(getTypicalNetConnect(), new UserPrefs()); + @BeforeAll + public static void setUp() { + setUpForTesting(); + } + + @AfterAll + public static void close() { + cleanUpAfterTesting(); + } @Test public void execute_validIdUnfilteredList_success() { @@ -55,7 +67,6 @@ public void execute_invalidIdUnfilteredList_throwsCommandException() { @Test public void execute_validIdFilteredListPresent_success() { showPersonAtId(model, ID_FIRST_PERSON); - Person personToDelete = model.getPersonById(ID_FIRST_PERSON); DeleteCommand deleteCommand = new DeleteCommand(ID_FIRST_PERSON); @@ -72,7 +83,6 @@ public void execute_validIdFilteredListPresent_success() { @Test public void execute_validIdFilteredListAbsent_success() { showPersonAtId(model, ID_SECOND_PERSON); - Person personToDelete = model.getPersonById(ID_FIRST_PERSON); DeleteCommand deleteCommand = new DeleteCommand(ID_FIRST_PERSON); From 66f9e53b2444ca39539812d0b331d5d04004e045 Mon Sep 17 00:00:00 2001 From: nuyer <98694104+nuyer@users.noreply.github.com> Date: Fri, 29 Mar 2024 17:03:43 +0800 Subject: [PATCH 06/29] Change implement for ExportCommand to export current view --- .../java/seedu/address/logic/utils/CsvExporter.java | 6 +++--- src/main/java/seedu/address/model/ModelManager.java | 5 ++++- src/main/java/seedu/address/model/NetConnect.java | 13 ------------- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/main/java/seedu/address/logic/utils/CsvExporter.java b/src/main/java/seedu/address/logic/utils/CsvExporter.java index 3440cc314dc..defd3fd4282 100644 --- a/src/main/java/seedu/address/logic/utils/CsvExporter.java +++ b/src/main/java/seedu/address/logic/utils/CsvExporter.java @@ -6,11 +6,11 @@ import java.util.ArrayList; import java.util.List; +import javafx.collections.transformation.FilteredList; import seedu.address.model.person.Client; import seedu.address.model.person.Employee; import seedu.address.model.person.Person; import seedu.address.model.person.Supplier; -import seedu.address.model.person.UniquePersonList; /** * A utility class for exporting data from an address book to a CSV file. @@ -22,7 +22,7 @@ public class CsvExporter { private boolean isSuccessful = false; - private final UniquePersonList persons; + private final FilteredList persons; /** * Constructs a CSVExporter object with the specified list of persons and filename. @@ -30,7 +30,7 @@ public class CsvExporter { * @param persons The list of persons to be exported to CSV. * @param filename The filename for the CSV file to be created. */ - public CsvExporter(UniquePersonList persons, String filename) { + public CsvExporter(FilteredList persons, String filename) { this.persons = persons; this.filename = filename; } diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index a5cfcd2e445..178bb121829 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -11,6 +11,7 @@ import javafx.collections.transformation.FilteredList; import seedu.address.commons.core.GuiSettings; import seedu.address.commons.core.LogsCenter; +import seedu.address.logic.utils.CsvExporter; import seedu.address.model.person.Id; import seedu.address.model.person.Person; @@ -129,7 +130,9 @@ public void setPerson(Person target, Person editedPerson) { @Override public boolean exportCsv(String filename) { requireNonNull(filename); - return netConnect.exportCsv(filename); + CsvExporter exporter = new CsvExporter(filteredPersons, filename); + exporter.execute(); + return exporter.getIsSuccessful(); } // =========== Filtered Person List Accessors diff --git a/src/main/java/seedu/address/model/NetConnect.java b/src/main/java/seedu/address/model/NetConnect.java index 3bac26fb45f..6c1c5f418a5 100644 --- a/src/main/java/seedu/address/model/NetConnect.java +++ b/src/main/java/seedu/address/model/NetConnect.java @@ -6,7 +6,6 @@ import javafx.collections.ObservableList; import seedu.address.commons.util.ToStringBuilder; -import seedu.address.logic.utils.CsvExporter; import seedu.address.model.person.Id; import seedu.address.model.person.Person; import seedu.address.model.person.UniquePersonList; @@ -115,18 +114,6 @@ public void removePerson(Person key) { } - /** - * Exports the data from the address book as a CSV file with the specified filename. - * Returns {@code true} if the export operation is successful, {@code false} otherwise. - * - * @return {@code true} if the export operation is successful, {@code false} otherwise. - */ - public boolean exportCsv(String filename) { - CsvExporter exporter = new CsvExporter(persons, filename); - exporter.execute(); - return exporter.getIsSuccessful(); - } - //// util methods @Override From 67e389b85412a3645efa1209d5f5b8d26ad35447 Mon Sep 17 00:00:00 2001 From: Tan Jie Ling Date: Sun, 31 Mar 2024 04:22:22 +0800 Subject: [PATCH 07/29] Refactor save-state under storage --- src/main/java/seedu/address/MainApp.java | 5 +- .../seedu/address/storage/StateStorage.java | 146 +----------- .../java/seedu/address/storage/Storage.java | 10 +- .../seedu/address/storage/StorageManager.java | 21 +- .../address/storage/TextStateStorage.java | 147 ++++++++++++ .../java/seedu/address/ui/CommandBox.java | 16 +- .../seedu/address/logic/LogicManagerTest.java | 8 +- .../address/storage/StateStorageTest.java | 210 +++++++++--------- .../address/storage/StorageManagerTest.java | 3 +- 9 files changed, 315 insertions(+), 251 deletions(-) create mode 100644 src/main/java/seedu/address/storage/TextStateStorage.java diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/address/MainApp.java index d73f86d426b..f79a44b9f0b 100644 --- a/src/main/java/seedu/address/MainApp.java +++ b/src/main/java/seedu/address/MainApp.java @@ -25,8 +25,10 @@ import seedu.address.storage.JsonNetConnectStorage; import seedu.address.storage.JsonUserPrefsStorage; import seedu.address.storage.NetConnectStorage; +import seedu.address.storage.StateStorage; import seedu.address.storage.Storage; import seedu.address.storage.StorageManager; +import seedu.address.storage.TextStateStorage; import seedu.address.storage.UserPrefsStorage; import seedu.address.ui.Ui; import seedu.address.ui.UiManager; @@ -58,7 +60,8 @@ public void init() throws Exception { UserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(config.getUserPrefsFilePath()); UserPrefs userPrefs = initPrefs(userPrefsStorage); NetConnectStorage netConnectStorage = new JsonNetConnectStorage(userPrefs.getNetConnectFilePath()); - storage = new StorageManager(netConnectStorage, userPrefsStorage); + StateStorage stateStorage = new TextStateStorage(); + storage = new StorageManager(netConnectStorage, userPrefsStorage, stateStorage); model = initModelManager(storage, userPrefs); diff --git a/src/main/java/seedu/address/storage/StateStorage.java b/src/main/java/seedu/address/storage/StateStorage.java index 0ca1fef73d2..3b70994fcc2 100644 --- a/src/main/java/seedu/address/storage/StateStorage.java +++ b/src/main/java/seedu/address/storage/StateStorage.java @@ -1,155 +1,33 @@ package seedu.address.storage; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.logging.Logger; +import java.util.Optional; -import seedu.address.MainApp; -import seedu.address.commons.core.LogsCenter; import seedu.address.commons.exceptions.DataLoadingException; /** * Represents the database to store the previous state of command before the application is closed. */ -public class StateStorage { - private static final String filePath = "./data/state.txt"; - private static final Path DIRECTORY_PATH = Paths.get("./data"); - private static final Path FILE_PATH = Paths.get(filePath); - private static final Logger logger = LogsCenter.getLogger(MainApp.class); - - /** - * Constructor for the storage. - *

- * The constructor creates a new file and/or directory if the filepath for ./data/state.txt does not exist. - */ - public StateStorage() { - assert !filePath.isBlank() : "the file path should not be blank"; - - try { - if (!Files.exists(DIRECTORY_PATH)) { - Files.createDirectories(DIRECTORY_PATH); - } - if (!Files.exists(FILE_PATH)) { - Files.createFile(FILE_PATH); - } - } catch (IOException e) { - logger.info("Error clearing creating state storage: " + e.getMessage()); - } - } - - /** - * Clears all the text in the state storage file. - */ - public static void clearState() { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) { - writer.write(""); - } catch (IOException e) { - logger.info("Error clearing state text: " + e.getMessage()); - logger.info("Starting with a clean slate..."); - deleteStateStorage(); - StateStorage stateStorage = new StateStorage(); - } - } - +public interface StateStorage { /** - * Checks if the state storage file exists. - * - * @return True if the file exists, else false. - */ - public static boolean isStateStorageExists() { - return Files.exists(FILE_PATH); - } - - /** - * Deletes the entire state storage file. - */ - public static void deleteStateStorage() { - try { - Files.delete(FILE_PATH); - } catch (IOException e) { - logger.info("Error deleting state file: " + e.getMessage()); - } - } - - /** - * Saves the command to the state storage by writing to the file. - * - * @param input Updated command input (at every change) to be written to the storage file. - */ - public static void writeState(String input) { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) { - writer.write(input); - } catch (IOException e) { - logger.info("Error saving state to file: " + e.getMessage()); - } - } - - /** - * Retrieves the past state of the command box if found, else it will return an empty command. - * - * @return The last input in the command box, or and empty string if not found. - * @throws DataLoadingException If the file is not found or cannot be read. - */ - public static String loadState() throws DataLoadingException { - logger.info("Loading state from " + FILE_PATH + "..."); - - String lastCommand = ""; - try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { - String data = reader.readLine(); - - while (data != null) { - lastCommand = lastCommand + data; - data = reader.readLine(); - } - } catch (IOException e) { - throw new DataLoadingException(e); - } - return lastCommand; - } - - /** - * Instantiates a stateStorage file if it does not exist. If it already exists, it will return the last command. - * - * @return The last input in the command box, or and empty string new file created. - * @throws DataLoadingException If the file is not found or cannot be read. - */ - public static String getLastCommand() throws DataLoadingException { - StateStorage stateStorage = new StateStorage(); - String lastCommand = loadState(); - - return lastCommand; - } - - /** - * Returns the location of the state file. - * - * @return The path of the state file. + * Returns the file path of the StateStorage data file. */ - public static Path getFilePath() { - return FILE_PATH; - } + Path getStateStorageFilePath(); /** - * Returns the location of the state file as a String. + * Returns command box state data from storage. + * Returns {@code Optional.empty()} if storage file is not found. * - * @return The path of the state file as a String. + * @throws DataLoadingException if the loading of data from preference file failed. */ - public static String getFilePathString() { - return filePath; - } + Optional readState() throws DataLoadingException; /** - * Returns the location of the state directory. + * Saves the given string retrieved from the command box to the state storage. * - * @return The path of the state directory. + * @param input retrieved from the command box. + * @throws IOException if there was any problem writing to the file. */ - public static Path getDirectoryPath() { - return DIRECTORY_PATH; - } + void saveState(String input) throws IOException; } diff --git a/src/main/java/seedu/address/storage/Storage.java b/src/main/java/seedu/address/storage/Storage.java index 151f34126de..f9967033496 100644 --- a/src/main/java/seedu/address/storage/Storage.java +++ b/src/main/java/seedu/address/storage/Storage.java @@ -12,7 +12,7 @@ /** * API of the Storage component */ -public interface Storage extends NetConnectStorage, UserPrefsStorage { +public interface Storage extends NetConnectStorage, UserPrefsStorage, StateStorage { @Override Optional readUserPrefs() throws DataLoadingException; @@ -29,4 +29,12 @@ public interface Storage extends NetConnectStorage, UserPrefsStorage { @Override void saveNetConnect(ReadOnlyNetConnect netConnect) throws IOException; + @Override + Optional readState() throws DataLoadingException; + + @Override + void saveState(String input) throws IOException; + + @Override + Path getStateStorageFilePath(); } diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java index d03eb010449..344187cf0f9 100644 --- a/src/main/java/seedu/address/storage/StorageManager.java +++ b/src/main/java/seedu/address/storage/StorageManager.java @@ -19,14 +19,17 @@ public class StorageManager implements Storage { private static final Logger logger = LogsCenter.getLogger(StorageManager.class); private final NetConnectStorage netConnectStorage; private final UserPrefsStorage userPrefsStorage; + private final StateStorage stateStorage; /** * Creates a {@code StorageManager} with the given {@code NetConnectStorage} and * {@code UserPrefStorage}. */ - public StorageManager(NetConnectStorage netConnectStorage, UserPrefsStorage userPrefsStorage) { + public StorageManager(NetConnectStorage netConnectStorage, + UserPrefsStorage userPrefsStorage, StateStorage stateStorage) { this.netConnectStorage = netConnectStorage; this.userPrefsStorage = userPrefsStorage; + this.stateStorage = stateStorage; } // ================ UserPrefs methods ============================== @@ -75,4 +78,20 @@ public void saveNetConnect(ReadOnlyNetConnect netConnect, Path filePath) throws netConnectStorage.saveNetConnect(netConnect, filePath); } + // ================ StateStorage methods ============================== + + @Override + public void saveState(String input) throws IOException { + stateStorage.saveState(input); + } + + @Override + public Optional readState() throws DataLoadingException { + return stateStorage.readState(); + } + + @Override + public Path getStateStorageFilePath() { + return stateStorage.getStateStorageFilePath(); + } } diff --git a/src/main/java/seedu/address/storage/TextStateStorage.java b/src/main/java/seedu/address/storage/TextStateStorage.java new file mode 100644 index 00000000000..f0e36752586 --- /dev/null +++ b/src/main/java/seedu/address/storage/TextStateStorage.java @@ -0,0 +1,147 @@ +package seedu.address.storage; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.logging.Logger; + +import seedu.address.MainApp; +import seedu.address.commons.core.LogsCenter; +import seedu.address.commons.exceptions.DataLoadingException; + +/** + * A class to access state of command box stored in the hard disk as a text file. + */ +public class TextStateStorage implements StateStorage { + private static final String FILE_PATH_STRING = "./data/state.txt"; + private static final Path DIRECTORY_PATH = Paths.get("./data"); + private static final Path FILE_PATH = Paths.get(FILE_PATH_STRING); + private static final Logger logger = LogsCenter.getLogger(MainApp.class); + + /** + * Constructor for the storage. + *

+ * The constructor creates a new file and/or directory if the filepath for ./data/state.txt does not exist. + */ + public TextStateStorage() { + assert !FILE_PATH_STRING.isBlank() : "the file path should not be blank"; + + try { + if (!Files.exists(DIRECTORY_PATH)) { + Files.createDirectories(DIRECTORY_PATH); + } + if (!Files.exists(FILE_PATH)) { + Files.createFile(FILE_PATH); + } + } catch (IOException e) { + logger.info("Error clearing creating state storage: " + e.getMessage()); + } + } + + /** + * Clears all the text in the state storage file. + */ + public static void clearState() { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH_STRING))) { + writer.write(""); + } catch (IOException e) { + logger.info("Error clearing state text: " + e.getMessage()); + logger.info("Starting with a clean slate..."); + deleteStateStorage(); + TextStateStorage textStateStorage = new TextStateStorage(); + } + } + + /** + * Checks if the state storage file exists. + * + * @return True if the file exists, else false. + */ + public static boolean isStateStorageExists() { + return Files.exists(FILE_PATH); + } + + /** + * Deletes the entire state storage file. + */ + public static void deleteStateStorage() { + try { + Files.delete(FILE_PATH); + } catch (IOException e) { + logger.info("Error deleting state file: " + e.getMessage()); + } + } + + /** + * Saves the command to the state storage by writing to the file. + * + * @param input Updated command input (at every change) to be written to the storage file. + */ + public void saveState(String input) throws IOException { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH_STRING))) { + writer.write(input); + } + } + + /** + * Retrieves the past state of the command box if found, else it will return an empty command. + * + * @return The last input in the command box, or and empty string if not found. + * @throws DataLoadingException If the file is not found or cannot be read. + */ + public Optional readState() throws DataLoadingException { + logger.info("Loading state from " + FILE_PATH + "..."); + + String lastCommand = ""; + try (BufferedReader reader = new BufferedReader(new FileReader(FILE_PATH_STRING))) { + String data = reader.readLine(); + + while (data != null) { + lastCommand = lastCommand + data; + data = reader.readLine(); + } + } catch (IOException e) { + throw new DataLoadingException(e); + } + return Optional.of(lastCommand); + } + + + public Path getStateStorageFilePath() { + return FILE_PATH; + } + + + /** + * Returns the location of the state file. + * + * @return The path of the state file. + */ + public static Path getFilePath() { + return FILE_PATH; + } + + /** + * Returns the location of the state file as a String. + * + * @return The path of the state file as a String. + */ + public static String getFilePathString() { + return FILE_PATH_STRING; + } + + /** + * Returns the location of the state directory. + * + * @return The path of the state directory. + */ + public static Path getDirectoryPath() { + return DIRECTORY_PATH; + } +} diff --git a/src/main/java/seedu/address/ui/CommandBox.java b/src/main/java/seedu/address/ui/CommandBox.java index 00bd4f8a483..f96762bcc9a 100644 --- a/src/main/java/seedu/address/ui/CommandBox.java +++ b/src/main/java/seedu/address/ui/CommandBox.java @@ -1,8 +1,8 @@ package seedu.address.ui; -import static seedu.address.storage.StateStorage.getFilePath; -import static seedu.address.storage.StateStorage.getLastCommand; +import static seedu.address.storage.TextStateStorage.getFilePath; +import java.io.IOException; import java.util.logging.Logger; import javafx.collections.ObservableList; @@ -15,7 +15,7 @@ import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.storage.StateStorage; +import seedu.address.storage.TextStateStorage; /** * The UI component that is responsible for receiving user command inputs. @@ -26,7 +26,7 @@ public class CommandBox extends UiPart { private static final String FXML = "CommandBox.fxml"; private static final Logger logger = LogsCenter.getLogger(MainApp.class); private final CommandExecutor commandExecutor; - + private final TextStateStorage stateStorage = new TextStateStorage(); @FXML private TextField commandTextField; @@ -38,7 +38,7 @@ public CommandBox(CommandExecutor commandExecutor) { this.commandExecutor = commandExecutor; try { - commandTextField.setText(getLastCommand()); + commandTextField.setText(stateStorage.readState().orElse("")); commandTextField.end(); } catch (DataLoadingException e) { logger.warning("State file at " + getFilePath() + " could not be loaded." @@ -48,7 +48,11 @@ public CommandBox(CommandExecutor commandExecutor) { commandTextField.textProperty().addListener((observable, oldValue, newValue) -> { setStyleToDefault(); - StateStorage.writeState(newValue); + try { + stateStorage.saveState(newValue); + } catch (IOException e) { + throw new RuntimeException(e); + } }); } diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java index 6fb7ceff45b..16e0e6395fa 100644 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ b/src/test/java/seedu/address/logic/LogicManagerTest.java @@ -23,7 +23,9 @@ import seedu.address.model.UserPrefs; import seedu.address.storage.JsonNetConnectStorage; import seedu.address.storage.JsonUserPrefsStorage; +import seedu.address.storage.StateStorage; import seedu.address.storage.StorageManager; +import seedu.address.storage.TextStateStorage; public class LogicManagerTest { private static final IOException DUMMY_IO_EXCEPTION = new IOException("dummy IO exception"); @@ -40,7 +42,8 @@ public void setUp() { JsonNetConnectStorage netConnectStorage = new JsonNetConnectStorage( temporaryFolder.resolve("netConnect.json")); JsonUserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(temporaryFolder.resolve("userPrefs.json")); - StorageManager storage = new StorageManager(netConnectStorage, userPrefsStorage); + StateStorage stateStorage = new TextStateStorage(); + StorageManager storage = new StorageManager(netConnectStorage, userPrefsStorage, stateStorage); logic = new LogicManager(model, storage); } @@ -154,7 +157,8 @@ public void saveNetConnect(ReadOnlyNetConnect netConnect, Path filePath) JsonUserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage( temporaryFolder.resolve("ExceptionUserPrefs.json")); - StorageManager storage = new StorageManager(netConnectStorage, userPrefsStorage); + StateStorage stateStorage = new TextStateStorage(); + StorageManager storage = new StorageManager(netConnectStorage, userPrefsStorage, stateStorage); logic = new LogicManager(model, storage); diff --git a/src/test/java/seedu/address/storage/StateStorageTest.java b/src/test/java/seedu/address/storage/StateStorageTest.java index 705941d222e..afe86f1d7bc 100644 --- a/src/test/java/seedu/address/storage/StateStorageTest.java +++ b/src/test/java/seedu/address/storage/StateStorageTest.java @@ -1,105 +1,105 @@ -package seedu.address.storage; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static seedu.address.storage.StateStorage.clearState; -import static seedu.address.storage.StateStorage.deleteStateStorage; -import static seedu.address.storage.StateStorage.getLastCommand; -import static seedu.address.storage.StateStorage.loadState; -import static seedu.address.storage.StateStorage.writeState; -import static seedu.address.testutil.Assert.assertThrows; - -import java.nio.file.Paths; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import seedu.address.commons.exceptions.DataLoadingException; - -public class StateStorageTest { - - private StateStorage stateStorage; - - @BeforeEach - public void setUp() { - this.stateStorage = new StateStorage(); - } - @AfterAll - public static void tearDown() { - clearState(); - } - - @Test - public void createStorage_successfullyCreated_throwsNullPointerException() throws NullPointerException { - assertNotNull(stateStorage); - } - - - @Test - public void getFilePath_successfullyReturned() { - assertNotNull(StateStorage.getFilePath()); - assertEquals(Paths.get("./data/state.txt"), StateStorage.getFilePath()); - - } - - @Test - public void getFilePathString_successfullyReturned() { - assertEquals("./data/state.txt", StateStorage.getFilePathString()); - } - - @Test - public void getDirectoryPath_successfullyReturned() { - assertEquals(Paths.get("./data"), StateStorage.getDirectoryPath()); - } - - - @Test - public void loadState_emptyFile_successfullyLoaded() throws DataLoadingException { - clearState(); - String expected = ""; - String actual = loadState(); - assertEquals(expected, actual); - } - - @Test - public void getLastCommand_emptyFile_successfullyLoaded() throws DataLoadingException { - clearState(); - String expected = ""; - String actual = getLastCommand(); - assertEquals(expected, actual); - } - - @Test - public void writeState_successfullyWritten() throws DataLoadingException { - String expected = "test123abc cba321tset"; - writeState(expected); - String actual = loadState(); - assertEquals(expected, actual); - } - - @Test - public void overWriteState_successfullyOverWritten() throws DataLoadingException { - String expected = "test123abc cba321tset"; - writeState(expected); - String actual = loadState(); - assertEquals(expected, actual); - - String overWriteString = "newTest"; - writeState(overWriteString); - String actualOverWrittenString = loadState(); - assertEquals(overWriteString, actualOverWrittenString); - } - - @Test - public void loadFromFile_fileDoesNotExist_handlesDataLoadingException() { - deleteStateStorage(); - assertThrows(DataLoadingException.class, () -> loadState()); - } - - @Test - public void isStateStorageExists_fileDoesNotExist_returnsFalse() { - deleteStateStorage(); - assertEquals(false, StateStorage.isStateStorageExists()); - } -} +//package seedu.address.storage; +// +//import static org.junit.jupiter.api.Assertions.assertEquals; +//import static org.junit.jupiter.api.Assertions.assertNotNull; +//import static seedu.address.storage.StateStorage.clearState; +//import static seedu.address.storage.StateStorage.deleteStateStorage; +//import static seedu.address.storage.StateStorage.getLastCommand; +//import static seedu.address.storage.StateStorage.loadState; +//import static seedu.address.storage.StateStorage.writeState; +//import static seedu.address.testutil.Assert.assertThrows; +// +//import java.nio.file.Paths; +// +//import org.junit.jupiter.api.AfterAll; +//import org.junit.jupiter.api.BeforeEach; +//import org.junit.jupiter.api.Test; +// +//import seedu.address.commons.exceptions.DataLoadingException; +// +//public class StateStorageTest { +// +// private StateStorage stateStorage; +// +// @BeforeEach +// public void setUp() { +// this.stateStorage = new StateStorage(); +// } +// @AfterAll +// public static void tearDown() { +// clearState(); +// } +// +// @Test +// public void createStorage_successfullyCreated_throwsNullPointerException() throws NullPointerException { +// assertNotNull(stateStorage); +// } +// +// +// @Test +// public void getFilePath_successfullyReturned() { +// assertNotNull(StateStorage.getFilePath()); +// assertEquals(Paths.get("./data/state.txt"), StateStorage.getFilePath()); +// +// } +// +// @Test +// public void getFilePathString_successfullyReturned() { +// assertEquals("./data/state.txt", StateStorage.getFilePathString()); +// } +// +// @Test +// public void getDirectoryPath_successfullyReturned() { +// assertEquals(Paths.get("./data"), StateStorage.getDirectoryPath()); +// } +// +// +// @Test +// public void loadState_emptyFile_successfullyLoaded() throws DataLoadingException { +// clearState(); +// String expected = ""; +// String actual = loadState(); +// assertEquals(expected, actual); +// } +// +// @Test +// public void getLastCommand_emptyFile_successfullyLoaded() throws DataLoadingException { +// clearState(); +// String expected = ""; +// String actual = getLastCommand(); +// assertEquals(expected, actual); +// } +// +// @Test +// public void writeState_successfullyWritten() throws DataLoadingException { +// String expected = "test123abc cba321tset"; +// writeState(expected); +// String actual = loadState(); +// assertEquals(expected, actual); +// } +// +// @Test +// public void overWriteState_successfullyOverWritten() throws DataLoadingException { +// String expected = "test123abc cba321tset"; +// writeState(expected); +// String actual = loadState(); +// assertEquals(expected, actual); +// +// String overWriteString = "newTest"; +// writeState(overWriteString); +// String actualOverWrittenString = loadState(); +// assertEquals(overWriteString, actualOverWrittenString); +// } +// +// @Test +// public void loadFromFile_fileDoesNotExist_handlesDataLoadingException() { +// deleteStateStorage(); +// assertThrows(DataLoadingException.class, () -> loadState()); +// } +// +// @Test +// public void isStateStorageExists_fileDoesNotExist_returnsFalse() { +// deleteStateStorage(); +// assertEquals(false, StateStorage.isStateStorageExists()); +// } +//} diff --git a/src/test/java/seedu/address/storage/StorageManagerTest.java b/src/test/java/seedu/address/storage/StorageManagerTest.java index f57ebf1d0f4..3a9bb4787c3 100644 --- a/src/test/java/seedu/address/storage/StorageManagerTest.java +++ b/src/test/java/seedu/address/storage/StorageManagerTest.java @@ -26,7 +26,8 @@ public class StorageManagerTest { public void setUp() { JsonNetConnectStorage netConnectStorage = new JsonNetConnectStorage(getTempFilePath("ab")); JsonUserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(getTempFilePath("prefs")); - storageManager = new StorageManager(netConnectStorage, userPrefsStorage); + StateStorage stateStorage = new TextStateStorage(); + storageManager = new StorageManager(netConnectStorage, userPrefsStorage, stateStorage); } private Path getTempFilePath(String fileName) { From 858b5fbd97fc3e23d539c2f33ece7ee1ea5870b7 Mon Sep 17 00:00:00 2001 From: Tan Jie Ling Date: Sun, 31 Mar 2024 13:23:03 +0800 Subject: [PATCH 08/29] Refactor statestorage under storage --- .../seedu/address/storage/StateStorage.java | 3 +- .../java/seedu/address/storage/Storage.java | 2 +- .../seedu/address/storage/StorageManager.java | 4 +- .../address/storage/TextStateStorage.java | 7 +- .../java/seedu/address/ui/CommandBox.java | 2 +- .../address/storage/StateStorageTest.java | 105 ------------------ .../address/storage/TextStateStorageTest.java | 103 +++++++++++++++++ 7 files changed, 111 insertions(+), 115 deletions(-) delete mode 100644 src/test/java/seedu/address/storage/StateStorageTest.java create mode 100644 src/test/java/seedu/address/storage/TextStateStorageTest.java diff --git a/src/main/java/seedu/address/storage/StateStorage.java b/src/main/java/seedu/address/storage/StateStorage.java index 3b70994fcc2..915d48e4ef0 100644 --- a/src/main/java/seedu/address/storage/StateStorage.java +++ b/src/main/java/seedu/address/storage/StateStorage.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.nio.file.Path; -import java.util.Optional; import seedu.address.commons.exceptions.DataLoadingException; @@ -21,7 +20,7 @@ public interface StateStorage { * * @throws DataLoadingException if the loading of data from preference file failed. */ - Optional readState() throws DataLoadingException; + String readState() throws DataLoadingException; /** * Saves the given string retrieved from the command box to the state storage. diff --git a/src/main/java/seedu/address/storage/Storage.java b/src/main/java/seedu/address/storage/Storage.java index f9967033496..4598dc16dff 100644 --- a/src/main/java/seedu/address/storage/Storage.java +++ b/src/main/java/seedu/address/storage/Storage.java @@ -30,7 +30,7 @@ public interface Storage extends NetConnectStorage, UserPrefsStorage, StateStora void saveNetConnect(ReadOnlyNetConnect netConnect) throws IOException; @Override - Optional readState() throws DataLoadingException; + String readState() throws DataLoadingException; @Override void saveState(String input) throws IOException; diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java index 344187cf0f9..660fb66ad60 100644 --- a/src/main/java/seedu/address/storage/StorageManager.java +++ b/src/main/java/seedu/address/storage/StorageManager.java @@ -82,11 +82,13 @@ public void saveNetConnect(ReadOnlyNetConnect netConnect, Path filePath) throws @Override public void saveState(String input) throws IOException { + logger.fine("Attempting to write to data file: " + getStateStorageFilePath()); stateStorage.saveState(input); } @Override - public Optional readState() throws DataLoadingException { + public String readState() throws DataLoadingException { + logger.fine("Attempting to read data from file: " + stateStorage.getStateStorageFilePath()); return stateStorage.readState(); } diff --git a/src/main/java/seedu/address/storage/TextStateStorage.java b/src/main/java/seedu/address/storage/TextStateStorage.java index f0e36752586..4a5888b5d9d 100644 --- a/src/main/java/seedu/address/storage/TextStateStorage.java +++ b/src/main/java/seedu/address/storage/TextStateStorage.java @@ -8,7 +8,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Optional; import java.util.logging.Logger; import seedu.address.MainApp; @@ -95,9 +94,7 @@ public void saveState(String input) throws IOException { * @return The last input in the command box, or and empty string if not found. * @throws DataLoadingException If the file is not found or cannot be read. */ - public Optional readState() throws DataLoadingException { - logger.info("Loading state from " + FILE_PATH + "..."); - + public String readState() throws DataLoadingException { String lastCommand = ""; try (BufferedReader reader = new BufferedReader(new FileReader(FILE_PATH_STRING))) { String data = reader.readLine(); @@ -109,7 +106,7 @@ public Optional readState() throws DataLoadingException { } catch (IOException e) { throw new DataLoadingException(e); } - return Optional.of(lastCommand); + return lastCommand; } diff --git a/src/main/java/seedu/address/ui/CommandBox.java b/src/main/java/seedu/address/ui/CommandBox.java index f96762bcc9a..3adc5c21cfc 100644 --- a/src/main/java/seedu/address/ui/CommandBox.java +++ b/src/main/java/seedu/address/ui/CommandBox.java @@ -38,7 +38,7 @@ public CommandBox(CommandExecutor commandExecutor) { this.commandExecutor = commandExecutor; try { - commandTextField.setText(stateStorage.readState().orElse("")); + commandTextField.setText(stateStorage.readState()); commandTextField.end(); } catch (DataLoadingException e) { logger.warning("State file at " + getFilePath() + " could not be loaded." diff --git a/src/test/java/seedu/address/storage/StateStorageTest.java b/src/test/java/seedu/address/storage/StateStorageTest.java deleted file mode 100644 index afe86f1d7bc..00000000000 --- a/src/test/java/seedu/address/storage/StateStorageTest.java +++ /dev/null @@ -1,105 +0,0 @@ -//package seedu.address.storage; -// -//import static org.junit.jupiter.api.Assertions.assertEquals; -//import static org.junit.jupiter.api.Assertions.assertNotNull; -//import static seedu.address.storage.StateStorage.clearState; -//import static seedu.address.storage.StateStorage.deleteStateStorage; -//import static seedu.address.storage.StateStorage.getLastCommand; -//import static seedu.address.storage.StateStorage.loadState; -//import static seedu.address.storage.StateStorage.writeState; -//import static seedu.address.testutil.Assert.assertThrows; -// -//import java.nio.file.Paths; -// -//import org.junit.jupiter.api.AfterAll; -//import org.junit.jupiter.api.BeforeEach; -//import org.junit.jupiter.api.Test; -// -//import seedu.address.commons.exceptions.DataLoadingException; -// -//public class StateStorageTest { -// -// private StateStorage stateStorage; -// -// @BeforeEach -// public void setUp() { -// this.stateStorage = new StateStorage(); -// } -// @AfterAll -// public static void tearDown() { -// clearState(); -// } -// -// @Test -// public void createStorage_successfullyCreated_throwsNullPointerException() throws NullPointerException { -// assertNotNull(stateStorage); -// } -// -// -// @Test -// public void getFilePath_successfullyReturned() { -// assertNotNull(StateStorage.getFilePath()); -// assertEquals(Paths.get("./data/state.txt"), StateStorage.getFilePath()); -// -// } -// -// @Test -// public void getFilePathString_successfullyReturned() { -// assertEquals("./data/state.txt", StateStorage.getFilePathString()); -// } -// -// @Test -// public void getDirectoryPath_successfullyReturned() { -// assertEquals(Paths.get("./data"), StateStorage.getDirectoryPath()); -// } -// -// -// @Test -// public void loadState_emptyFile_successfullyLoaded() throws DataLoadingException { -// clearState(); -// String expected = ""; -// String actual = loadState(); -// assertEquals(expected, actual); -// } -// -// @Test -// public void getLastCommand_emptyFile_successfullyLoaded() throws DataLoadingException { -// clearState(); -// String expected = ""; -// String actual = getLastCommand(); -// assertEquals(expected, actual); -// } -// -// @Test -// public void writeState_successfullyWritten() throws DataLoadingException { -// String expected = "test123abc cba321tset"; -// writeState(expected); -// String actual = loadState(); -// assertEquals(expected, actual); -// } -// -// @Test -// public void overWriteState_successfullyOverWritten() throws DataLoadingException { -// String expected = "test123abc cba321tset"; -// writeState(expected); -// String actual = loadState(); -// assertEquals(expected, actual); -// -// String overWriteString = "newTest"; -// writeState(overWriteString); -// String actualOverWrittenString = loadState(); -// assertEquals(overWriteString, actualOverWrittenString); -// } -// -// @Test -// public void loadFromFile_fileDoesNotExist_handlesDataLoadingException() { -// deleteStateStorage(); -// assertThrows(DataLoadingException.class, () -> loadState()); -// } -// -// @Test -// public void isStateStorageExists_fileDoesNotExist_returnsFalse() { -// deleteStateStorage(); -// assertEquals(false, StateStorage.isStateStorageExists()); -// } -//} diff --git a/src/test/java/seedu/address/storage/TextStateStorageTest.java b/src/test/java/seedu/address/storage/TextStateStorageTest.java new file mode 100644 index 00000000000..27b7be36e8f --- /dev/null +++ b/src/test/java/seedu/address/storage/TextStateStorageTest.java @@ -0,0 +1,103 @@ +package seedu.address.storage; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static seedu.address.storage.TextStateStorage.clearState; +import static seedu.address.storage.TextStateStorage.deleteStateStorage; +import static seedu.address.testutil.Assert.assertThrows; + +import java.io.IOException; +import java.nio.file.Paths; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import seedu.address.commons.exceptions.DataLoadingException; + +public class TextStateStorageTest { + + private TextStateStorage textStateStorage; + + @BeforeEach + public void setUp() { + this.textStateStorage = new TextStateStorage(); + } + @AfterAll + public static void tearDown() { + clearState(); + } + + @Test + public void createStorage_successfullyCreated_throwsNullPointerException() throws NullPointerException { + assertNotNull(textStateStorage); + } + + + @Test + public void getFilePath_successfullyReturned() { + assertNotNull(TextStateStorage.getFilePath()); + assertEquals(Paths.get("./data/state.txt"), TextStateStorage.getFilePath()); + + } + + @Test + public void getFilePathString_successfullyReturned() { + assertEquals("./data/state.txt", TextStateStorage.getFilePathString()); + } + + @Test + public void getDirectoryPath_successfullyReturned() { + assertEquals(Paths.get("./data"), TextStateStorage.getDirectoryPath()); + } + + + @Test + public void loadState_emptyFile_successfullyLoaded() throws DataLoadingException { + clearState(); + String expected = ""; + String actual = textStateStorage.readState(); + assertEquals(expected, actual); + } + + @Test + public void getLastCommand_emptyFile_successfullyLoaded() throws DataLoadingException { + clearState(); + String expected = ""; + String actual = textStateStorage.readState(); + assertEquals(expected, actual); + } + + @Test + public void writeState_successfullyWritten() throws IOException, DataLoadingException { + String expected = "test123abc cba321tset"; + textStateStorage.saveState(expected); + String actual = textStateStorage.readState(); + assertEquals(expected, actual); + } + + @Test + public void overWriteState_successfullyOverWritten() throws DataLoadingException, IOException { + String expected = "test123abc cba321tset"; + textStateStorage.saveState(expected); + String actual = textStateStorage.readState(); + assertEquals(expected, actual); + + String overWriteString = "newTest"; + textStateStorage.saveState(overWriteString); + String actualOverWrittenString = textStateStorage.readState(); + assertEquals(overWriteString, actualOverWrittenString); + } + + @Test + public void loadFromFile_fileDoesNotExist_handlesDataLoadingException() { + deleteStateStorage(); + assertThrows(DataLoadingException.class, () -> textStateStorage.readState()); + } + + @Test + public void isStateStorageExists_fileDoesNotExist_returnsFalse() { + deleteStateStorage(); + assertEquals(false, TextStateStorage.isStateStorageExists()); + } +} From 97a07dd6bb6789135007ffb4b56cd5d58bd51c00 Mon Sep 17 00:00:00 2001 From: Tan Jie Ling Date: Sun, 31 Mar 2024 13:52:46 +0800 Subject: [PATCH 09/29] Add more tests --- .../address/storage/TextStateStorage.java | 29 +++++-------------- .../java/seedu/address/ui/CommandBox.java | 4 +-- .../address/storage/StorageManagerTest.java | 24 +++++++++++++++ .../address/storage/TextStateStorageTest.java | 14 ++++----- 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/main/java/seedu/address/storage/TextStateStorage.java b/src/main/java/seedu/address/storage/TextStateStorage.java index 4a5888b5d9d..0b251be03ba 100644 --- a/src/main/java/seedu/address/storage/TextStateStorage.java +++ b/src/main/java/seedu/address/storage/TextStateStorage.java @@ -46,15 +46,10 @@ public TextStateStorage() { /** * Clears all the text in the state storage file. */ - public static void clearState() { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH_STRING))) { - writer.write(""); - } catch (IOException e) { - logger.info("Error clearing state text: " + e.getMessage()); - logger.info("Starting with a clean slate..."); - deleteStateStorage(); - TextStateStorage textStateStorage = new TextStateStorage(); - } + public static void clearState() throws IOException { + Path filePath = Paths.get(FILE_PATH_STRING); + Files.delete(filePath); + Files.createFile(filePath); } /** @@ -69,12 +64,8 @@ public static boolean isStateStorageExists() { /** * Deletes the entire state storage file. */ - public static void deleteStateStorage() { - try { - Files.delete(FILE_PATH); - } catch (IOException e) { - logger.info("Error deleting state file: " + e.getMessage()); - } + public static void deleteStateStorage() throws IOException { + Files.delete(FILE_PATH); } /** @@ -109,18 +100,12 @@ public String readState() throws DataLoadingException { return lastCommand; } - - public Path getStateStorageFilePath() { - return FILE_PATH; - } - - /** * Returns the location of the state file. * * @return The path of the state file. */ - public static Path getFilePath() { + public Path getStateStorageFilePath() { return FILE_PATH; } diff --git a/src/main/java/seedu/address/ui/CommandBox.java b/src/main/java/seedu/address/ui/CommandBox.java index 3adc5c21cfc..478538f10e5 100644 --- a/src/main/java/seedu/address/ui/CommandBox.java +++ b/src/main/java/seedu/address/ui/CommandBox.java @@ -1,7 +1,5 @@ package seedu.address.ui; -import static seedu.address.storage.TextStateStorage.getFilePath; - import java.io.IOException; import java.util.logging.Logger; @@ -41,7 +39,7 @@ public CommandBox(CommandExecutor commandExecutor) { commandTextField.setText(stateStorage.readState()); commandTextField.end(); } catch (DataLoadingException e) { - logger.warning("State file at " + getFilePath() + " could not be loaded." + logger.warning("State file at " + stateStorage.getStateStorageFilePath() + " could not be loaded." + " Starting with an empty command box."); } diff --git a/src/test/java/seedu/address/storage/StorageManagerTest.java b/src/test/java/seedu/address/storage/StorageManagerTest.java index 3a9bb4787c3..25ca9ff872e 100644 --- a/src/test/java/seedu/address/storage/StorageManagerTest.java +++ b/src/test/java/seedu/address/storage/StorageManagerTest.java @@ -50,6 +50,11 @@ public void prefsReadSave() throws Exception { assertEquals(original, retrieved); } + @Test + public void getUserPrefsFilePath() { + assertNotNull(storageManager.getUserPrefsFilePath()); + } + @Test public void netConnectReadSave() throws Exception { /* @@ -70,4 +75,23 @@ public void getNetConnectFilePath() { assertNotNull(storageManager.getNetConnectFilePath()); } + @Test + public void stateReadSave() throws Exception { + /* + * Note: This is an integration test that verifies the StorageManager is + * properly wired to the + * {@link TextStateStorage} class. + * More extensive testing of state saving/reading is done in {@link + * TextStateStorageTest} class. + */ + String original = "dummy state"; + storageManager.saveState(original); + String retrieved = storageManager.readState(); + assertEquals(original, retrieved); + } + + @Test + public void getStateStorageFilePath() { + assertNotNull(storageManager.getStateStorageFilePath()); + } } diff --git a/src/test/java/seedu/address/storage/TextStateStorageTest.java b/src/test/java/seedu/address/storage/TextStateStorageTest.java index 27b7be36e8f..d9fd12ce5a4 100644 --- a/src/test/java/seedu/address/storage/TextStateStorageTest.java +++ b/src/test/java/seedu/address/storage/TextStateStorageTest.java @@ -24,7 +24,7 @@ public void setUp() { this.textStateStorage = new TextStateStorage(); } @AfterAll - public static void tearDown() { + public static void tearDown() throws IOException { clearState(); } @@ -36,8 +36,8 @@ public void createStorage_successfullyCreated_throwsNullPointerException() throw @Test public void getFilePath_successfullyReturned() { - assertNotNull(TextStateStorage.getFilePath()); - assertEquals(Paths.get("./data/state.txt"), TextStateStorage.getFilePath()); + assertNotNull(textStateStorage.getStateStorageFilePath()); + assertEquals(Paths.get("./data/state.txt"), textStateStorage.getStateStorageFilePath()); } @@ -53,7 +53,7 @@ public void getDirectoryPath_successfullyReturned() { @Test - public void loadState_emptyFile_successfullyLoaded() throws DataLoadingException { + public void loadState_emptyFile_successfullyLoaded() throws DataLoadingException, IOException { clearState(); String expected = ""; String actual = textStateStorage.readState(); @@ -61,7 +61,7 @@ public void loadState_emptyFile_successfullyLoaded() throws DataLoadingException } @Test - public void getLastCommand_emptyFile_successfullyLoaded() throws DataLoadingException { + public void getLastCommand_emptyFile_successfullyLoaded() throws DataLoadingException, IOException { clearState(); String expected = ""; String actual = textStateStorage.readState(); @@ -90,13 +90,13 @@ public void overWriteState_successfullyOverWritten() throws DataLoadingException } @Test - public void loadFromFile_fileDoesNotExist_handlesDataLoadingException() { + public void loadFromFile_fileDoesNotExist_handlesDataLoadingException() throws IOException { deleteStateStorage(); assertThrows(DataLoadingException.class, () -> textStateStorage.readState()); } @Test - public void isStateStorageExists_fileDoesNotExist_returnsFalse() { + public void isStateStorageExists_fileDoesNotExist_returnsFalse() throws IOException { deleteStateStorage(); assertEquals(false, TextStateStorage.isStateStorageExists()); } From 9c186fe870fab90545e581dd3a8d202b6d742e72 Mon Sep 17 00:00:00 2001 From: Shaun Lee Date: Tue, 2 Apr 2024 15:26:53 +0800 Subject: [PATCH 10/29] Integrate findrole into find command --- .../address/commons/util/StringUtil.java | 8 +- .../address/logic/commands/FindCommand.java | 26 +++-- .../logic/commands/FindRoleCommand.java | 60 ----------- .../logic/parser/AddCommandParser.java | 2 +- .../logic/parser/FindCommandParser.java | 10 +- .../logic/parser/FindRoleCommandParser.java | 41 ------- .../logic/parser/NetConnectParser.java | 4 - .../seedu/address/model/ModelManager.java | 2 +- .../seedu/address/model/person/Person.java | 7 +- .../address/model/person/filter/Filter.java | 9 +- ...java => RoleMatchesKeywordsPredicate.java} | 16 +-- .../address/commons/util/StringUtilTest.java | 2 +- .../commands/AddCommandIntegrationTest.java | 8 +- .../logic/commands/FindCommandTest.java | 5 +- .../logic/commands/FindRoleCommandTest.java | 101 ------------------ .../logic/parser/FindCommandParserTest.java | 41 ++++++- .../parser/FindRoleCommandParserTest.java | 37 ------- .../logic/parser/NetConnectParserTest.java | 10 -- .../RemarkContainsKeywordsPredicateTest.java | 15 +++ ... => RoleMatchesKeywordsPredicateTest.java} | 32 +++--- 20 files changed, 129 insertions(+), 307 deletions(-) delete mode 100644 src/main/java/seedu/address/logic/commands/FindRoleCommand.java delete mode 100644 src/main/java/seedu/address/logic/parser/FindRoleCommandParser.java rename src/main/java/seedu/address/model/person/filter/{RoleContainsKeywordsPredicate.java => RoleMatchesKeywordsPredicate.java} (72%) delete mode 100644 src/test/java/seedu/address/logic/commands/FindRoleCommandTest.java delete mode 100644 src/test/java/seedu/address/logic/parser/FindRoleCommandParserTest.java rename src/test/java/seedu/address/model/person/filter/{RoleContainsKeywordsPredicateTest.java => RoleMatchesKeywordsPredicateTest.java} (65%) diff --git a/src/main/java/seedu/address/commons/util/StringUtil.java b/src/main/java/seedu/address/commons/util/StringUtil.java index d6f527c33d4..d233f930d88 100644 --- a/src/main/java/seedu/address/commons/util/StringUtil.java +++ b/src/main/java/seedu/address/commons/util/StringUtil.java @@ -42,12 +42,12 @@ public static boolean containsWordIgnoreCase(String sentence, String word) { /** * Returns true if the {@code source} contains the {@code target}. - * Ignores case, and a partial match also returns true. + * Ignores case, and a partial match returns true. *
examples:

-     *       hasPartialMatchIgnoreCase("ABc def", "abc") == true
-     *       hasPartialMatchIgnoreCase("ABc def", "DEF") == true
+     *       hasPartialMatchIgnoreCase("abc", "ABc def") == true
+     *       hasPartialMatchIgnoreCase("DEF", "ABc def") == true
      *       // partial match, compared to return false in {@link #containsWordIgnoreCase(String, String)}
-     *       hasPartialMatchIgnoreCase("ABc def", "AB") == true
+     *       hasPartialMatchIgnoreCase("AB", "ABc def") == true
      *       
* * @param target cannot be null, cannot be empty diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/address/logic/commands/FindCommand.java index 74a9c9a11f2..b23413eaf99 100644 --- a/src/main/java/seedu/address/logic/commands/FindCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindCommand.java @@ -1,26 +1,36 @@ package seedu.address.logic.commands; import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ROLE; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import seedu.address.commons.util.ToStringBuilder; import seedu.address.logic.Messages; import seedu.address.model.Model; import seedu.address.model.person.Person; -import seedu.address.model.person.filter.Filter; import seedu.address.model.person.filter.NetConnectPredicate; /** - * Finds and lists all persons in address book whose name contains any of the argument keywords. - * Keyword matching is case insensitive. + * Finds and lists all persons in NetConnect whose information matches any of the given arguments. + * Keyword matching is case-insensitive. + * Find command supports finding by: name, tag, and role. */ public class FindCommand extends Command { public static final String COMMAND_WORD = "find"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain any of " - + "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n" - + "Parameters: KEYWORD [MORE_KEYWORDS]...\n" - + "Example: " + COMMAND_WORD + " alice bob charlie"; + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Finds all persons whose information matches any of the given arguments.\n" + + "Only one type of argument can be given per " + COMMAND_WORD + " command.\n" + + "Parameters: " + + "[" + PREFIX_NAME + "NAME]... " + + "[" + PREFIX_TAG + "TAG]... " + + "[" + PREFIX_ROLE + "ROLE]... \n" + + "Examples: \n" + + COMMAND_WORD + " n/alice n/bob n/charlie\n" + + COMMAND_WORD + " t/friends t/colleagues\n" + + COMMAND_WORD + " role/client"; private final NetConnectPredicate predicate; @@ -33,7 +43,7 @@ public CommandResult execute(Model model) { requireNonNull(model); model.stackFilters(predicate); String output = String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size()) - + "\n" + String.format(Filter.MESSAGE_FILTERS_APPLIED, model.printFilters()); + + "\n" + model.printFilters(); return new CommandResult(output); } diff --git a/src/main/java/seedu/address/logic/commands/FindRoleCommand.java b/src/main/java/seedu/address/logic/commands/FindRoleCommand.java deleted file mode 100644 index 654f99e744f..00000000000 --- a/src/main/java/seedu/address/logic/commands/FindRoleCommand.java +++ /dev/null @@ -1,60 +0,0 @@ -package seedu.address.logic.commands; - -import static java.util.Objects.requireNonNull; - -import seedu.address.commons.util.ToStringBuilder; -import seedu.address.logic.Messages; -import seedu.address.model.Model; -import seedu.address.model.person.filter.RoleContainsKeywordsPredicate; - - -/** - * Finds and lists all persons in address book whose role matches the argument roles. - */ -public class FindRoleCommand extends Command { - - public static final String COMMAND_WORD = "findrole"; - - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose role matches the specified " - + "role and displays them as a list with index numbers.\n" - + "A role must be either CLIENT, SUPPLIER or EMPLOYEE. \n" - + "Parameters: ROLE [ROLES]...\n" - + "Example: " + COMMAND_WORD + " CLIENT SUPPLIER"; - - private final RoleContainsKeywordsPredicate predicate; - - public FindRoleCommand(RoleContainsKeywordsPredicate predicate) { - this.predicate = predicate; - } - - @Override - public CommandResult execute(Model model) { - requireNonNull(model); - model.clearFilter(); - model.stackFilters(predicate); - return new CommandResult( - String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size())); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof FindRoleCommand)) { - return false; - } - - FindRoleCommand otherFindRoleCommand = (FindRoleCommand) other; - return predicate.equals(otherFindRoleCommand.predicate); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .add("predicate", predicate) - .toString(); - } -} diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java index 5ebf7d03f1a..cf10476b712 100644 --- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddCommandParser.java @@ -103,7 +103,7 @@ public AddCommand parse(String args) throws ParseException { person = new Supplier(name, phone, email, address, remark, tagList, supplierProducts, termsOfService); break; default: - throw new ParseException("Invalid role specified. Must be one of: client, employee, supplier."); + throw new ParseException(Person.MESSAGE_ROLE_CONSTRAINTS); } return new AddCommand(person); } diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/address/logic/parser/FindCommandParser.java index e34870c4832..b28c673ebf0 100644 --- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FindCommandParser.java @@ -3,6 +3,7 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_ROLE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import java.util.List; @@ -13,6 +14,7 @@ import seedu.address.model.person.Person; import seedu.address.model.person.filter.NameContainsKeywordsPredicate; import seedu.address.model.person.filter.NetConnectPredicate; +import seedu.address.model.person.filter.RoleMatchesKeywordsPredicate; import seedu.address.model.person.filter.TagsContainsKeywordsPredicate; import seedu.address.model.tag.Tag; @@ -29,7 +31,7 @@ public class FindCommandParser implements Parser { */ public FindCommand parse(String args) throws ParseException { requireNonNull(args); - ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_TAG); + ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_TAG, PREFIX_ROLE); argMultimap.verifyOnlyOnePrefix(); return new FindCommand(createPredicate(argMultimap)); @@ -55,6 +57,12 @@ private static NetConnectPredicate createPredicate( throw new ParseException(Tag.MESSAGE_CONSTRAINTS); } return new TagsContainsKeywordsPredicate(tags); + } else if (argMultimap.getValue(PREFIX_ROLE).isPresent()) { + List roles = argMultimap.getAllValues(PREFIX_ROLE); + if (!roles.stream().allMatch(Person::isValidRole)) { + throw new ParseException(Person.MESSAGE_ROLE_CONSTRAINTS); + } + return new RoleMatchesKeywordsPredicate(roles); } else { // no field provided throw new ParseException( diff --git a/src/main/java/seedu/address/logic/parser/FindRoleCommandParser.java b/src/main/java/seedu/address/logic/parser/FindRoleCommandParser.java deleted file mode 100644 index ff3c23d3b8e..00000000000 --- a/src/main/java/seedu/address/logic/parser/FindRoleCommandParser.java +++ /dev/null @@ -1,41 +0,0 @@ -package seedu.address.logic.parser; - -import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.model.person.Person.isValidRole; - -import java.util.Arrays; - -import seedu.address.logic.commands.FindRoleCommand; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.filter.RoleContainsKeywordsPredicate; - -/** - * Parses input arguments and creates a new FindRoleCommand object - */ -public class FindRoleCommandParser implements Parser { - - /** - * Parses the given {@code String} of arguments in the context of the FindRoleCommand - * and returns a FindRoleCommand object for execution. - * - * @throws ParseException if the user input does not conform the expected format - */ - public FindRoleCommand parse(String args) throws ParseException { - String trimmedArgs = args.trim(); - if (trimmedArgs.isEmpty()) { - throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindRoleCommand.MESSAGE_USAGE)); - } - - String[] roleKeywords = trimmedArgs.split("\\s+"); - // Check if all roleKeywords in input are valid - for (String roleKeyword : roleKeywords) { - if (!isValidRole(roleKeyword)) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindRoleCommand.MESSAGE_USAGE)); - } - } - - return new FindRoleCommand(new RoleContainsKeywordsPredicate(Arrays.asList(roleKeywords))); - } - -} diff --git a/src/main/java/seedu/address/logic/parser/NetConnectParser.java b/src/main/java/seedu/address/logic/parser/NetConnectParser.java index 83c0da027cf..9105bc5574b 100644 --- a/src/main/java/seedu/address/logic/parser/NetConnectParser.java +++ b/src/main/java/seedu/address/logic/parser/NetConnectParser.java @@ -18,7 +18,6 @@ import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.FindNumCommand; import seedu.address.logic.commands.FindRemCommand; -import seedu.address.logic.commands.FindRoleCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.RemarkCommand; @@ -80,9 +79,6 @@ public Command parseCommand(String userInput) throws ParseException { case FindRemCommand.COMMAND_WORD: return new FindRemCommandParser().parse(arguments); - case FindRoleCommand.COMMAND_WORD: - return new FindRoleCommandParser().parse(arguments); - case RemarkCommand.COMMAND_WORD: return new RemarkCommandParser().parse(arguments); diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index c6441235dbb..c857a62c8a7 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -162,7 +162,7 @@ public void stackFilters(NetConnectPredicate predicate) { @Override public String printFilters() { - return filter.formatFilter(); + return String.format(Filter.MESSAGE_FILTERS_APPLIED, filter.size(), filter.formatFilter()); } @Override diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java index 2ee28f4e007..22de6fcdc76 100644 --- a/src/main/java/seedu/address/model/person/Person.java +++ b/src/main/java/seedu/address/model/person/Person.java @@ -16,6 +16,9 @@ */ public abstract class Person { + public static final String MESSAGE_ROLE_CONSTRAINTS = "Invalid role specified. " + + "Must be one of: client, employee, supplier."; + // Unique id protected final Id id; @@ -98,7 +101,9 @@ public Set getTags() { * @return {@code true} if the role is valid, {@code false} otherwise. */ public static boolean isValidRole(String role) { - return role.equals("employee") || role.equals("client") || role.equals("supplier"); + return role.equalsIgnoreCase("employee") + || role.equalsIgnoreCase("client") + || role.equalsIgnoreCase("supplier"); } /** diff --git a/src/main/java/seedu/address/model/person/filter/Filter.java b/src/main/java/seedu/address/model/person/filter/Filter.java index 884f95c2432..bd3fa98deaf 100644 --- a/src/main/java/seedu/address/model/person/filter/Filter.java +++ b/src/main/java/seedu/address/model/person/filter/Filter.java @@ -16,7 +16,7 @@ */ public class Filter extends NetConnectPredicate { - public static final String MESSAGE_FILTERS_APPLIED = "Current filters applied:\n%1$s"; + public static final String MESSAGE_FILTERS_APPLIED = "%1$d filter(s) applied:\n%2$s"; /** Cached empty filter object */ private static final Filter EMPTY_FILTER = new Filter(List.of()); @@ -60,6 +60,13 @@ public Filter add(NetConnectPredicate p) { return new Filter(Collections.unmodifiableList(newFilters)); } + /** + * Returns the count of predicates in the {@code Filter}. + */ + public int size() { + return filters.size(); + } + /** * Formats the filter in a user-readable format. */ diff --git a/src/main/java/seedu/address/model/person/filter/RoleContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/person/filter/RoleMatchesKeywordsPredicate.java similarity index 72% rename from src/main/java/seedu/address/model/person/filter/RoleContainsKeywordsPredicate.java rename to src/main/java/seedu/address/model/person/filter/RoleMatchesKeywordsPredicate.java index 3112b5e587d..2dd8715ba78 100644 --- a/src/main/java/seedu/address/model/person/filter/RoleContainsKeywordsPredicate.java +++ b/src/main/java/seedu/address/model/person/filter/RoleMatchesKeywordsPredicate.java @@ -10,10 +10,10 @@ import seedu.address.model.person.Person; /** - * Represents a predicate that checks if a person's role contains any of the specified keywords. + * Represents a predicate that checks if a person's role matches any of the specified keywords. * This predicate is used to filter a list of persons based on their roles. */ -public class RoleContainsKeywordsPredicate extends NetConnectPredicate { +public class RoleMatchesKeywordsPredicate extends NetConnectPredicate { private final List keywords; /** @@ -21,7 +21,7 @@ public class RoleContainsKeywordsPredicate extends NetConnectPredicate { * * @param keywords The list of keywords to match against the person's role. */ - public RoleContainsKeywordsPredicate(List keywords) { + public RoleMatchesKeywordsPredicate(List keywords) { this.keywords = Collections.unmodifiableList(keywords); } @@ -30,12 +30,6 @@ public String formatFilter() { return keywords.stream().map(s -> PREFIX_ROLE + s).collect(Collectors.joining(" ")); } - /** - * Tests if the given person's role contains any of the keywords. - * - * @param person The person to test. - * @return {@code true} if the person's role contains any of the keywords, {@code false} otherwise. - */ @Override public boolean test(Person person) { return keywords.stream().anyMatch(person.getRole()::equalsIgnoreCase); @@ -52,10 +46,10 @@ public boolean equals(Object other) { if (this == other) { return true; } - if (!(other instanceof RoleContainsKeywordsPredicate)) { + if (!(other instanceof RoleMatchesKeywordsPredicate)) { return false; } - RoleContainsKeywordsPredicate otherPredicate = (RoleContainsKeywordsPredicate) other; + RoleMatchesKeywordsPredicate otherPredicate = (RoleMatchesKeywordsPredicate) other; return keywords.equals(otherPredicate.keywords); } diff --git a/src/test/java/seedu/address/commons/util/StringUtilTest.java b/src/test/java/seedu/address/commons/util/StringUtilTest.java index 6f1e14818de..148542925be 100644 --- a/src/test/java/seedu/address/commons/util/StringUtilTest.java +++ b/src/test/java/seedu/address/commons/util/StringUtilTest.java @@ -210,7 +210,7 @@ public void hasPartialMatchIgnoreCase_validInputs_correctResult() { assertTrue(StringUtil.hasPartialMatchIgnoreCase("bB CCc@1", "aaa bBb ccc@1")); // Last characters (boundary case) assertTrue(StringUtil.hasPartialMatchIgnoreCase("aaa", - " AAA bBb ccc ")); // Sentence has extra spaces + " AAA bBb ccc ")); // Source has extra spaces assertTrue(StringUtil.hasPartialMatchIgnoreCase("aaa", "Aaa")); // One word in source and target (boundary case) diff --git a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java index d5a8d9870b9..3d9c97f3c61 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java +++ b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java @@ -14,7 +14,7 @@ import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; import seedu.address.model.person.Person; -import seedu.address.model.person.filter.RoleContainsKeywordsPredicate; +import seedu.address.model.person.filter.RoleMatchesKeywordsPredicate; import seedu.address.testutil.ClientBuilder; import seedu.address.testutil.EmployeeBuilder; import seedu.address.testutil.SupplierBuilder; @@ -70,21 +70,21 @@ public void execute_newSupplier_success() { @Test public void execute_duplicateClient_throwsCommandException() { - model.stackFilters(new RoleContainsKeywordsPredicate(Collections.singletonList("client"))); + model.stackFilters(new RoleMatchesKeywordsPredicate(Collections.singletonList("client"))); Person clientInList = model.getFilteredPersonList().get(0); assertCommandFailure(new AddCommand(clientInList), model, AddCommand.MESSAGE_DUPLICATE_PERSON); } @Test public void execute_duplicateEmployee_throwsCommandException() { - model.stackFilters(new RoleContainsKeywordsPredicate(Collections.singletonList("employee"))); + model.stackFilters(new RoleMatchesKeywordsPredicate(Collections.singletonList("employee"))); Person employeeInList = model.getFilteredPersonList().get(0); assertCommandFailure(new AddCommand(employeeInList), model, AddCommand.MESSAGE_DUPLICATE_PERSON); } @Test public void execute_duplicateSupplier_throwsCommandException() { - model.stackFilters(new RoleContainsKeywordsPredicate(Collections.singletonList("supplier"))); + model.stackFilters(new RoleMatchesKeywordsPredicate(Collections.singletonList("supplier"))); Person supplierInList = model.getFilteredPersonList().get(0); assertCommandFailure(new AddCommand(supplierInList), model, AddCommand.MESSAGE_DUPLICATE_PERSON); } diff --git a/src/test/java/seedu/address/logic/commands/FindCommandTest.java b/src/test/java/seedu/address/logic/commands/FindCommandTest.java index c365206d222..c833e35886b 100644 --- a/src/test/java/seedu/address/logic/commands/FindCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/FindCommandTest.java @@ -18,7 +18,6 @@ import seedu.address.model.Model; import seedu.address.model.ModelManager; import seedu.address.model.UserPrefs; -import seedu.address.model.person.filter.Filter; import seedu.address.model.person.filter.NameContainsKeywordsPredicate; /** @@ -62,7 +61,7 @@ public void execute_zeroKeywords_noPersonFound() { FindCommand command = new FindCommand(predicate); expectedModel.stackFilters(predicate); String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0) - + "\n" + String.format(Filter.MESSAGE_FILTERS_APPLIED, expectedModel.printFilters()); + + "\n" + expectedModel.printFilters(); assertCommandSuccess(command, model, expectedMessage, expectedModel); assertEquals(Collections.emptyList(), model.getFilteredPersonList()); } @@ -73,7 +72,7 @@ public void execute_multipleKeywords_multiplePersonsFound() { FindCommand command = new FindCommand(predicate); expectedModel.stackFilters(predicate); String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 2) - + "\n" + String.format(Filter.MESSAGE_FILTERS_APPLIED, expectedModel.printFilters()); + + "\n" + expectedModel.printFilters(); assertCommandSuccess(command, model, expectedMessage, expectedModel); assertEquals(Arrays.asList(ELLE, FIONA), model.getFilteredPersonList()); } diff --git a/src/test/java/seedu/address/logic/commands/FindRoleCommandTest.java b/src/test/java/seedu/address/logic/commands/FindRoleCommandTest.java deleted file mode 100644 index 8da31708ab3..00000000000 --- a/src/test/java/seedu/address/logic/commands/FindRoleCommandTest.java +++ /dev/null @@ -1,101 +0,0 @@ -package seedu.address.logic.commands; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static seedu.address.logic.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalPersons.ALICE; -import static seedu.address.testutil.TypicalPersons.AMY; -import static seedu.address.testutil.TypicalPersons.BENSON; -import static seedu.address.testutil.TypicalPersons.BOB; -import static seedu.address.testutil.TypicalPersons.DANIEL; -import static seedu.address.testutil.TypicalPersons.ELLE; -import static seedu.address.testutil.TypicalPersons.getTypicalNetConnect; - -import java.util.Arrays; -import java.util.Collections; - -import org.junit.jupiter.api.Test; - -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.UserPrefs; -import seedu.address.model.person.filter.RoleContainsKeywordsPredicate; - -public class FindRoleCommandTest { - private final Model model = new ModelManager(getTypicalNetConnect(), new UserPrefs()); - private final Model expectedModel = new ModelManager(getTypicalNetConnect(), new UserPrefs()); - - @Test - public void equals() { - RoleContainsKeywordsPredicate firstPredicate = - new RoleContainsKeywordsPredicate(Collections.singletonList("client")); - RoleContainsKeywordsPredicate secondPredicate = - new RoleContainsKeywordsPredicate(Collections.singletonList("supplier")); - - FindRoleCommand findRoleFirstCommand = new FindRoleCommand(firstPredicate); - FindRoleCommand findRoleSecondCommand = new FindRoleCommand(secondPredicate); - - // same object -> returns true - assertEquals(findRoleFirstCommand, findRoleFirstCommand); - - // same values -> returns true - FindRoleCommand findRoleFirstCommandCopy = new FindRoleCommand(firstPredicate); - assertEquals(findRoleFirstCommand, findRoleFirstCommandCopy); - - // different types -> returns false - assertFalse(findRoleFirstCommand.equals(1)); - - // null -> returns false - assertFalse(findRoleFirstCommand.equals(null)); - - // different person -> returns false - assertFalse(findRoleFirstCommand.equals(findRoleSecondCommand)); - } - - @Test - public void execute_zeroRoles_noPersonFound() { - String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0); - RoleContainsKeywordsPredicate predicate = preparePredicate(" "); - FindRoleCommand command = new FindRoleCommand(predicate); - expectedModel.stackFilters(predicate); - assertCommandSuccess(command, model, expectedMessage, expectedModel); - assertEquals(Collections.emptyList(), model.getFilteredPersonList()); - } - - @Test - public void execute_singleRole_multiplePersonsFound() { - String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 3); - RoleContainsKeywordsPredicate predicate = preparePredicate("client"); - FindRoleCommand command = new FindRoleCommand(predicate); - expectedModel.stackFilters(predicate); - assertCommandSuccess(command, model, expectedMessage, expectedModel); - assertEquals(Arrays.asList(ALICE, BENSON, AMY), model.getFilteredPersonList()); - } - - @Test - public void execute_multipleRoles_multiplePersonsFound() { - String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 6); - RoleContainsKeywordsPredicate predicate = preparePredicate("client employee"); - FindRoleCommand command = new FindRoleCommand(predicate); - expectedModel.stackFilters(predicate); - assertCommandSuccess(command, model, expectedMessage, expectedModel); - assertEquals(Arrays.asList(ALICE, BENSON, DANIEL, ELLE, AMY, BOB), model.getFilteredPersonList()); - } - - @Test - public void toStringMethod() { - RoleContainsKeywordsPredicate predicate = - new RoleContainsKeywordsPredicate(Collections.singletonList("client")); - FindRoleCommand findRoleCommand = new FindRoleCommand(predicate); - String expected = FindRoleCommand.class.getCanonicalName() + "{predicate=" + predicate + "}"; - assertEquals(expected, findRoleCommand.toString()); - } - - /** - * Parses {@code userInput} into a {@code NameContainsKeywordsPredicate}. - */ - private RoleContainsKeywordsPredicate preparePredicate(String userInput) { - return new RoleContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+"))); - } -} diff --git a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java index a87d0467220..63eb25b7afc 100644 --- a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java @@ -11,7 +11,9 @@ import seedu.address.logic.Messages; import seedu.address.logic.commands.FindCommand; import seedu.address.model.person.Name; +import seedu.address.model.person.Person; import seedu.address.model.person.filter.NameContainsKeywordsPredicate; +import seedu.address.model.person.filter.RoleMatchesKeywordsPredicate; import seedu.address.model.person.filter.TagsContainsKeywordsPredicate; import seedu.address.model.tag.Tag; @@ -46,6 +48,18 @@ public void parse_validTags_returnsFindCommand() { assertParseSuccess(parser, " \n t/friends \n \t t/colleagues \t", expectedFindCommand); } + @Test + public void parse_validRoles_returnsFindCommand() { + // no leading and trailing whitespaces + FindCommand expectedFindCommand = new FindCommand(new RoleMatchesKeywordsPredicate( + Arrays.asList("client", "employee", "supplier"))); + assertParseSuccess(parser, " role/client role/employee role/supplier", expectedFindCommand); + + // multiple whitespaces between keywords + assertParseSuccess(parser, + " \n role/client \n \t role/employee \t \n role/supplier", expectedFindCommand); + } + @Test public void parse_invalidNames_throwsParseException() { // empty name @@ -70,18 +84,41 @@ public void parse_invalidTags_throwsParseException() { assertParseFailure(parser, " t/colleagues t/fri@ends", String.format(Tag.MESSAGE_CONSTRAINTS)); } + @Test + public void parse_invalidRoles_throwsParseException() { + // empty tag + assertParseFailure(parser, " role/", String.format(Person.MESSAGE_ROLE_CONSTRAINTS)); + assertParseFailure(parser, " role/ role/ role/", String.format(Person.MESSAGE_ROLE_CONSTRAINTS)); + + // invalid tag format + assertParseFailure(parser, " role/clie", + String.format(Person.MESSAGE_ROLE_CONSTRAINTS)); + assertParseFailure(parser, " role/clie role/employees", + String.format(Person.MESSAGE_ROLE_CONSTRAINTS)); + assertParseFailure(parser, " role/client role/employ", + String.format(Person.MESSAGE_ROLE_CONSTRAINTS)); + } + @Test public void parse_multipleFields_throwsParseException() { + // with possible invalid inputs assertParseFailure(parser, " n/ t/", String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); + assertParseFailure(parser, " n/ t/ role/", String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); assertParseFailure(parser, " n/Alice t/friends", String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); assertParseFailure(parser, " n/Ali@ce t/friends", String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); assertParseFailure(parser, " n/Alice t/fri@ends", String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); + assertParseFailure(parser, " role/clie t/friends", String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); + assertParseFailure(parser, " n/Alice t/friends role/clie", + String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); - // repeated fields + // multiple repeated fields with possible invalid inputs assertParseFailure(parser, " n/ n/ t/", String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); assertParseFailure(parser, " n/ t/ t/", String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); - assertParseFailure(parser, " n/Alice n/Bob t/friends", String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); + assertParseFailure(parser, " n/Alice n/Bob t/friends", + String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); assertParseFailure(parser, " n/Ali@ce t/friends t/colleagues", String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); + assertParseFailure(parser, " role/clie role/employ t/friends t/colleagues", + String.format(Messages.MESSAGE_NON_UNIQUE_FIELDS)); } } diff --git a/src/test/java/seedu/address/logic/parser/FindRoleCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindRoleCommandParserTest.java deleted file mode 100644 index 2fc11aad58f..00000000000 --- a/src/test/java/seedu/address/logic/parser/FindRoleCommandParserTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package seedu.address.logic.parser; - -import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; - -import java.util.Arrays; - -import org.junit.jupiter.api.Test; - -import seedu.address.logic.commands.FindRoleCommand; -import seedu.address.model.person.filter.RoleContainsKeywordsPredicate; - -public class FindRoleCommandParserTest { - private final FindRoleCommandParser findRoleCommandParser = new FindRoleCommandParser(); - - @Test - public void parse_emptyArg_throwsParseException() { - assertParseFailure(findRoleCommandParser, "", - String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindRoleCommand.MESSAGE_USAGE)); - } - - @Test - public void parse_invalidRole_throwsParseException() { - assertParseFailure(findRoleCommandParser, "cliont", - String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindRoleCommand.MESSAGE_USAGE)); - } - - @Test - public void parse_validRole_returnsFindRoleCommand() { - // no leading and trailing whitespaces - FindRoleCommand expectedFindRoleCommand = - new FindRoleCommand(new RoleContainsKeywordsPredicate(Arrays.asList("client", "supplier"))); - assertParseSuccess(findRoleCommandParser, "client supplier", expectedFindRoleCommand); - assertParseSuccess(findRoleCommandParser, " \n client \n \t supplier \t", expectedFindRoleCommand); - } -} diff --git a/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java b/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java index 4e9904fd454..1e781cca4de 100644 --- a/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java +++ b/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java @@ -26,7 +26,6 @@ import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.FindNumCommand; import seedu.address.logic.commands.FindRemCommand; -import seedu.address.logic.commands.FindRoleCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.RemarkCommand; @@ -36,7 +35,6 @@ import seedu.address.model.person.filter.NameContainsKeywordsPredicate; import seedu.address.model.person.filter.PhoneContainsDigitsPredicate; import seedu.address.model.person.filter.RemarkContainsKeywordsPredicate; -import seedu.address.model.person.filter.RoleContainsKeywordsPredicate; import seedu.address.testutil.ClientBuilder; import seedu.address.testutil.EditPersonDescriptorBuilder; import seedu.address.testutil.PersonUtil; @@ -104,14 +102,6 @@ public void parseCommand_findRem() throws Exception { assertEquals(new FindRemCommand(new RemarkContainsKeywordsPredicate(keywords)), command); } - @Test - public void parseCommand_findRole() throws Exception { - List roles = Arrays.asList("supplier", "employee"); - FindRoleCommand command = (FindRoleCommand) parser.parseCommand( - FindRoleCommand.COMMAND_WORD + " " + roles.stream().collect(Collectors.joining(" "))); - assertEquals(new FindRoleCommand(new RoleContainsKeywordsPredicate(roles)), command); - } - @Test public void parseCommand_help() throws Exception { assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD) instanceof HelpCommand); diff --git a/src/test/java/seedu/address/model/person/RemarkContainsKeywordsPredicateTest.java b/src/test/java/seedu/address/model/person/RemarkContainsKeywordsPredicateTest.java index a8f7a76519e..ac7a9c04ebe 100644 --- a/src/test/java/seedu/address/model/person/RemarkContainsKeywordsPredicateTest.java +++ b/src/test/java/seedu/address/model/person/RemarkContainsKeywordsPredicateTest.java @@ -15,6 +15,21 @@ import seedu.address.testutil.SupplierBuilder; public class RemarkContainsKeywordsPredicateTest { + + @Test + public void formatFilter() { + List firstPredicateKeywordList = Collections.singletonList("first"); + List secondPredicateKeywordList = Arrays.asList("first", "second"); + + RemarkContainsKeywordsPredicate firstPredicate = + new RemarkContainsKeywordsPredicate(firstPredicateKeywordList); + RemarkContainsKeywordsPredicate secondPredicate = + new RemarkContainsKeywordsPredicate(secondPredicateKeywordList); + + assertEquals("r/first", firstPredicate.formatFilter()); + assertEquals("r/first r/second", secondPredicate.formatFilter()); + } + @Test public void equals() { // same object -> returns true diff --git a/src/test/java/seedu/address/model/person/filter/RoleContainsKeywordsPredicateTest.java b/src/test/java/seedu/address/model/person/filter/RoleMatchesKeywordsPredicateTest.java similarity index 65% rename from src/test/java/seedu/address/model/person/filter/RoleContainsKeywordsPredicateTest.java rename to src/test/java/seedu/address/model/person/filter/RoleMatchesKeywordsPredicateTest.java index a7b978d048a..9b98dad860d 100644 --- a/src/test/java/seedu/address/model/person/filter/RoleContainsKeywordsPredicateTest.java +++ b/src/test/java/seedu/address/model/person/filter/RoleMatchesKeywordsPredicateTest.java @@ -13,15 +13,15 @@ import seedu.address.testutil.ClientBuilder; import seedu.address.testutil.SupplierBuilder; -class RoleContainsKeywordsPredicateTest { +class RoleMatchesKeywordsPredicateTest { @Test public void formatFilter() { List firstPredicateKeywordList = Collections.singletonList("first"); List secondPredicateKeywordList = Arrays.asList("first", "second"); - RoleContainsKeywordsPredicate firstPredicate = new RoleContainsKeywordsPredicate(firstPredicateKeywordList); - RoleContainsKeywordsPredicate secondPredicate = new RoleContainsKeywordsPredicate(secondPredicateKeywordList); + RoleMatchesKeywordsPredicate firstPredicate = new RoleMatchesKeywordsPredicate(firstPredicateKeywordList); + RoleMatchesKeywordsPredicate secondPredicate = new RoleMatchesKeywordsPredicate(secondPredicateKeywordList); assertEquals("role/first", firstPredicate.formatFilter()); assertEquals("role/first role/second", secondPredicate.formatFilter()); @@ -32,15 +32,15 @@ public void equals() { List firstPredicateKeywordList = Collections.singletonList("first"); List secondPredicateKeywordList = Arrays.asList("first", "second"); - RoleContainsKeywordsPredicate firstPredicate = new RoleContainsKeywordsPredicate(firstPredicateKeywordList); - RoleContainsKeywordsPredicate secondPredicate = new RoleContainsKeywordsPredicate(secondPredicateKeywordList); + RoleMatchesKeywordsPredicate firstPredicate = new RoleMatchesKeywordsPredicate(firstPredicateKeywordList); + RoleMatchesKeywordsPredicate secondPredicate = new RoleMatchesKeywordsPredicate(secondPredicateKeywordList); // same object -> returns true assertTrue(firstPredicate.equals(firstPredicate)); // same values -> returns true - RoleContainsKeywordsPredicate firstPredicateCopy = - new RoleContainsKeywordsPredicate(firstPredicateKeywordList); + RoleMatchesKeywordsPredicate firstPredicateCopy = + new RoleMatchesKeywordsPredicate(firstPredicateKeywordList); assertTrue(firstPredicate.equals(firstPredicateCopy)); // different types -> returns false @@ -56,22 +56,22 @@ public void equals() { @Test public void test_roleContainsKeywords_returnsTrue() { // One keyword - RoleContainsKeywordsPredicate predicate = - new RoleContainsKeywordsPredicate(Collections.singletonList("client")); + RoleMatchesKeywordsPredicate predicate = + new RoleMatchesKeywordsPredicate(Collections.singletonList("client")); assertTrue(predicate.test(new ClientBuilder().build())); // Multiple keywords - predicate = new RoleContainsKeywordsPredicate(List.of("client", "supplier")); + predicate = new RoleMatchesKeywordsPredicate(List.of("client", "supplier")); assertTrue(predicate.test(new ClientBuilder().build())); assertTrue(predicate.test(new SupplierBuilder().build())); // Only one matching keyword - predicate = new RoleContainsKeywordsPredicate(List.of("client", "supplier")); + predicate = new RoleMatchesKeywordsPredicate(List.of("client", "supplier")); assertTrue(predicate.test(new SupplierBuilder().build())); assertTrue(predicate.test(new SupplierBuilder().build())); // Mixed-case keywords - predicate = new RoleContainsKeywordsPredicate(List.of("cLiEnT", "sUpPlIeR")); + predicate = new RoleMatchesKeywordsPredicate(List.of("cLiEnT", "sUpPlIeR")); assertTrue(predicate.test(new SupplierBuilder().build())); assertTrue(predicate.test(new SupplierBuilder().build())); } @@ -79,12 +79,12 @@ public void test_roleContainsKeywords_returnsTrue() { @Test public void test_roleDoesNotContainKeywords_returnsFalse() { // Zero keywords - RoleContainsKeywordsPredicate predicate = new RoleContainsKeywordsPredicate(List.of()); + RoleMatchesKeywordsPredicate predicate = new RoleMatchesKeywordsPredicate(List.of()); assertFalse(predicate.test(new ClientBuilder().build())); assertFalse(predicate.test(new SupplierBuilder().build())); // Non-matching keyword - predicate = new RoleContainsKeywordsPredicate(List.of("employee")); + predicate = new RoleMatchesKeywordsPredicate(List.of("employee")); assertFalse(predicate.test(new ClientBuilder().build())); assertFalse(predicate.test(new SupplierBuilder().build())); } @@ -92,9 +92,9 @@ public void test_roleDoesNotContainKeywords_returnsFalse() { @Test public void toStringMethod() { List roles = List.of("client", "supplier"); - RoleContainsKeywordsPredicate predicate = new RoleContainsKeywordsPredicate(roles); + RoleMatchesKeywordsPredicate predicate = new RoleMatchesKeywordsPredicate(roles); - String expected = RoleContainsKeywordsPredicate.class.getCanonicalName() + "{keywords=" + roles + "}"; + String expected = RoleMatchesKeywordsPredicate.class.getCanonicalName() + "{keywords=" + roles + "}"; assertEquals(expected, predicate.toString()); } } From 71728d0698db9178e43990090c4289bf1c2b6501 Mon Sep 17 00:00:00 2001 From: Shaun Lee Date: Tue, 2 Apr 2024 17:02:55 +0800 Subject: [PATCH 11/29] Integrate findrem into find command --- .../address/logic/commands/FindCommand.java | 11 +- .../logic/commands/FindRemCommand.java | 57 ---------- .../logic/parser/ArgumentMultimap.java | 2 +- .../logic/parser/FindCommandParser.java | 8 +- .../logic/parser/FindRemCommandParser.java | 39 ------- .../logic/parser/NetConnectParser.java | 4 - .../RemarkContainsKeywordsPredicate.java | 19 +++- .../logic/commands/CommandTestUtil.java | 1 + .../logic/commands/FindRemCommandTest.java | 104 ------------------ .../logic/parser/AddCommandParserTest.java | 5 + .../logic/parser/FindCommandParserTest.java | 26 +++++ .../parser/FindRemCommandParserTest.java | 44 -------- .../logic/parser/NetConnectParserTest.java | 10 -- .../RemarkContainsKeywordsPredicateTest.java | 47 ++++++++ 14 files changed, 110 insertions(+), 267 deletions(-) delete mode 100644 src/main/java/seedu/address/logic/commands/FindRemCommand.java delete mode 100644 src/main/java/seedu/address/logic/parser/FindRemCommandParser.java delete mode 100644 src/test/java/seedu/address/logic/commands/FindRemCommandTest.java delete mode 100644 src/test/java/seedu/address/logic/parser/FindRemCommandParserTest.java diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/address/logic/commands/FindCommand.java index b23413eaf99..69e6e0755f8 100644 --- a/src/main/java/seedu/address/logic/commands/FindCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindCommand.java @@ -2,6 +2,7 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK; import static seedu.address.logic.parser.CliSyntax.PREFIX_ROLE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; @@ -14,7 +15,7 @@ /** * Finds and lists all persons in NetConnect whose information matches any of the given arguments. * Keyword matching is case-insensitive. - * Find command supports finding by: name, tag, and role. + * Find command supports finding by: name, tag, role, and remark. */ public class FindCommand extends Command { @@ -23,14 +24,18 @@ public class FindCommand extends Command { public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose information matches any of the given arguments.\n" + "Only one type of argument can be given per " + COMMAND_WORD + " command.\n" + + "Name, tag and role cannot be empty. " + + "Remark can be empty to find persons with no remarks.\n" + "Parameters: " + "[" + PREFIX_NAME + "NAME]... " + "[" + PREFIX_TAG + "TAG]... " - + "[" + PREFIX_ROLE + "ROLE]... \n" + + "[" + PREFIX_ROLE + "ROLE]... " + + "[" + PREFIX_REMARK + "REMARK]... \n" + "Examples: \n" + COMMAND_WORD + " n/alice n/bob n/charlie\n" + COMMAND_WORD + " t/friends t/colleagues\n" - + COMMAND_WORD + " role/client"; + + COMMAND_WORD + " role/client\n" + + COMMAND_WORD + " r/owes money r/quarterly report"; private final NetConnectPredicate predicate; diff --git a/src/main/java/seedu/address/logic/commands/FindRemCommand.java b/src/main/java/seedu/address/logic/commands/FindRemCommand.java deleted file mode 100644 index a3272e2be7a..00000000000 --- a/src/main/java/seedu/address/logic/commands/FindRemCommand.java +++ /dev/null @@ -1,57 +0,0 @@ -package seedu.address.logic.commands; - -import static java.util.Objects.requireNonNull; - -import seedu.address.commons.util.ToStringBuilder; -import seedu.address.logic.Messages; -import seedu.address.model.Model; -import seedu.address.model.person.filter.RemarkContainsKeywordsPredicate; - -/** - * Finds and lists all persons in address book whose remark contains any of the argument keywords. - * Keyword matching is case-insensitive. - */ -public class FindRemCommand extends Command { - public static final String COMMAND_WORD = "findrem"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose remarks contain any of " - + "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n" - + "Parameters: REMARK_KEYWORD [MORE_KEYWORDS]...\n" - + "Example: " + COMMAND_WORD + " owesMoney unfriendly"; - - private final RemarkContainsKeywordsPredicate predicate; - - public FindRemCommand(RemarkContainsKeywordsPredicate predicate) { - this.predicate = predicate; - } - - @Override - public CommandResult execute(Model model) { - requireNonNull(model); - model.clearFilter(); - model.stackFilters(predicate); - return new CommandResult( - String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size())); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - if (!(other instanceof FindRemCommand)) { - return false; - } - - FindRemCommand otherFindRemCommand = (FindRemCommand) other; - return predicate.equals(otherFindRemCommand.predicate); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .add("predicate", predicate) - .toString(); - } - -} diff --git a/src/main/java/seedu/address/logic/parser/ArgumentMultimap.java b/src/main/java/seedu/address/logic/parser/ArgumentMultimap.java index a682b8641fc..ec4ea8559ee 100644 --- a/src/main/java/seedu/address/logic/parser/ArgumentMultimap.java +++ b/src/main/java/seedu/address/logic/parser/ArgumentMultimap.java @@ -83,7 +83,7 @@ public void verifyNoDuplicatePrefixesFor(Prefix... prefixes) throws ParseExcepti */ public void verifyOnlyOnePrefix() throws ParseException { // check more than 2 since preamble is added into the multimap - if (argMultimap.values().stream().filter(v -> v.size() > 0).count() > 2) { + if (argMultimap.values().size() > 2) { throw new ParseException(Messages.MESSAGE_NON_UNIQUE_FIELDS); } } diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/address/logic/parser/FindCommandParser.java index b28c673ebf0..476eaeffdf3 100644 --- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FindCommandParser.java @@ -3,6 +3,7 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK; import static seedu.address.logic.parser.CliSyntax.PREFIX_ROLE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; @@ -14,6 +15,7 @@ import seedu.address.model.person.Person; import seedu.address.model.person.filter.NameContainsKeywordsPredicate; import seedu.address.model.person.filter.NetConnectPredicate; +import seedu.address.model.person.filter.RemarkContainsKeywordsPredicate; import seedu.address.model.person.filter.RoleMatchesKeywordsPredicate; import seedu.address.model.person.filter.TagsContainsKeywordsPredicate; import seedu.address.model.tag.Tag; @@ -31,7 +33,8 @@ public class FindCommandParser implements Parser { */ public FindCommand parse(String args) throws ParseException { requireNonNull(args); - ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_TAG, PREFIX_ROLE); + ArgumentMultimap argMultimap = ArgumentTokenizer + .tokenize(args, PREFIX_NAME, PREFIX_TAG, PREFIX_ROLE, PREFIX_REMARK); argMultimap.verifyOnlyOnePrefix(); return new FindCommand(createPredicate(argMultimap)); @@ -63,6 +66,9 @@ private static NetConnectPredicate createPredicate( throw new ParseException(Person.MESSAGE_ROLE_CONSTRAINTS); } return new RoleMatchesKeywordsPredicate(roles); + } else if (argMultimap.getValue(PREFIX_REMARK).isPresent()) { + List remarks = argMultimap.getAllValues(PREFIX_REMARK); + return new RemarkContainsKeywordsPredicate(remarks); } else { // no field provided throw new ParseException( diff --git a/src/main/java/seedu/address/logic/parser/FindRemCommandParser.java b/src/main/java/seedu/address/logic/parser/FindRemCommandParser.java deleted file mode 100644 index c800f839d51..00000000000 --- a/src/main/java/seedu/address/logic/parser/FindRemCommandParser.java +++ /dev/null @@ -1,39 +0,0 @@ -package seedu.address.logic.parser; - -import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; - -import java.util.Arrays; - -import seedu.address.logic.commands.FindRemCommand; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.filter.RemarkContainsKeywordsPredicate; - -/** - * Parses input arguments and creates a new FindRemCommand object - */ -public class FindRemCommandParser implements Parser { - - /** - * Parses the given {@code String} of arguments in the context of the FindRemCommand - * and returns a FindRemCommand object for execution. - * @throws ParseException if the user input does not conform the expected format - */ - public FindRemCommand parse(String args) throws ParseException { - String trimmedArgs = args.trim(); - if (trimmedArgs.isEmpty()) { - throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindRemCommand.MESSAGE_USAGE)); - } - - String[] remarkKeywords = trimmedArgs.split("\\s+"); - - // Check if all keywords in input are valid - for (String keyword : remarkKeywords) { - assert !keyword.isEmpty(); - assert keyword.matches("^[a-zA-Z0-9\\p{Punct}]*$"); - } - - return new FindRemCommand(new RemarkContainsKeywordsPredicate(Arrays.asList(remarkKeywords))); - } - -} diff --git a/src/main/java/seedu/address/logic/parser/NetConnectParser.java b/src/main/java/seedu/address/logic/parser/NetConnectParser.java index 9105bc5574b..a0b13e5f300 100644 --- a/src/main/java/seedu/address/logic/parser/NetConnectParser.java +++ b/src/main/java/seedu/address/logic/parser/NetConnectParser.java @@ -17,7 +17,6 @@ import seedu.address.logic.commands.ExportCommand; import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.FindNumCommand; -import seedu.address.logic.commands.FindRemCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.RemarkCommand; @@ -76,9 +75,6 @@ public Command parseCommand(String userInput) throws ParseException { case FindNumCommand.COMMAND_WORD: return new FindNumCommandParser().parse(arguments); - case FindRemCommand.COMMAND_WORD: - return new FindRemCommandParser().parse(arguments); - case RemarkCommand.COMMAND_WORD: return new RemarkCommandParser().parse(arguments); diff --git a/src/main/java/seedu/address/model/person/filter/RemarkContainsKeywordsPredicate.java b/src/main/java/seedu/address/model/person/filter/RemarkContainsKeywordsPredicate.java index 27c49cd477b..94640fbe589 100644 --- a/src/main/java/seedu/address/model/person/filter/RemarkContainsKeywordsPredicate.java +++ b/src/main/java/seedu/address/model/person/filter/RemarkContainsKeywordsPredicate.java @@ -3,6 +3,7 @@ import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK; import java.util.List; +import java.util.function.Predicate; import java.util.stream.Collectors; import seedu.address.commons.util.StringUtil; @@ -13,21 +14,30 @@ * Tests that a {@code Person}'s {@code Remark} contains any of the keywords given. */ public class RemarkContainsKeywordsPredicate extends NetConnectPredicate { + private final boolean hasEmptyKeyword; private final List keywords; + /** + * Constructs a {@code RemarkContainsKeywordsPredicate} with a list of keywords. + * + * @param keywords The list of keywords to match against the person's remarks. + */ public RemarkContainsKeywordsPredicate(List keywords) { - this.keywords = keywords; + this.keywords = keywords.stream().filter(Predicate.not(String::isBlank)).collect(Collectors.toList()); + this.hasEmptyKeyword = keywords.stream().anyMatch(String::isBlank); } @Override public String formatFilter() { - return keywords.stream().map(s -> PREFIX_REMARK + s).collect(Collectors.joining(" ")); + return keywords.stream().map(s -> PREFIX_REMARK + s).collect(Collectors.joining(" ")) + + (hasEmptyKeyword ? PREFIX_REMARK + "EMPTY-REMARK" : ""); } @Override public boolean test(Person person) { return keywords.stream() - .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getRemark().value, keyword)); + .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getRemark().value, keyword)) + || (hasEmptyKeyword && person.getRemark().value.isBlank()); } @Override @@ -42,7 +52,8 @@ public boolean equals(Object other) { } RemarkContainsKeywordsPredicate otherRemarkContainsKeywordsPredicate = (RemarkContainsKeywordsPredicate) other; - return keywords.equals(otherRemarkContainsKeywordsPredicate.keywords); + return keywords.equals(otherRemarkContainsKeywordsPredicate.keywords) + && (hasEmptyKeyword == otherRemarkContainsKeywordsPredicate.hasEmptyKeyword); } @Override diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java index ac8c7528b11..1721f6998e8 100644 --- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java @@ -88,6 +88,7 @@ public class CommandTestUtil { public static final String INVALID_EMAIL_DESC = " " + PREFIX_EMAIL + "bob!yahoo"; // missing '@' symbol public static final String INVALID_ADDRESS_DESC = " " + PREFIX_ADDRESS; // empty string not allowed for addresses public static final String INVALID_TAG_DESC = " " + PREFIX_TAG + "hubby*"; // '*' not allowed in tags + public static final String INVALID_ROLE_DESC = " " + PREFIX_ROLE + "employ"; public static final String PREAMBLE_WHITESPACE = "\t \r \n"; public static final String PREAMBLE_NON_EMPTY = "NonEmptyPreamble"; diff --git a/src/test/java/seedu/address/logic/commands/FindRemCommandTest.java b/src/test/java/seedu/address/logic/commands/FindRemCommandTest.java deleted file mode 100644 index 76dc5ccd2c9..00000000000 --- a/src/test/java/seedu/address/logic/commands/FindRemCommandTest.java +++ /dev/null @@ -1,104 +0,0 @@ -package seedu.address.logic.commands; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalPersons.ALICE; -import static seedu.address.testutil.TypicalPersons.BENSON; -import static seedu.address.testutil.TypicalPersons.DANIEL; -import static seedu.address.testutil.TypicalPersons.ELLE; -import static seedu.address.testutil.TypicalPersons.FIONA; -import static seedu.address.testutil.TypicalPersons.GEORGE; -import static seedu.address.testutil.TypicalPersons.getTypicalNetConnect; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.jupiter.api.Test; - -import seedu.address.logic.Messages; -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.UserPrefs; -import seedu.address.model.person.filter.RemarkContainsKeywordsPredicate; - -/** - * Contains integration tests (interaction with the Model) and unit tests for FindRemCommand. - */ -public class FindRemCommandTest { - private final Model model = new ModelManager(getTypicalNetConnect(), new UserPrefs()); - private final Model expectedModel = new ModelManager(getTypicalNetConnect(), new UserPrefs()); - - @Test - public void equals() { - List firstPredicateKeywordList = Collections.singletonList("first"); - List secondPredicateKeywordList = Arrays.asList("first", "second"); - - RemarkContainsKeywordsPredicate firstPredicate = - new RemarkContainsKeywordsPredicate(firstPredicateKeywordList); - RemarkContainsKeywordsPredicate secondPredicate = - new RemarkContainsKeywordsPredicate(secondPredicateKeywordList); - - FindRemCommand findFirstCommand = new FindRemCommand(firstPredicate); - FindRemCommand findSecondCommand = new FindRemCommand(secondPredicate); - - // same object -> returns true - assertTrue(findFirstCommand.equals(findFirstCommand)); - - // same values -> returns true - FindRemCommand findFirstCommandCopy = new FindRemCommand(firstPredicate); - assertTrue(findFirstCommand.equals(findFirstCommandCopy)); - - // different types -> returns false - assertFalse(findFirstCommand.equals(1)); - - // null -> returns false - assertFalse(findFirstCommand.equals(null)); - - // different person -> returns false - assertFalse(findFirstCommand.equals(findSecondCommand)); - } - - @Test - public void execute_zeroKeywords_noPersonFound() { - String expectedMessage = String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, 0); - RemarkContainsKeywordsPredicate predicate = preparePredicate(" "); - FindRemCommand command = new FindRemCommand(predicate); - expectedModel.clearFilter(); - expectedModel.stackFilters(predicate); - CommandResult expectedCommandResult = new CommandResult(expectedMessage); - assertCommandSuccess(command, model, expectedCommandResult, expectedModel); - assertTrue(model.getFilteredPersonList().isEmpty()); - } - - @Test - public void execute_multipleKeywords_multiplePersonsFound() { - String expectedMessage = String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, 6); - RemarkContainsKeywordsPredicate predicate = preparePredicate("some remarks"); - FindRemCommand command = new FindRemCommand(predicate); - expectedModel.clearFilter(); - expectedModel.stackFilters(predicate); - CommandResult expectedCommandResult = new CommandResult(expectedMessage); - assertCommandSuccess(command, model, expectedCommandResult, expectedModel); - assertTrue(model.getFilteredPersonList().size() == 6); - assertEquals(Arrays.asList(ALICE, BENSON, DANIEL, ELLE, FIONA, GEORGE), model.getFilteredPersonList()); - } - - - @Test - public void toStringMethod() { - RemarkContainsKeywordsPredicate predicate = preparePredicate("friendly unfriendly"); - FindRemCommand command = new FindRemCommand(predicate); - String expected = FindRemCommand.class.getCanonicalName() + "{predicate=" + predicate + "}"; - assertEquals(expected, command.toString()); - } - - /** - * Parses {@code userInput} into a {@code RemarkContainsKeywordsPredicate}. - */ - private RemarkContainsKeywordsPredicate preparePredicate(String userInput) { - return new RemarkContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+"))); - } -} diff --git a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java index 23e59cb18a0..c6f9705b0e3 100644 --- a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java @@ -10,6 +10,7 @@ import static seedu.address.logic.commands.CommandTestUtil.INVALID_EMAIL_DESC; import static seedu.address.logic.commands.CommandTestUtil.INVALID_NAME_DESC; import static seedu.address.logic.commands.CommandTestUtil.INVALID_PHONE_DESC; +import static seedu.address.logic.commands.CommandTestUtil.INVALID_ROLE_DESC; import static seedu.address.logic.commands.CommandTestUtil.INVALID_TAG_DESC; import static seedu.address.logic.commands.CommandTestUtil.JOB_TITLE_DESC_BOB; import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY; @@ -202,6 +203,10 @@ public void parse_invalidValue_failure() { assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB + INVALID_TAG_DESC + VALID_TAG_FRIEND + ROLE_DESC_EMPLOYEE, Tag.MESSAGE_CONSTRAINTS); + // invalid role + assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB + + TAG_DESC_HUSBAND + TAG_DESC_FRIEND + INVALID_ROLE_DESC, Person.MESSAGE_ROLE_CONSTRAINTS); + // two invalid values, only first invalid value reported assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + INVALID_ADDRESS_DESC + ROLE_DESC_EMPLOYEE, Name.MESSAGE_CONSTRAINTS); diff --git a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java index 63eb25b7afc..865087d8584 100644 --- a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java @@ -5,6 +5,7 @@ import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; import java.util.Arrays; +import java.util.Collections; import org.junit.jupiter.api.Test; @@ -13,6 +14,7 @@ import seedu.address.model.person.Name; import seedu.address.model.person.Person; import seedu.address.model.person.filter.NameContainsKeywordsPredicate; +import seedu.address.model.person.filter.RemarkContainsKeywordsPredicate; import seedu.address.model.person.filter.RoleMatchesKeywordsPredicate; import seedu.address.model.person.filter.TagsContainsKeywordsPredicate; import seedu.address.model.tag.Tag; @@ -60,6 +62,30 @@ public void parse_validRoles_returnsFindCommand() { " \n role/client \n \t role/employee \t \n role/supplier", expectedFindCommand); } + @Test + public void parse_validRemarks_returnsFindCommand() { + // empty remark + FindCommand expectedFindCommand = new FindCommand( + new RemarkContainsKeywordsPredicate(Collections.singletonList(""))); + assertParseSuccess(parser, " r/", expectedFindCommand); + assertParseSuccess(parser, " r/ \t \n", expectedFindCommand); + + // non-empty + empty remarks + expectedFindCommand = new FindCommand( + new RemarkContainsKeywordsPredicate(Arrays.asList("", "first"))); + assertParseSuccess(parser, " r/ r/first", expectedFindCommand); + assertParseSuccess(parser, " r/first \n \t r/ \t \n", expectedFindCommand); + + // no leading and trailing whitespaces + expectedFindCommand = new FindCommand(new RemarkContainsKeywordsPredicate( + Arrays.asList("first", "second"))); + assertParseSuccess(parser, " r/first r/second", expectedFindCommand); + + // multiple whitespaces between keywords + assertParseSuccess(parser, + " \n r/first \n \t r/second \t", expectedFindCommand); + } + @Test public void parse_invalidNames_throwsParseException() { // empty name diff --git a/src/test/java/seedu/address/logic/parser/FindRemCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindRemCommandParserTest.java deleted file mode 100644 index 5035c57b676..00000000000 --- a/src/test/java/seedu/address/logic/parser/FindRemCommandParserTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package seedu.address.logic.parser; - -import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; - -import java.util.Arrays; - -import org.junit.jupiter.api.Test; - -import seedu.address.logic.commands.FindRemCommand; -import seedu.address.model.person.filter.RemarkContainsKeywordsPredicate; - -public class FindRemCommandParserTest { - private final FindRemCommandParser parser = new FindRemCommandParser(); - - @Test - public void parseEmptyArgs_throwsParseException() { - assertParseFailure( - parser, "", String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindRemCommand.MESSAGE_USAGE)); - } - - @Test - public void parseValidArgs_returnsFindRemCommand() { - // no leading and trailing whitespaces - FindRemCommand expectedFindRemCommand = - new FindRemCommand(new RemarkContainsKeywordsPredicate(Arrays.asList("first", "second"))); - assertParseSuccess(parser, "first second", expectedFindRemCommand); - - // multiple whitespaces between keywords - assertParseSuccess(parser, " \n first \n \t second \t", expectedFindRemCommand); - } - - @Test - public void parseInvalidArgs_throwsParseException() { - // empty keyword - assertParseFailure( - parser, - " \n \t \n", - String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindRemCommand.MESSAGE_USAGE)); - } - - -} diff --git a/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java b/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java index 1e781cca4de..0ca092a0cd2 100644 --- a/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java +++ b/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java @@ -25,7 +25,6 @@ import seedu.address.logic.commands.ExportCommand; import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.FindNumCommand; -import seedu.address.logic.commands.FindRemCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.RemarkCommand; @@ -34,7 +33,6 @@ import seedu.address.model.person.Remark; import seedu.address.model.person.filter.NameContainsKeywordsPredicate; import seedu.address.model.person.filter.PhoneContainsDigitsPredicate; -import seedu.address.model.person.filter.RemarkContainsKeywordsPredicate; import seedu.address.testutil.ClientBuilder; import seedu.address.testutil.EditPersonDescriptorBuilder; import seedu.address.testutil.PersonUtil; @@ -94,14 +92,6 @@ public void parseCommand_findNum() throws Exception { assertEquals(new FindNumCommand(new PhoneContainsDigitsPredicate(phones)), command); } - @Test - public void parseCommand_findRem() throws Exception { - List keywords = Arrays.asList("foo", "bar", "baz"); - FindRemCommand command = (FindRemCommand) parser.parseCommand( - FindRemCommand.COMMAND_WORD + " " + keywords.stream().collect(Collectors.joining(" "))); - assertEquals(new FindRemCommand(new RemarkContainsKeywordsPredicate(keywords)), command); - } - @Test public void parseCommand_help() throws Exception { assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD) instanceof HelpCommand); diff --git a/src/test/java/seedu/address/model/person/RemarkContainsKeywordsPredicateTest.java b/src/test/java/seedu/address/model/person/RemarkContainsKeywordsPredicateTest.java index ac7a9c04ebe..a98badefbf8 100644 --- a/src/test/java/seedu/address/model/person/RemarkContainsKeywordsPredicateTest.java +++ b/src/test/java/seedu/address/model/person/RemarkContainsKeywordsPredicateTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import java.util.Collections; @@ -18,14 +19,18 @@ public class RemarkContainsKeywordsPredicateTest { @Test public void formatFilter() { + List emptyKeywordList = Collections.singletonList(""); List firstPredicateKeywordList = Collections.singletonList("first"); List secondPredicateKeywordList = Arrays.asList("first", "second"); + RemarkContainsKeywordsPredicate emptyPredicate = + new RemarkContainsKeywordsPredicate(emptyKeywordList); RemarkContainsKeywordsPredicate firstPredicate = new RemarkContainsKeywordsPredicate(firstPredicateKeywordList); RemarkContainsKeywordsPredicate secondPredicate = new RemarkContainsKeywordsPredicate(secondPredicateKeywordList); + assertEquals("r/EMPTY-REMARK", emptyPredicate.formatFilter()); assertEquals("r/first", firstPredicate.formatFilter()); assertEquals("r/first r/second", secondPredicate.formatFilter()); } @@ -60,6 +65,44 @@ public void equals() { RemarkContainsKeywordsPredicate sixthPredicate = new RemarkContainsKeywordsPredicate(Collections.singletonList("second")); assertFalse(firstPredicate.equals(sixthPredicate)); + + //// additional tests with empty keyword + RemarkContainsKeywordsPredicate emptyPredicate = + new RemarkContainsKeywordsPredicate(Collections.singletonList("")); + RemarkContainsKeywordsPredicate otherEmptyPredicate = + new RemarkContainsKeywordsPredicate(Collections.singletonList("")); + RemarkContainsKeywordsPredicate firstWithEmptyPredicate = + new RemarkContainsKeywordsPredicate(Arrays.asList("first", "")); + + // same object -> returns true + assertTrue(emptyPredicate.equals(emptyPredicate)); + + // diff object, both empty -> returns true + assertTrue(emptyPredicate.equals(otherEmptyPredicate)); + + // empty but has diff keyword list -> returns false + assertFalse(emptyPredicate.equals(firstWithEmptyPredicate)); + + // same keyword list, diff empty boolean -> returns false + assertFalse(firstPredicate.equals(firstWithEmptyPredicate)); + + // all values different -> returns false + assertFalse(thirdPredicate.equals(firstWithEmptyPredicate)); + } + + @Test + public void test_remarkContainsKeywords_returnsTrue() { + RemarkContainsKeywordsPredicate predicate = + new RemarkContainsKeywordsPredicate(Arrays.asList("first", "second")); + assertTrue(predicate.test(new ClientBuilder().withRemark("first").build())); + assertTrue(predicate.test(new ClientBuilder().withRemark("second").build())); + } + + @Test + public void test_remarkMatchesEmptyKeyword_returnsTrue() { + RemarkContainsKeywordsPredicate predicate = + new RemarkContainsKeywordsPredicate(Collections.singletonList("")); + assertTrue(predicate.test(new ClientBuilder().withRemark("").build())); } @Test @@ -77,6 +120,10 @@ public void test_remarkDoesNotContainKeywords_returnsFalse() { Arrays.asList("Alice", "alice@email.com", "Main", "Street", "12345")); assertFalse(predicate.test(new SupplierBuilder().withName("Alice").withPhone("12345") .withEmail("alice@email.com").withAddress("Main Street").withRemark("biscuit").build())); + + // Non-empty remark with empty keyword + predicate = new RemarkContainsKeywordsPredicate(Collections.singletonList("")); + assertFalse(predicate.test(new ClientBuilder().withRemark("first").build())); } @Test From 2a0bbec76e3dc6b0e4619a1876c6b1908d0cba2f Mon Sep 17 00:00:00 2001 From: Shaun Lee Date: Tue, 2 Apr 2024 17:39:51 +0800 Subject: [PATCH 12/29] Refactor code Changes: * Index: removed dead code * DeleteCommandTest: fix naming of methods and add test --- .../address/commons/core/index/Index.java | 69 ------------------- .../java/seedu/address/logic/Messages.java | 1 - .../address/logic/parser/ParserUtil.java | 19 ----- .../address/commons/core/index/IndexTest.java | 67 ------------------ .../logic/commands/CommandTestUtil.java | 16 ----- .../logic/commands/DeleteCommandTest.java | 2 - .../logic/commands/ListCommandTest.java | 6 +- .../address/logic/parser/ParserUtilTest.java | 22 ------ .../logic/parser/RemarkCommandParserTest.java | 11 ++- .../java/seedu/address/testutil/TestUtil.java | 25 ------- .../address/testutil/TypicalIndexes.java | 11 --- 11 files changed, 12 insertions(+), 237 deletions(-) delete mode 100644 src/main/java/seedu/address/commons/core/index/Index.java delete mode 100644 src/test/java/seedu/address/commons/core/index/IndexTest.java delete mode 100644 src/test/java/seedu/address/testutil/TypicalIndexes.java diff --git a/src/main/java/seedu/address/commons/core/index/Index.java b/src/main/java/seedu/address/commons/core/index/Index.java deleted file mode 100644 index 930118a0451..00000000000 --- a/src/main/java/seedu/address/commons/core/index/Index.java +++ /dev/null @@ -1,69 +0,0 @@ -package seedu.address.commons.core.index; - -import seedu.address.commons.util.ToStringBuilder; - -/** - * Represents a zero-based or one-based index. - *

- * {@code Index} should be used right from the start (when parsing in a new user input), so that if the current - * component wants to communicate with another component, it can send an {@code Index} to avoid having to know what - * base the other component is using for its index. However, after receiving the {@code Index}, that component can - * convert it back to an int if the index will not be passed to a different component again. - */ -public class Index { - private final int zeroBasedIndex; - - /** - * Index can only be created by calling {@link Index#fromZeroBased(int)} or - * {@link Index#fromOneBased(int)}. - */ - private Index(int zeroBasedIndex) { - if (zeroBasedIndex < 0) { - throw new IndexOutOfBoundsException(); - } - - this.zeroBasedIndex = zeroBasedIndex; - } - - public int getZeroBased() { - return zeroBasedIndex; - } - - public int getOneBased() { - return zeroBasedIndex + 1; - } - - /** - * Creates a new {@code Index} using a zero-based index. - */ - public static Index fromZeroBased(int zeroBasedIndex) { - return new Index(zeroBasedIndex); - } - - /** - * Creates a new {@code Index} using a one-based index. - */ - public static Index fromOneBased(int oneBasedIndex) { - return new Index(oneBasedIndex - 1); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof Index)) { - return false; - } - - Index otherIndex = (Index) other; - return zeroBasedIndex == otherIndex.zeroBasedIndex; - } - - @Override - public String toString() { - return new ToStringBuilder(this).add("zeroBasedIndex", zeroBasedIndex).toString(); - } -} diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java index 8e69fc06a93..1445b6b409b 100644 --- a/src/main/java/seedu/address/logic/Messages.java +++ b/src/main/java/seedu/address/logic/Messages.java @@ -17,7 +17,6 @@ public class Messages { public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command"; public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; - public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; public static final String MESSAGE_INVALID_PERSON_ID = "There is no person with id %1$d"; public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; public static final String MESSAGE_DUPLICATE_FIELDS = diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java index 1bf35f5cc70..4503e6b0a33 100644 --- a/src/main/java/seedu/address/logic/parser/ParserUtil.java +++ b/src/main/java/seedu/address/logic/parser/ParserUtil.java @@ -7,7 +7,6 @@ import java.util.List; import java.util.Set; -import seedu.address.commons.core.index.Index; import seedu.address.commons.util.StringUtil; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.person.Address; @@ -29,24 +28,6 @@ */ public class ParserUtil { - public static final String MESSAGE_INVALID_INDEX = "Index is not a non-zero unsigned integer."; - - /** - * Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading - * and trailing whitespaces will be - * trimmed. - * - * @throws ParseException if the specified index is invalid (not non-zero - * unsigned integer). - */ - public static Index parseIndex(String oneBasedIndex) throws ParseException { - String trimmedIndex = oneBasedIndex.trim(); - if (!StringUtil.isNonZeroUnsignedInteger(trimmedIndex)) { - throw new ParseException(MESSAGE_INVALID_INDEX); - } - return Index.fromOneBased(Integer.parseInt(trimmedIndex)); - } - /** * Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing whitespaces will be * trimmed. diff --git a/src/test/java/seedu/address/commons/core/index/IndexTest.java b/src/test/java/seedu/address/commons/core/index/IndexTest.java deleted file mode 100644 index a497d9628fa..00000000000 --- a/src/test/java/seedu/address/commons/core/index/IndexTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package seedu.address.commons.core.index; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static seedu.address.testutil.Assert.assertThrows; - -import org.junit.jupiter.api.Test; - -public class IndexTest { - - @Test - public void createOneBasedIndex() { - // invalid index - assertThrows(IndexOutOfBoundsException.class, () -> Index.fromOneBased(0)); - - // check equality using the same base - assertEquals(1, Index.fromOneBased(1).getOneBased()); - assertEquals(5, Index.fromOneBased(5).getOneBased()); - - // convert from one-based index to zero-based index - assertEquals(0, Index.fromOneBased(1).getZeroBased()); - assertEquals(4, Index.fromOneBased(5).getZeroBased()); - } - - @Test - public void createZeroBasedIndex() { - // invalid index - assertThrows(IndexOutOfBoundsException.class, () -> Index.fromZeroBased(-1)); - - // check equality using the same base - assertEquals(0, Index.fromZeroBased(0).getZeroBased()); - assertEquals(5, Index.fromZeroBased(5).getZeroBased()); - - // convert from zero-based index to one-based index - assertEquals(1, Index.fromZeroBased(0).getOneBased()); - assertEquals(6, Index.fromZeroBased(5).getOneBased()); - } - - @Test - public void equals() { - final Index fifthPersonIndex = Index.fromOneBased(5); - - // same values -> returns true - assertEquals(fifthPersonIndex, Index.fromOneBased(5)); - assertEquals(fifthPersonIndex, Index.fromZeroBased(4)); - - // same object -> returns true - assertEquals(fifthPersonIndex, fifthPersonIndex); - - // null -> returns false - assertNotEquals(null, fifthPersonIndex); - - // different types -> returns false - assertFalse(fifthPersonIndex.equals(0.5f)); - - // different index -> returns false - assertNotEquals(fifthPersonIndex, Index.fromOneBased(1)); - } - - @Test - public void toStringMethod() { - Index index = Index.fromZeroBased(0); - String expected = Index.class.getCanonicalName() + "{zeroBasedIndex=" + index.getZeroBased() + "}"; - assertEquals(expected, index.toString()); - } -} diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java index 0032d47a594..0c922016113 100644 --- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java +++ b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java @@ -22,7 +22,6 @@ import java.util.Collections; import java.util.List; -import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; import seedu.address.model.NetConnect; @@ -163,21 +162,6 @@ public static void assertCommandFailure(Command command, Model actualModel, Stri assertEquals(expectedFilteredList, actualModel.getFilteredPersonList()); } - /** - * Updates {@code model}'s filtered list to show only the person at the given - * {@code targetIndex} in the - * {@code model}'s address book. - */ - public static void showPersonAtIndex(Model model, Index targetIndex) { - assertTrue(targetIndex.getZeroBased() < model.getFilteredPersonList().size()); - - Person person = model.getFilteredPersonList().get(targetIndex.getZeroBased()); - final String[] splitName = person.getName().fullName.split("\\s+"); - model.updateFilteredPersonList(new NameContainsKeywordsPredicate(Collections.singletonList(splitName[0]))); - - assertEquals(1, model.getFilteredPersonList().size()); - } - /** * Updates {@code model}'s filtered list to show only the person at the given * {@code targetId} in the {@code model}'s netconnect. diff --git a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java index 1caec03eba1..5d97d12cf2d 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java @@ -13,7 +13,6 @@ import org.junit.jupiter.api.Test; -import seedu.address.commons.core.index.Index; import seedu.address.logic.Messages; import seedu.address.model.Model; import seedu.address.model.ModelManager; @@ -110,7 +109,6 @@ public void equals() { @Test public void toStringMethod() { - Index targetIndex = Index.fromOneBased(1); Id targetId = ID_FIRST_PERSON; DeleteCommand deleteCommand = new DeleteCommand(targetId); String expected = DeleteCommand.class.getCanonicalName() + "{targetId=" + targetId + "}"; diff --git a/src/test/java/seedu/address/logic/commands/ListCommandTest.java b/src/test/java/seedu/address/logic/commands/ListCommandTest.java index b60fb5dd3af..1f8bc0116c2 100644 --- a/src/test/java/seedu/address/logic/commands/ListCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/ListCommandTest.java @@ -1,8 +1,8 @@ package seedu.address.logic.commands; import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; +import static seedu.address.logic.commands.CommandTestUtil.showPersonAtId; +import static seedu.address.testutil.TypicalIds.ID_FIRST_PERSON; import static seedu.address.testutil.TypicalPersons.getTypicalNetConnect; import org.junit.jupiter.api.BeforeEach; @@ -34,7 +34,7 @@ public void execute_listIsNotFiltered_showsSameList() { @Test public void execute_listIsFiltered_showsEverything() { - showPersonAtIndex(model, INDEX_FIRST_PERSON); + showPersonAtId(model, ID_FIRST_PERSON); assertCommandSuccess(new ListCommand(), model, ListCommand.MESSAGE_SUCCESS, expectedModel); } } diff --git a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java index 1eed7db4be8..bdbe42a6240 100644 --- a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java +++ b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java @@ -2,10 +2,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.parser.ParserUtil.MESSAGE_INVALID_INDEX; import static seedu.address.testutil.Assert.assertThrows; import static seedu.address.testutil.TypicalIds.ID_FIRST_PERSON; -import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON; import java.util.Arrays; import java.util.Collection; @@ -56,26 +54,6 @@ public class ParserUtilTest { private static final String WHITESPACE = " \t\r\n"; - @Test - public void parseIndex_invalidInput_throwsParseException() { - assertThrows(ParseException.class, () -> ParserUtil.parseIndex("10 a")); - } - - @Test - public void parseIndex_outOfRangeInput_throwsParseException() { - assertThrows(ParseException.class, MESSAGE_INVALID_INDEX, () - -> ParserUtil.parseIndex(Long.toString(Integer.MAX_VALUE + 1))); - } - - @Test - public void parseIndex_validInput_success() throws Exception { - // No whitespaces - assertEquals(INDEX_FIRST_PERSON, ParserUtil.parseIndex("1")); - - // Leading and trailing whitespaces - assertEquals(INDEX_FIRST_PERSON, ParserUtil.parseIndex(" 1 ")); - } - @Test public void parseId_invalidInput_throwsParseException() { assertThrows(ParseException.class, () -> ParserUtil.parseId("0")); diff --git a/src/test/java/seedu/address/logic/parser/RemarkCommandParserTest.java b/src/test/java/seedu/address/logic/parser/RemarkCommandParserTest.java index afb4bbb9511..f4a318efb11 100644 --- a/src/test/java/seedu/address/logic/parser/RemarkCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/RemarkCommandParserTest.java @@ -11,19 +11,26 @@ import seedu.address.logic.Messages; import seedu.address.logic.commands.RemarkCommand; +import seedu.address.model.person.Id; import seedu.address.model.person.Remark; public class RemarkCommandParserTest { private final RemarkCommandParser parser = new RemarkCommandParser(); @Test - public void parse_validIndex_returnsDeleteCommand() { + public void parse_validId_returnsRemarkCommand() { assertParseSuccess(parser, " i/1 r/remark", new RemarkCommand(ID_FIRST_PERSON, new Remark("remark"))); } @Test - public void parse_repeatedFields_throwsParserException() { + public void parse_invalidId_throwsParseException() { + assertParseFailure(parser, " i/0 r/remark", + String.format(Id.MESSAGE_CONSTRAINTS)); + } + + @Test + public void parse_repeatedFields_throwsParseException() { // repeated id assertParseFailure(parser, " i/1 i/2 r/remark", String.format(Messages.getErrorMessageForDuplicatePrefixes(PREFIX_ID))); diff --git a/src/test/java/seedu/address/testutil/TestUtil.java b/src/test/java/seedu/address/testutil/TestUtil.java index 896d103eb0b..6b23436c9e3 100644 --- a/src/test/java/seedu/address/testutil/TestUtil.java +++ b/src/test/java/seedu/address/testutil/TestUtil.java @@ -5,10 +5,6 @@ import java.nio.file.Path; import java.nio.file.Paths; -import seedu.address.commons.core.index.Index; -import seedu.address.model.Model; -import seedu.address.model.person.Person; - /** * A utility class for test cases. */ @@ -31,25 +27,4 @@ public static Path getFilePathInSandboxFolder(String fileName) { } return SANDBOX_FOLDER.resolve(fileName); } - - /** - * Returns the middle index of the person in the {@code model}'s person list. - */ - public static Index getMidIndex(Model model) { - return Index.fromOneBased(model.getFilteredPersonList().size() / 2); - } - - /** - * Returns the last index of the person in the {@code model}'s person list. - */ - public static Index getLastIndex(Model model) { - return Index.fromOneBased(model.getFilteredPersonList().size()); - } - - /** - * Returns the person in the {@code model}'s person list at {@code index}. - */ - public static Person getPerson(Model model, Index index) { - return model.getFilteredPersonList().get(index.getZeroBased()); - } } diff --git a/src/test/java/seedu/address/testutil/TypicalIndexes.java b/src/test/java/seedu/address/testutil/TypicalIndexes.java deleted file mode 100644 index f34d5da14bc..00000000000 --- a/src/test/java/seedu/address/testutil/TypicalIndexes.java +++ /dev/null @@ -1,11 +0,0 @@ -package seedu.address.testutil; - -import seedu.address.commons.core.index.Index; - -/** - * A utility class containing a list of {@code Index} objects to be used in tests. - */ -public class TypicalIndexes { - public static final Index INDEX_FIRST_PERSON = Index.fromOneBased(1); - public static final Index INDEX_SECOND_PERSON = Index.fromOneBased(2); -} From 637406ec2f0f1e194e0488e722154deaa5f29eeb Mon Sep 17 00:00:00 2001 From: nuyer <98694104+nuyer@users.noreply.github.com> Date: Wed, 3 Apr 2024 13:28:27 +0800 Subject: [PATCH 13/29] Update CsvExporterTest.java --- .../address/logic/utils/CsvExporterTest.java | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java index 910cd73b5f4..1bec41becd8 100644 --- a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java +++ b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java @@ -6,12 +6,16 @@ import java.io.File; import java.util.Arrays; +import java.util.List; +import javafx.collections.FXCollections; +import javafx.collections.transformation.FilteredList; +import javafx.collections.ObservableList; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import seedu.address.model.person.Client; -import seedu.address.model.person.UniquePersonList; +import seedu.address.model.person.Person; import seedu.address.testutil.TypicalPersons; @@ -20,16 +24,22 @@ public class CsvExporterTest { private static final String TEST_FILENAME = "test_export.csv"; private CsvExporter csvExporter; - private UniquePersonList persons; + private FilteredList persons; @BeforeEach public void setUp() { - UniquePersonList persons = new UniquePersonList(); - persons.setPersons(Arrays.asList( + ObservableList sourceList = FXCollections.observableArrayList(); + + FilteredList persons = new FilteredList<>(sourceList); + + // Adding typical persons to the filtered list + List personList = Arrays.asList( TypicalPersons.ALICE, TypicalPersons.BENSON, - TypicalPersons.DANIEL, TypicalPersons.ELLE, TypicalPersons.FIONA - )); - this.persons = persons; + TypicalPersons.DANIEL, TypicalPersons.ELLE, TypicalPersons.FIONA); + + // Adding persons directly to the filtered list + persons.addAll(personList); + csvExporter = new CsvExporter(persons, TEST_FILENAME); } From a7090a933bffb11896b4bab38dffbad3467b601b Mon Sep 17 00:00:00 2001 From: nuyer <98694104+nuyer@users.noreply.github.com> Date: Thu, 4 Apr 2024 02:48:26 +0800 Subject: [PATCH 14/29] Correct Style --- .../java/seedu/address/logic/utils/CsvExporterTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java index 1bec41becd8..c04f488ba0f 100644 --- a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java +++ b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java @@ -8,17 +8,16 @@ import java.util.Arrays; import java.util.List; -import javafx.collections.FXCollections; -import javafx.collections.transformation.FilteredList; -import javafx.collections.ObservableList; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.collections.transformation.FilteredList; import seedu.address.model.person.Client; import seedu.address.model.person.Person; import seedu.address.testutil.TypicalPersons; - public class CsvExporterTest { private static final String TEST_FILENAME = "test_export.csv"; From 1f91f08c5378ccc82664a3720b162542622ba920 Mon Sep 17 00:00:00 2001 From: nuyer <98694104+nuyer@users.noreply.github.com> Date: Thu, 4 Apr 2024 10:31:29 +0800 Subject: [PATCH 15/29] Fix Test cases for CsvExporter --- .../seedu/address/logic/utils/CsvExporterTest.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java index c04f488ba0f..1133347812e 100644 --- a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java +++ b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java @@ -27,17 +27,13 @@ public class CsvExporterTest { @BeforeEach public void setUp() { - ObservableList sourceList = FXCollections.observableArrayList(); - - FilteredList persons = new FilteredList<>(sourceList); - - // Adding typical persons to the filtered list List personList = Arrays.asList( TypicalPersons.ALICE, TypicalPersons.BENSON, TypicalPersons.DANIEL, TypicalPersons.ELLE, TypicalPersons.FIONA); - // Adding persons directly to the filtered list - persons.addAll(personList); + ObservableList sourceList = FXCollections.observableArrayList(personList); + + persons = new FilteredList<>(sourceList); csvExporter = new CsvExporter(persons, TEST_FILENAME); } From a81feaf208528fb4076f34f0595e60324a1eb166 Mon Sep 17 00:00:00 2001 From: nuyer <98694104+nuyer@users.noreply.github.com> Date: Thu, 4 Apr 2024 10:50:48 +0800 Subject: [PATCH 16/29] Add Testcases for CsvExporter --- .../address/logic/utils/CsvExporter.java | 2 +- .../address/logic/utils/CsvExporterTest.java | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/utils/CsvExporter.java b/src/main/java/seedu/address/logic/utils/CsvExporter.java index defd3fd4282..d927a79c4b7 100644 --- a/src/main/java/seedu/address/logic/utils/CsvExporter.java +++ b/src/main/java/seedu/address/logic/utils/CsvExporter.java @@ -91,7 +91,7 @@ public String[] convertPersonToStringArray(Person person) { Employee employee = (Employee) person; personStringArray[7] = employee.getDepartment().toString(); personStringArray[8] = employee.getJobTitle().toString(); - personStringArray[9] = employee.getSkills().toString(); + personStringArray[9] = employee.getSkills().toString().replace("[", "").replace("]", ""); personStringArray[10] = ""; personStringArray[11] = ""; personStringArray[12] = ""; diff --git a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java index 1133347812e..48f263514dc 100644 --- a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java +++ b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java @@ -75,4 +75,41 @@ public void convertPersonToStringArray() { }; assertArrayEquals(expectedArray, csvExporter.convertPersonToStringArray(person)); } + + @Test + public void getIsSuccessful_afterSuccessfulExecution() { + csvExporter.execute(); + assertTrue(csvExporter.getIsSuccessful()); + } + + @Test + public void getIsSuccessful_afterFailedExecution() { + csvExporter = new CsvExporter(persons, ""); + csvExporter.execute(); + assertFalse(csvExporter.getIsSuccessful()); + } + + @Test + public void convertPersonToStringArray_employee() { + String[] expectedArray = new String[]{ + "3", "Daniel Meier", "87652533", "cornelia@example.com", "\"10th street\"", "some remarks", "\"friends\"", "Marketing", "Manager", "Digital Marketing, Public Speaking", "", "", "" + }; + assertArrayEquals(expectedArray, csvExporter.convertPersonToStringArray(TypicalPersons.DANIEL)); + } + + @Test + public void convertPersonToStringArray_client() { + String[] expectedArray = new String[]{ + "1", "Alice Pauline", "94351253", "alice@example.com", "\"123, Jurong West Ave 6, #08-111\"", "some remarks", "\"friends\"", "", "", "", "Product1, Product2", "Vegan", "" + }; + assertArrayEquals(expectedArray, csvExporter.convertPersonToStringArray(TypicalPersons.ALICE)); + } + + @Test + public void convertPersonToStringArray_supplier() { + String[] expectedArray = new String[]{ + "5", "Fiona Kunz", "9482427", "lydia@example.com", "\"little tokyo\"", "some remarks", "\"\"", "", "", "", "Office Supplies, Furniture", "", "Delivery within 2 weeks" + }; + assertArrayEquals(expectedArray, csvExporter.convertPersonToStringArray(TypicalPersons.FIONA)); + } } From 953c196018d0d02ce45bc400019b3c3cad204f7c Mon Sep 17 00:00:00 2001 From: nuyer <98694104+nuyer@users.noreply.github.com> Date: Thu, 4 Apr 2024 10:56:03 +0800 Subject: [PATCH 17/29] Correct Style for CsvExporter --- .../java/seedu/address/logic/utils/CsvExporterTest.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java index 48f263514dc..b6686c84e61 100644 --- a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java +++ b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java @@ -92,7 +92,8 @@ public void getIsSuccessful_afterFailedExecution() { @Test public void convertPersonToStringArray_employee() { String[] expectedArray = new String[]{ - "3", "Daniel Meier", "87652533", "cornelia@example.com", "\"10th street\"", "some remarks", "\"friends\"", "Marketing", "Manager", "Digital Marketing, Public Speaking", "", "", "" + "3", "Daniel Meier", "87652533", "cornelia@example.com", "\"10th street\"", "some remarks", + "\"friends\"", "Marketing", "Manager", "Digital Marketing, Public Speaking", "", "", "" }; assertArrayEquals(expectedArray, csvExporter.convertPersonToStringArray(TypicalPersons.DANIEL)); } @@ -100,7 +101,8 @@ public void convertPersonToStringArray_employee() { @Test public void convertPersonToStringArray_client() { String[] expectedArray = new String[]{ - "1", "Alice Pauline", "94351253", "alice@example.com", "\"123, Jurong West Ave 6, #08-111\"", "some remarks", "\"friends\"", "", "", "", "Product1, Product2", "Vegan", "" + "1", "Alice Pauline", "94351253", "alice@example.com", "\"123, Jurong West Ave 6, #08-111\"", + "some remarks", "\"friends\"", "", "", "", "Product1, Product2", "Vegan", "" }; assertArrayEquals(expectedArray, csvExporter.convertPersonToStringArray(TypicalPersons.ALICE)); } @@ -108,7 +110,8 @@ public void convertPersonToStringArray_client() { @Test public void convertPersonToStringArray_supplier() { String[] expectedArray = new String[]{ - "5", "Fiona Kunz", "9482427", "lydia@example.com", "\"little tokyo\"", "some remarks", "\"\"", "", "", "", "Office Supplies, Furniture", "", "Delivery within 2 weeks" + "5", "Fiona Kunz", "9482427", "lydia@example.com", "\"little tokyo\"", "some remarks", "\"\"", "", "", + "", "Office Supplies, Furniture", "", "Delivery within 2 weeks" }; assertArrayEquals(expectedArray, csvExporter.convertPersonToStringArray(TypicalPersons.FIONA)); } From 76d3bf26362170665884967cae0ba4f1f826c416 Mon Sep 17 00:00:00 2001 From: nuyer <98694104+nuyer@users.noreply.github.com> Date: Thu, 4 Apr 2024 11:18:14 +0800 Subject: [PATCH 18/29] Add test cases for CsvExporter --- .../address/logic/utils/CsvExporter.java | 4 +-- .../address/logic/utils/CsvExporterTest.java | 35 ++++++++++++++++++- test_export.csv | 6 ++++ 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 test_export.csv diff --git a/src/main/java/seedu/address/logic/utils/CsvExporter.java b/src/main/java/seedu/address/logic/utils/CsvExporter.java index d927a79c4b7..be7d6fd100f 100644 --- a/src/main/java/seedu/address/logic/utils/CsvExporter.java +++ b/src/main/java/seedu/address/logic/utils/CsvExporter.java @@ -57,7 +57,7 @@ public void execute() { * * @return A list of string arrays representing the data to be exported. */ - private List createDataList() { + protected List createDataList() { List dataList = new ArrayList<>(); String[] fieldNames = {"ID", "Name", "Phone", "Email", "Address", "Remark", "Tags", "Department", "Job Title", "Skills", "Products", "Preferences", "Terms of Service"}; @@ -86,7 +86,7 @@ public String[] convertPersonToStringArray(Person person) { personStringArray[3] = person.getEmail().toString(); personStringArray[4] = "\"" + person.getAddress().toString() + "\""; personStringArray[5] = (person.getRemark() != null) ? person.getRemark().toString() : ""; - personStringArray[6] = "\"" + person.getTagsAsString() + "\""; + personStringArray[6] = !person.getTags().isEmpty() ? "\"" + person.getTagsAsString() + "\"" : ""; if (person instanceof Employee) { Employee employee = (Employee) person; personStringArray[7] = employee.getDepartment().toString(); diff --git a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java index b6686c84e61..bd26b990127 100644 --- a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java +++ b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -16,6 +17,9 @@ import javafx.collections.transformation.FilteredList; import seedu.address.model.person.Client; import seedu.address.model.person.Person; +import seedu.address.testutil.ClientBuilder; +import seedu.address.testutil.EmployeeBuilder; +import seedu.address.testutil.SupplierBuilder; import seedu.address.testutil.TypicalPersons; public class CsvExporterTest { @@ -38,6 +42,35 @@ public void setUp() { csvExporter = new CsvExporter(persons, TEST_FILENAME); } + @Test + public void createDataList_correctlyConstructedList() { + List persons = Arrays.asList( + new EmployeeBuilder().withId(1).withName("John Doe").withPhone("1234567890").withEmail("john@example.com") + .withAddress("123 Main St").withDepartment("HR").withJobTitle("Manager").withSkills("Java, SQL").build(), + new ClientBuilder().withId(2).withName("Jane Smith").withPhone("9876543210").withEmail("jane@example.com") + .withAddress("456 Elm St").withProducts("Product A").withPreferences("Likes discounts").build(), + new SupplierBuilder().withId(3).withName("Acme Inc").withPhone("5555555555").withEmail("info@acme.com") + .withAddress("789 Oak St").withProducts("Product X").withTermsOfService("30 days").build() + ); + FilteredList filteredList = new FilteredList<>(FXCollections.observableArrayList(persons)); + CsvExporter csvExporter = new CsvExporter(filteredList, "test.csv"); + + List dataList = csvExporter.createDataList(); + + assertTrue(dataList != null); + assertTrue(dataList.size() == 4); + + assertArrayEquals(new String[]{"ID", "Name", "Phone", "Email", "Address", "Remark", "Tags", "Department", + "Job Title", "Skills", "Products", "Preferences", "Terms of Service"}, dataList.get(0)); + + assertArrayEquals(new String[]{"1", "John Doe", "1234567890", "john@example.com", "\"123 Main St\"", "some remarks", "", "HR", + "Manager", "Java, SQL", "", "", ""}, dataList.get(1)); + assertArrayEquals(new String[]{"2", "Jane Smith", "9876543210", "jane@example.com", "\"456 Elm St\"", "some remarks", "", + "", "", "", "Product A", "Likes discounts", ""}, dataList.get(2)); + assertArrayEquals(new String[]{"3", "Acme Inc", "5555555555", "info@acme.com", "\"789 Oak St\"", "some remarks", "", + "", "", "", "Product X", "", "30 days"}, dataList.get(3)); + } + @Test public void execute_exportSuccess() { csvExporter.execute(); @@ -110,7 +143,7 @@ public void convertPersonToStringArray_client() { @Test public void convertPersonToStringArray_supplier() { String[] expectedArray = new String[]{ - "5", "Fiona Kunz", "9482427", "lydia@example.com", "\"little tokyo\"", "some remarks", "\"\"", "", "", + "5", "Fiona Kunz", "9482427", "lydia@example.com", "\"little tokyo\"", "some remarks", "", "", "", "", "Office Supplies, Furniture", "", "Delivery within 2 weeks" }; assertArrayEquals(expectedArray, csvExporter.convertPersonToStringArray(TypicalPersons.FIONA)); diff --git a/test_export.csv b/test_export.csv new file mode 100644 index 00000000000..052b66022b3 --- /dev/null +++ b/test_export.csv @@ -0,0 +1,6 @@ +ID,Name,Phone,Email,Address,Remark,Tags,Department,Job Title,Skills,Products,Preferences,Terms of Service +1,Alice Pauline,94351253,alice@example.com,"123, Jurong West Ave 6, #08-111",some remarks,"friends",,,,Product1, Product2,Vegan, +2,Benson Meier,98765432,johnd@example.com,"311, Clementi Ave 2, #02-25",some remarks,"owesMoney, friends",,,,Product3,Gluten-Free, +3,Daniel Meier,87652533,cornelia@example.com,"10th street",some remarks,"friends",Marketing,Manager,Digital Marketing, Public Speaking,,, +4,Elle Meyer,9482224,werner@example.com,"michegan ave",some remarks,,IT,Developer,Java, C++,,, +5,Fiona Kunz,9482427,lydia@example.com,"little tokyo",some remarks,,,,,Office Supplies, Furniture,,Delivery within 2 weeks From ce45c35d6c7ebb12726ae812c9b741e280958bc9 Mon Sep 17 00:00:00 2001 From: nuyer <98694104+nuyer@users.noreply.github.com> Date: Thu, 4 Apr 2024 11:22:04 +0800 Subject: [PATCH 19/29] Correct Style --- .../address/logic/utils/CsvExporterTest.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java index bd26b990127..4f1b7310658 100644 --- a/src/test/java/seedu/address/logic/utils/CsvExporterTest.java +++ b/src/test/java/seedu/address/logic/utils/CsvExporterTest.java @@ -5,7 +5,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -45,10 +44,13 @@ public void setUp() { @Test public void createDataList_correctlyConstructedList() { List persons = Arrays.asList( - new EmployeeBuilder().withId(1).withName("John Doe").withPhone("1234567890").withEmail("john@example.com") - .withAddress("123 Main St").withDepartment("HR").withJobTitle("Manager").withSkills("Java, SQL").build(), - new ClientBuilder().withId(2).withName("Jane Smith").withPhone("9876543210").withEmail("jane@example.com") - .withAddress("456 Elm St").withProducts("Product A").withPreferences("Likes discounts").build(), + new EmployeeBuilder().withId(1).withName("John Doe").withPhone("1234567890") + .withEmail("john@example.com").withAddress("123 Main St").withDepartment("HR") + .withJobTitle("Manager").withSkills("Java, SQL").build(), + new ClientBuilder().withId(2).withName("Jane Smith").withPhone("9876543210") + .withEmail("jane@example.com") + .withAddress("456 Elm St").withProducts("Product A").withPreferences("Likes discounts") + .build(), new SupplierBuilder().withId(3).withName("Acme Inc").withPhone("5555555555").withEmail("info@acme.com") .withAddress("789 Oak St").withProducts("Product X").withTermsOfService("30 days").build() ); @@ -61,14 +63,14 @@ public void createDataList_correctlyConstructedList() { assertTrue(dataList.size() == 4); assertArrayEquals(new String[]{"ID", "Name", "Phone", "Email", "Address", "Remark", "Tags", "Department", - "Job Title", "Skills", "Products", "Preferences", "Terms of Service"}, dataList.get(0)); - - assertArrayEquals(new String[]{"1", "John Doe", "1234567890", "john@example.com", "\"123 Main St\"", "some remarks", "", "HR", - "Manager", "Java, SQL", "", "", ""}, dataList.get(1)); - assertArrayEquals(new String[]{"2", "Jane Smith", "9876543210", "jane@example.com", "\"456 Elm St\"", "some remarks", "", - "", "", "", "Product A", "Likes discounts", ""}, dataList.get(2)); - assertArrayEquals(new String[]{"3", "Acme Inc", "5555555555", "info@acme.com", "\"789 Oak St\"", "some remarks", "", - "", "", "", "Product X", "", "30 days"}, dataList.get(3)); + "Job Title", "Skills", "Products", "Preferences", "Terms of Service"}, dataList.get(0)); + + assertArrayEquals(new String[]{"1", "John Doe", "1234567890", "john@example.com", "\"123 Main St\"", + "some remarks", "", "HR", "Manager", "Java, SQL", "", "", ""}, dataList.get(1)); + assertArrayEquals(new String[]{"2", "Jane Smith", "9876543210", "jane@example.com", "\"456 Elm St\"", + "some remarks", "", "", "", "", "Product A", "Likes discounts", ""}, dataList.get(2)); + assertArrayEquals(new String[]{"3", "Acme Inc", "5555555555", "info@acme.com", "\"789 Oak St\"", + "some remarks", "", "", "", "", "Product X", "", "30 days"}, dataList.get(3)); } @Test From c9d2ef06343f79df1bc6fbb042b795726f31046b Mon Sep 17 00:00:00 2001 From: nuyer <98694104+nuyer@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:23:37 +0800 Subject: [PATCH 20/29] Add ModelManagerTest testcases --- .../seedu/address/model/ModelManagerTest.java | 58 ++++++++++++++----- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/address/model/ModelManagerTest.java index 1e7e6664b1f..3bacd219751 100644 --- a/src/test/java/seedu/address/model/ModelManagerTest.java +++ b/src/test/java/seedu/address/model/ModelManagerTest.java @@ -3,7 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; import static seedu.address.testutil.Assert.assertThrows; import static seedu.address.testutil.TypicalIds.ID_FIRST_PERSON; import static seedu.address.testutil.TypicalPersons.ALICE; @@ -128,39 +127,68 @@ public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException } @Test - public void equals() { + public void equals_sameValues_returnsTrue() { NetConnect netConnect = new NetConnectBuilder().withPerson(ALICE).withPerson(BENSON).build(); - NetConnect differentNetConnect = new NetConnect(); UserPrefs userPrefs = new UserPrefs(); - // same values -> returns true modelManager = new ModelManager(netConnect, userPrefs); ModelManager modelManagerCopy = new ModelManager(netConnect, userPrefs); + assertTrue(modelManager.equals(modelManagerCopy)); + } - // same object -> returns true + @Test + public void equals_sameObject_returnsTrue() { assertTrue(modelManager.equals(modelManager)); + } - // null -> returns false + @Test + public void equals_nullObject_returnsFalse() { assertFalse(modelManager.equals(null)); + } - // different types -> returns false + @Test + public void equals_differentTypes_returnsFalse() { assertFalse(modelManager.equals(5)); + } + + @Test + public void equals_differentNetConnect_returnsFalse() { + NetConnect netConnect = new NetConnectBuilder().withPerson(ALICE).withPerson(BENSON).build(); + NetConnect differentNetConnect = new NetConnect(); + UserPrefs userPrefs = new UserPrefs(); + + modelManager = new ModelManager(netConnect, userPrefs); + ModelManager otherModelManager = new ModelManager(differentNetConnect, userPrefs); - // different netConnect -> returns false - assertFalse(modelManager.equals(new ModelManager(differentNetConnect, userPrefs))); + assertFalse(modelManager.equals(otherModelManager)); + } + + @Test + public void equals_differentFilteredPersonList_returnsFalse() { + NetConnect netConnect = new NetConnectBuilder().withPerson(ALICE).withPerson(BENSON).build(); + UserPrefs userPrefs = new UserPrefs(); - // different filteredList -> returns false + modelManager = new ModelManager(netConnect, userPrefs); String[] keywords = ALICE.getName().fullName.split("\\s+"); modelManager.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(keywords))); - assertFalse(modelManager.equals(new ModelManager(netConnect, userPrefs))); - // resets modelManager to initial state for upcoming tests - modelManager.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); + ModelManager modelManagerCopy = new ModelManager(netConnect, userPrefs); + + assertFalse(modelManager.equals(modelManagerCopy)); + } - // different userPrefs -> returns false + @Test + public void equals_differentUserPrefs_returnsFalse() { + NetConnect netConnect = new NetConnectBuilder().withPerson(ALICE).withPerson(BENSON).build(); + UserPrefs userPrefs = new UserPrefs(); UserPrefs differentUserPrefs = new UserPrefs(); differentUserPrefs.setNetConnectFilePath(Paths.get("differentFilePath")); - assertFalse(modelManager.equals(new ModelManager(netConnect, differentUserPrefs))); + + modelManager = new ModelManager(netConnect, userPrefs); + ModelManager modelManagerCopy = new ModelManager(netConnect, differentUserPrefs); + + assertFalse(modelManager.equals(modelManagerCopy)); } + } From 0268e444ffd2d59cd8b843b42bc9d818b28adc00 Mon Sep 17 00:00:00 2001 From: nuyer <98694104+nuyer@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:36:33 +0800 Subject: [PATCH 21/29] Update ModelManagerTest.java --- src/test/java/seedu/address/model/ModelManagerTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/address/model/ModelManagerTest.java index 3bacd219751..8ec2bd599d3 100644 --- a/src/test/java/seedu/address/model/ModelManagerTest.java +++ b/src/test/java/seedu/address/model/ModelManagerTest.java @@ -168,13 +168,10 @@ public void equals_differentNetConnect_returnsFalse() { public void equals_differentFilteredPersonList_returnsFalse() { NetConnect netConnect = new NetConnectBuilder().withPerson(ALICE).withPerson(BENSON).build(); UserPrefs userPrefs = new UserPrefs(); - modelManager = new ModelManager(netConnect, userPrefs); String[] keywords = ALICE.getName().fullName.split("\\s+"); modelManager.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(keywords))); - ModelManager modelManagerCopy = new ModelManager(netConnect, userPrefs); - assertFalse(modelManager.equals(modelManagerCopy)); } From cf0aef127a36a3f8a511a4dc66abd3cbc8b8a860 Mon Sep 17 00:00:00 2001 From: nuyer <98694104+nuyer@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:53:43 +0800 Subject: [PATCH 22/29] Update ModelManagerTest.java --- .../seedu/address/model/ModelManagerTest.java | 62 ++++++------------- 1 file changed, 18 insertions(+), 44 deletions(-) diff --git a/src/test/java/seedu/address/model/ModelManagerTest.java b/src/test/java/seedu/address/model/ModelManagerTest.java index 0f546427cde..e590d6fa9a0 100644 --- a/src/test/java/seedu/address/model/ModelManagerTest.java +++ b/src/test/java/seedu/address/model/ModelManagerTest.java @@ -128,67 +128,41 @@ public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException } @Test - public void equals_sameValues_returnsTrue() { + public void equals() { NetConnect netConnect = new NetConnectBuilder().withPerson(ALICE).withPerson(BENSON).build(); + NetConnect differentNetConnect = new NetConnect(); UserPrefs userPrefs = new UserPrefs(); RelatedList relatedList = new RelatedList(); - modelManager = new ModelManager(netConnect, userPrefs); - ModelManager modelManagerCopy = new ModelManager(netConnect, userPrefs); + // same values -> returns true + modelManager = new ModelManager(netConnect, userPrefs, relatedList); + ModelManager modelManagerCopy = new ModelManager(netConnect, userPrefs, relatedList); assertTrue(modelManager.equals(modelManagerCopy)); - } - @Test - public void equals_sameObject_returnsTrue() { + // same object -> returns true assertTrue(modelManager.equals(modelManager)); - } - @Test - public void equals_nullObject_returnsFalse() { + // null -> returns false assertFalse(modelManager.equals(null)); - } - @Test - public void equals_differentTypes_returnsFalse() { + // different types -> returns false assertFalse(modelManager.equals(5)); - } - - @Test - public void equals_differentNetConnect_returnsFalse() { - NetConnect netConnect = new NetConnectBuilder().withPerson(ALICE).withPerson(BENSON).build(); - NetConnect differentNetConnect = new NetConnect(); - UserPrefs userPrefs = new UserPrefs(); - modelManager = new ModelManager(netConnect, userPrefs); - ModelManager otherModelManager = new ModelManager(differentNetConnect, userPrefs); + // different netConnect -> returns false + assertFalse(modelManager.equals(new ModelManager(differentNetConnect, userPrefs, relatedList))); - assertFalse(modelManager.equals(otherModelManager)); - } - - @Test - public void equals_differentFilteredPersonList_returnsFalse() { - NetConnect netConnect = new NetConnectBuilder().withPerson(ALICE).withPerson(BENSON).build(); - UserPrefs userPrefs = new UserPrefs(); - modelManager = new ModelManager(netConnect, userPrefs); + // different filteredList -> returns false String[] keywords = ALICE.getName().fullName.split("\\s+"); - - modelManager.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(keywords))); - ModelManager modelManagerCopy = new ModelManager(netConnect, userPrefs); - assertFalse(modelManager.equals(modelManagerCopy)); - } + modelManager.stackFilters(new NameContainsKeywordsPredicate(Arrays.asList(keywords))); + assertFalse(modelManager.equals(new ModelManager(netConnect, userPrefs, relatedList))); - @Test - public void equals_differentUserPrefs_returnsFalse() { - NetConnect netConnect = new NetConnectBuilder().withPerson(ALICE).withPerson(BENSON).build(); - UserPrefs userPrefs = new UserPrefs(); + // resets modelManager to initial state for upcoming tests + modelManager.clearFilter(); + + // different userPrefs -> returns false UserPrefs differentUserPrefs = new UserPrefs(); differentUserPrefs.setNetConnectFilePath(Paths.get("differentFilePath")); - - modelManager = new ModelManager(netConnect, userPrefs); - ModelManager modelManagerCopy = new ModelManager(netConnect, differentUserPrefs); - - assertFalse(modelManager.equals(modelManagerCopy)); + assertFalse(modelManager.equals(new ModelManager(netConnect, differentUserPrefs, relatedList))); } - } From 16a0410c10ecdbcea14a3050ab8202ba934eb56e Mon Sep 17 00:00:00 2001 From: Shaun Lee Date: Thu, 4 Apr 2024 17:09:49 +0800 Subject: [PATCH 23/29] Integrate findnum into find command --- .../address/logic/commands/FindCommand.java | 5 +- .../logic/commands/FindNumCommand.java | 59 ------------ .../logic/parser/FindCommandParser.java | 11 ++- .../logic/parser/FindNumCommandParser.java | 43 --------- .../logic/parser/NetConnectParser.java | 4 - ....java => PhoneMatchesDigitsPredicate.java} | 12 +-- .../logic/commands/FindNumCommandTest.java | 96 ------------------- .../logic/parser/FindCommandParserTest.java | 30 +++++- .../parser/FindNumCommandParserTest.java | 43 --------- .../logic/parser/NetConnectParserTest.java | 10 -- ...a => PhoneMatchesDigitsPredicateTest.java} | 30 +++--- 11 files changed, 62 insertions(+), 281 deletions(-) delete mode 100644 src/main/java/seedu/address/logic/commands/FindNumCommand.java delete mode 100644 src/main/java/seedu/address/logic/parser/FindNumCommandParser.java rename src/main/java/seedu/address/model/person/filter/{PhoneContainsDigitsPredicate.java => PhoneMatchesDigitsPredicate.java} (66%) delete mode 100644 src/test/java/seedu/address/logic/commands/FindNumCommandTest.java delete mode 100644 src/test/java/seedu/address/logic/parser/FindNumCommandParserTest.java rename src/test/java/seedu/address/model/person/filter/{PhoneContainsDigitsPredicateTest.java => PhoneMatchesDigitsPredicateTest.java} (63%) diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/address/logic/commands/FindCommand.java index 69e6e0755f8..14efdc9f8fb 100644 --- a/src/main/java/seedu/address/logic/commands/FindCommand.java +++ b/src/main/java/seedu/address/logic/commands/FindCommand.java @@ -2,6 +2,7 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK; import static seedu.address.logic.parser.CliSyntax.PREFIX_ROLE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; @@ -24,15 +25,17 @@ public class FindCommand extends Command { public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose information matches any of the given arguments.\n" + "Only one type of argument can be given per " + COMMAND_WORD + " command.\n" - + "Name, tag and role cannot be empty. " + + "Name, phone, tag and role cannot be empty. " + "Remark can be empty to find persons with no remarks.\n" + "Parameters: " + "[" + PREFIX_NAME + "NAME]... " + + "[" + PREFIX_PHONE + "PHONE]..." + "[" + PREFIX_TAG + "TAG]... " + "[" + PREFIX_ROLE + "ROLE]... " + "[" + PREFIX_REMARK + "REMARK]... \n" + "Examples: \n" + COMMAND_WORD + " n/alice n/bob n/charlie\n" + + COMMAND_WORD + " p/91278539 p/83489532\n" + COMMAND_WORD + " t/friends t/colleagues\n" + COMMAND_WORD + " role/client\n" + COMMAND_WORD + " r/owes money r/quarterly report"; diff --git a/src/main/java/seedu/address/logic/commands/FindNumCommand.java b/src/main/java/seedu/address/logic/commands/FindNumCommand.java deleted file mode 100644 index 06ad556b83d..00000000000 --- a/src/main/java/seedu/address/logic/commands/FindNumCommand.java +++ /dev/null @@ -1,59 +0,0 @@ -package seedu.address.logic.commands; - -import static java.util.Objects.requireNonNull; - -import seedu.address.commons.util.ToStringBuilder; -import seedu.address.logic.Messages; -import seedu.address.model.Model; -import seedu.address.model.person.filter.PhoneContainsDigitsPredicate; - -/** - * Finds and lists all persons in address book whose phone number contains any of the argument phone numbers. - */ -public class FindNumCommand extends Command { - - public static final String COMMAND_WORD = "findnum"; - - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose phone number contain any of " - + "the specified numbers and displays them as a list with index numbers.\n" - + "A phone number must have more 3 or more numeric digits.\n" - + "Parameters: PHONE_NUMBER [PHONE_NUMBERS]...\n" - + "Example: " + COMMAND_WORD + " 87438807"; - - private final PhoneContainsDigitsPredicate predicate; - - public FindNumCommand(PhoneContainsDigitsPredicate predicate) { - this.predicate = predicate; - } - - @Override - public CommandResult execute(Model model) { - requireNonNull(model); - model.clearFilter(); - model.stackFilters(predicate); - return new CommandResult( - String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size())); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof FindNumCommand)) { - return false; - } - - FindNumCommand otherFindNumCommand = (FindNumCommand) other; - return predicate.equals(otherFindNumCommand.predicate); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .add("predicate", predicate) - .toString(); - } -} diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/address/logic/parser/FindCommandParser.java index 476eaeffdf3..3e2824a003b 100644 --- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/FindCommandParser.java @@ -3,6 +3,7 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK; import static seedu.address.logic.parser.CliSyntax.PREFIX_ROLE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; @@ -13,8 +14,10 @@ import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.person.Name; import seedu.address.model.person.Person; +import seedu.address.model.person.Phone; import seedu.address.model.person.filter.NameContainsKeywordsPredicate; import seedu.address.model.person.filter.NetConnectPredicate; +import seedu.address.model.person.filter.PhoneMatchesDigitsPredicate; import seedu.address.model.person.filter.RemarkContainsKeywordsPredicate; import seedu.address.model.person.filter.RoleMatchesKeywordsPredicate; import seedu.address.model.person.filter.TagsContainsKeywordsPredicate; @@ -34,7 +37,7 @@ public class FindCommandParser implements Parser { public FindCommand parse(String args) throws ParseException { requireNonNull(args); ArgumentMultimap argMultimap = ArgumentTokenizer - .tokenize(args, PREFIX_NAME, PREFIX_TAG, PREFIX_ROLE, PREFIX_REMARK); + .tokenize(args, PREFIX_NAME, PREFIX_TAG, PREFIX_ROLE, PREFIX_REMARK, PREFIX_PHONE); argMultimap.verifyOnlyOnePrefix(); return new FindCommand(createPredicate(argMultimap)); @@ -69,6 +72,12 @@ private static NetConnectPredicate createPredicate( } else if (argMultimap.getValue(PREFIX_REMARK).isPresent()) { List remarks = argMultimap.getAllValues(PREFIX_REMARK); return new RemarkContainsKeywordsPredicate(remarks); + } else if (argMultimap.getValue(PREFIX_PHONE).isPresent()) { + List phones = argMultimap.getAllValues(PREFIX_PHONE); + if (!phones.stream().allMatch(Phone::isValidPhone)) { + throw new ParseException(Phone.MESSAGE_CONSTRAINTS); + } + return new PhoneMatchesDigitsPredicate(phones); } else { // no field provided throw new ParseException( diff --git a/src/main/java/seedu/address/logic/parser/FindNumCommandParser.java b/src/main/java/seedu/address/logic/parser/FindNumCommandParser.java deleted file mode 100644 index a36cad337db..00000000000 --- a/src/main/java/seedu/address/logic/parser/FindNumCommandParser.java +++ /dev/null @@ -1,43 +0,0 @@ -package seedu.address.logic.parser; - -import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; - -import java.util.Arrays; - -import seedu.address.logic.commands.FindNumCommand; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.Phone; -import seedu.address.model.person.filter.PhoneContainsDigitsPredicate; - -/** - * Parses input arguments and creates a new FindNumCommand object - */ -public class FindNumCommandParser implements Parser { - - /** - * Parses the given {@code String} of arguments in the context of the FindNumCommand - * and returns a FindNumCommand object for execution. - * - * @throws ParseException if the user input does not conform the expected format - */ - public FindNumCommand parse(String args) throws ParseException { - String trimmedArgs = args.trim(); - if (trimmedArgs.isEmpty()) { - throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindNumCommand.MESSAGE_USAGE)); - } - - String[] phoneKeywords = trimmedArgs.split("\\s+"); - - // Check if all phone numbers in input are valid - for (String phoneKeyword : phoneKeywords) { - if (!Phone.isValidPhone(phoneKeyword)) { - throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindNumCommand.MESSAGE_USAGE)); - } - } - - return new FindNumCommand(new PhoneContainsDigitsPredicate(Arrays.asList(phoneKeywords))); - } - -} diff --git a/src/main/java/seedu/address/logic/parser/NetConnectParser.java b/src/main/java/seedu/address/logic/parser/NetConnectParser.java index a0b13e5f300..35a351a0271 100644 --- a/src/main/java/seedu/address/logic/parser/NetConnectParser.java +++ b/src/main/java/seedu/address/logic/parser/NetConnectParser.java @@ -16,7 +16,6 @@ import seedu.address.logic.commands.ExitCommand; import seedu.address.logic.commands.ExportCommand; import seedu.address.logic.commands.FindCommand; -import seedu.address.logic.commands.FindNumCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.RemarkCommand; @@ -72,9 +71,6 @@ public Command parseCommand(String userInput) throws ParseException { case FindCommand.COMMAND_WORD: return new FindCommandParser().parse(arguments); - case FindNumCommand.COMMAND_WORD: - return new FindNumCommandParser().parse(arguments); - case RemarkCommand.COMMAND_WORD: return new RemarkCommandParser().parse(arguments); diff --git a/src/main/java/seedu/address/model/person/filter/PhoneContainsDigitsPredicate.java b/src/main/java/seedu/address/model/person/filter/PhoneMatchesDigitsPredicate.java similarity index 66% rename from src/main/java/seedu/address/model/person/filter/PhoneContainsDigitsPredicate.java rename to src/main/java/seedu/address/model/person/filter/PhoneMatchesDigitsPredicate.java index ae7a1f16689..ec0d6311c99 100644 --- a/src/main/java/seedu/address/model/person/filter/PhoneContainsDigitsPredicate.java +++ b/src/main/java/seedu/address/model/person/filter/PhoneMatchesDigitsPredicate.java @@ -3,17 +3,16 @@ import java.util.List; import java.util.stream.Collectors; -import seedu.address.commons.util.StringUtil; import seedu.address.commons.util.ToStringBuilder; import seedu.address.model.person.Person; /** * Tests that a {@code Person}'s {@code Phone} matches any of the keywords given. */ -public class PhoneContainsDigitsPredicate extends NetConnectPredicate { +public class PhoneMatchesDigitsPredicate extends NetConnectPredicate { private final List phones; - public PhoneContainsDigitsPredicate(List phones) { + public PhoneMatchesDigitsPredicate(List phones) { this.phones = phones; } @@ -24,8 +23,7 @@ public String formatFilter() { @Override public boolean test(Person person) { - return phones.stream() - .anyMatch(phone -> StringUtil.containsWordIgnoreCase(person.getPhone().value, phone)); + return phones.stream().anyMatch(person.getPhone().value::equals); } @Override @@ -35,11 +33,11 @@ public boolean equals(Object other) { } // instanceof handles nulls - if (!(other instanceof PhoneContainsDigitsPredicate)) { + if (!(other instanceof PhoneMatchesDigitsPredicate)) { return false; } - PhoneContainsDigitsPredicate otherNameContainsKeywordsPredicate = (PhoneContainsDigitsPredicate) other; + PhoneMatchesDigitsPredicate otherNameContainsKeywordsPredicate = (PhoneMatchesDigitsPredicate) other; return phones.equals(otherNameContainsKeywordsPredicate.phones); } diff --git a/src/test/java/seedu/address/logic/commands/FindNumCommandTest.java b/src/test/java/seedu/address/logic/commands/FindNumCommandTest.java deleted file mode 100644 index 5e50d1e10d2..00000000000 --- a/src/test/java/seedu/address/logic/commands/FindNumCommandTest.java +++ /dev/null @@ -1,96 +0,0 @@ -package seedu.address.logic.commands; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.testutil.TypicalPersons.ALICE; -import static seedu.address.testutil.TypicalPersons.ELLE; -import static seedu.address.testutil.TypicalPersons.GEORGE; -import static seedu.address.testutil.TypicalPersons.getTypicalNetConnect; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.jupiter.api.Test; - -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.UserPrefs; -import seedu.address.model.person.filter.PhoneContainsDigitsPredicate; - -/** - * Contains integration tests (interaction with the Model) for - * {@code FindNumCommand}. - */ -public class FindNumCommandTest { - private final Model model = new ModelManager(getTypicalNetConnect(), new UserPrefs()); - private final Model expectedModel = new ModelManager(getTypicalNetConnect(), new UserPrefs()); - - @Test - public void equals() { - PhoneContainsDigitsPredicate firstPredicate = new PhoneContainsDigitsPredicate( - Collections.singletonList("first")); - PhoneContainsDigitsPredicate secondPredicate = new PhoneContainsDigitsPredicate( - Collections.singletonList("second")); - - FindNumCommand findNumFirstCommand = new FindNumCommand(firstPredicate); - FindNumCommand findNumSecondCommand = new FindNumCommand(secondPredicate); - - // same object -> returns true - assertEquals(findNumFirstCommand, findNumFirstCommand); - - // same values -> returns true - FindNumCommand findNumFirstCommandCopy = new FindNumCommand(firstPredicate); - assertTrue(findNumFirstCommand.equals(findNumFirstCommandCopy)); - - // different types -> returns false - assertFalse(findNumFirstCommand.equals(1)); - - // null -> returns false - assertFalse(findNumFirstCommand.equals(null)); - - // different instance -> returns false - assertFalse(firstPredicate.equals(model)); - - // different person -> returns false - assertFalse(findNumFirstCommand.equals(findNumSecondCommand)); - } - - @Test - public void execute_zeroPhones_noPersonFound() { - String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0); - PhoneContainsDigitsPredicate predicate = preparePredicate(" "); - FindNumCommand command = new FindNumCommand(predicate); - expectedModel.stackFilters(predicate); - assertCommandSuccess(command, model, expectedMessage, expectedModel); - assertEquals(Collections.emptyList(), model.getFilteredPersonList()); - } - - @Test - public void execute_multiplePhones_multiplePersonsFound() { - String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 3); - PhoneContainsDigitsPredicate predicate = preparePredicate("94351253 9482224 9482442"); - FindNumCommand command = new FindNumCommand(predicate); - expectedModel.stackFilters(predicate); - assertCommandSuccess(command, model, expectedMessage, expectedModel); - assertEquals(Arrays.asList(ALICE, ELLE, GEORGE), model.getFilteredPersonList()); - } - - @Test - public void toStringMethod() { - PhoneContainsDigitsPredicate predicate = new PhoneContainsDigitsPredicate(List.of("keyword")); - FindNumCommand findNumCommand = new FindNumCommand(predicate); - String expected = FindNumCommand.class.getCanonicalName() + "{predicate=" + predicate + "}"; - assertEquals(expected, findNumCommand.toString()); - } - - /** - * Parses {@code userInput} into a {@code NameContainsKeywordsPredicate}. - */ - private PhoneContainsDigitsPredicate preparePredicate(String userInput) { - return new PhoneContainsDigitsPredicate(Arrays.asList(userInput.split("\\s+"))); - } -} diff --git a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java index 865087d8584..238cda0f62f 100644 --- a/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/FindCommandParserTest.java @@ -13,7 +13,9 @@ import seedu.address.logic.commands.FindCommand; import seedu.address.model.person.Name; import seedu.address.model.person.Person; +import seedu.address.model.person.Phone; import seedu.address.model.person.filter.NameContainsKeywordsPredicate; +import seedu.address.model.person.filter.PhoneMatchesDigitsPredicate; import seedu.address.model.person.filter.RemarkContainsKeywordsPredicate; import seedu.address.model.person.filter.RoleMatchesKeywordsPredicate; import seedu.address.model.person.filter.TagsContainsKeywordsPredicate; @@ -39,6 +41,17 @@ public void parse_validNames_returnsFindCommand() { assertParseSuccess(parser, " \n n/Alice \n \t n/Bob \t", expectedFindCommand); } + @Test + public void parse_validPhones_returnsFindCommand() { + // no leading and trailing whitespaces + FindCommand expectedFindCommand = + new FindCommand(new PhoneMatchesDigitsPredicate(Arrays.asList("123", "91234567"))); + assertParseSuccess(parser, " p/123 p/91234567", expectedFindCommand); + + // multiple whitespaces between keywords + assertParseSuccess(parser, " \n p/123 \n \t p/91234567 \t", expectedFindCommand); + } + @Test public void parse_validTags_returnsFindCommand() { // no leading and trailing whitespaces @@ -98,6 +111,19 @@ public void parse_invalidNames_throwsParseException() { assertParseFailure(parser, " n/Bob n/Ali@ce", String.format(Name.MESSAGE_CONSTRAINTS)); } + @Test + public void parse_invalidPhones_throwsParseException() { + // empty phones + assertParseFailure(parser, " p/", String.format(Phone.MESSAGE_CONSTRAINTS)); + assertParseFailure(parser, " p/ p/ p/", String.format(Phone.MESSAGE_CONSTRAINTS)); + + // invalid phones format + assertParseFailure(parser, " p/12", String.format(Phone.MESSAGE_CONSTRAINTS)); + assertParseFailure(parser, " p/123a45", String.format(Phone.MESSAGE_CONSTRAINTS)); + assertParseFailure(parser, " p/1234a56 p/91234567", String.format(Phone.MESSAGE_CONSTRAINTS)); + assertParseFailure(parser, " p/91234567 p/12", String.format(Phone.MESSAGE_CONSTRAINTS)); + } + @Test public void parse_invalidTags_throwsParseException() { // empty tag @@ -112,11 +138,11 @@ public void parse_invalidTags_throwsParseException() { @Test public void parse_invalidRoles_throwsParseException() { - // empty tag + // empty role assertParseFailure(parser, " role/", String.format(Person.MESSAGE_ROLE_CONSTRAINTS)); assertParseFailure(parser, " role/ role/ role/", String.format(Person.MESSAGE_ROLE_CONSTRAINTS)); - // invalid tag format + // invalid role format assertParseFailure(parser, " role/clie", String.format(Person.MESSAGE_ROLE_CONSTRAINTS)); assertParseFailure(parser, " role/clie role/employees", diff --git a/src/test/java/seedu/address/logic/parser/FindNumCommandParserTest.java b/src/test/java/seedu/address/logic/parser/FindNumCommandParserTest.java deleted file mode 100644 index 0e34c187920..00000000000 --- a/src/test/java/seedu/address/logic/parser/FindNumCommandParserTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package seedu.address.logic.parser; - -import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; - -import java.util.Arrays; - -import org.junit.jupiter.api.Test; - -import seedu.address.logic.commands.FindNumCommand; -import seedu.address.model.person.filter.PhoneContainsDigitsPredicate; - -public class FindNumCommandParserTest { - - private final FindNumCommandParser parser = new FindNumCommandParser(); - - @Test - public void parse_emptyArg_throwsParseException() { - assertParseFailure(parser, " ", - String.format(MESSAGE_INVALID_COMMAND_FORMAT, - FindNumCommand.MESSAGE_USAGE)); - } - - @Test - public void parse_invalidNum_throwsParseException() { - assertParseFailure(parser, "91b892e24", - String.format(MESSAGE_INVALID_COMMAND_FORMAT, - FindNumCommand.MESSAGE_USAGE)); - } - - @Test - public void parse_validArgs_returnsFindNumCommand() { - // no leading and trailing whitespaces - FindNumCommand expectedFindNumCommand = - new FindNumCommand(new PhoneContainsDigitsPredicate(Arrays.asList("87438807", "99272758"))); - assertParseSuccess(parser, "87438807 99272758", expectedFindNumCommand); - - // multiple whitespaces between keywords - assertParseSuccess(parser, " \n 87438807 \n \t 99272758 \t", expectedFindNumCommand); - } - -} diff --git a/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java b/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java index 0ca092a0cd2..da203928855 100644 --- a/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java +++ b/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java @@ -24,7 +24,6 @@ import seedu.address.logic.commands.ExitCommand; import seedu.address.logic.commands.ExportCommand; import seedu.address.logic.commands.FindCommand; -import seedu.address.logic.commands.FindNumCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.RemarkCommand; @@ -32,7 +31,6 @@ import seedu.address.model.person.Person; import seedu.address.model.person.Remark; import seedu.address.model.person.filter.NameContainsKeywordsPredicate; -import seedu.address.model.person.filter.PhoneContainsDigitsPredicate; import seedu.address.testutil.ClientBuilder; import seedu.address.testutil.EditPersonDescriptorBuilder; import seedu.address.testutil.PersonUtil; @@ -84,14 +82,6 @@ public void parseCommand_find() throws Exception { assertEquals(new FindCommand(new NameContainsKeywordsPredicate(keywords)), command); } - @Test - public void parseCommand_findNum() throws Exception { - List phones = Arrays.asList("87438807", "99272758", "87652533"); - FindNumCommand command = (FindNumCommand) parser.parseCommand( - FindNumCommand.COMMAND_WORD + " " + phones.stream().collect(Collectors.joining(" "))); - assertEquals(new FindNumCommand(new PhoneContainsDigitsPredicate(phones)), command); - } - @Test public void parseCommand_help() throws Exception { assertTrue(parser.parseCommand(HelpCommand.COMMAND_WORD) instanceof HelpCommand); diff --git a/src/test/java/seedu/address/model/person/filter/PhoneContainsDigitsPredicateTest.java b/src/test/java/seedu/address/model/person/filter/PhoneMatchesDigitsPredicateTest.java similarity index 63% rename from src/test/java/seedu/address/model/person/filter/PhoneContainsDigitsPredicateTest.java rename to src/test/java/seedu/address/model/person/filter/PhoneMatchesDigitsPredicateTest.java index d181636c787..52d097a425f 100644 --- a/src/test/java/seedu/address/model/person/filter/PhoneContainsDigitsPredicateTest.java +++ b/src/test/java/seedu/address/model/person/filter/PhoneMatchesDigitsPredicateTest.java @@ -13,15 +13,15 @@ import seedu.address.testutil.ClientBuilder; -public class PhoneContainsDigitsPredicateTest { +public class PhoneMatchesDigitsPredicateTest { @Test public void formatFilter() { List firstPredicateKeywordList = Collections.singletonList("first"); List secondPredicateKeywordList = Arrays.asList("first", "second"); - PhoneContainsDigitsPredicate firstPredicate = new PhoneContainsDigitsPredicate(firstPredicateKeywordList); - PhoneContainsDigitsPredicate secondPredicate = new PhoneContainsDigitsPredicate(secondPredicateKeywordList); + PhoneMatchesDigitsPredicate firstPredicate = new PhoneMatchesDigitsPredicate(firstPredicateKeywordList); + PhoneMatchesDigitsPredicate secondPredicate = new PhoneMatchesDigitsPredicate(secondPredicateKeywordList); assertEquals("p/first", firstPredicate.formatFilter()); assertEquals("p/first p/second", secondPredicate.formatFilter()); @@ -32,14 +32,14 @@ public void equals() { List firstPredicateKeywordList = Collections.singletonList("94351253"); List secondPredicateKeywordList = Arrays.asList("94351253", "98765432"); - PhoneContainsDigitsPredicate firstPredicate = new PhoneContainsDigitsPredicate(firstPredicateKeywordList); - PhoneContainsDigitsPredicate secondPredicate = new PhoneContainsDigitsPredicate(secondPredicateKeywordList); + PhoneMatchesDigitsPredicate firstPredicate = new PhoneMatchesDigitsPredicate(firstPredicateKeywordList); + PhoneMatchesDigitsPredicate secondPredicate = new PhoneMatchesDigitsPredicate(secondPredicateKeywordList); // same object -> returns true assertEquals(firstPredicate, firstPredicate); // same values -> returns true - PhoneContainsDigitsPredicate firstPredicateCopy = new PhoneContainsDigitsPredicate(firstPredicateKeywordList); + PhoneMatchesDigitsPredicate firstPredicateCopy = new PhoneMatchesDigitsPredicate(firstPredicateKeywordList); assertEquals(firstPredicate, firstPredicateCopy); // different types -> returns false @@ -56,25 +56,25 @@ public void equals() { } @Test - public void test_numberContainsDigits_returnsTrue() { + public void test_numberMatchesDigits_returnsTrue() { // One keyword - PhoneContainsDigitsPredicate predicate = - new PhoneContainsDigitsPredicate(Collections.singletonList("94351253")); + PhoneMatchesDigitsPredicate predicate = + new PhoneMatchesDigitsPredicate(Collections.singletonList("94351253")); assertTrue(predicate.test(new ClientBuilder().withPhone("94351253").build())); } @Test - public void test_phoneDoesNotContainDigits_returnsFalse() { + public void test_phoneDoesNotMatchDigits_returnsFalse() { // Zero keywords - PhoneContainsDigitsPredicate predicate = new PhoneContainsDigitsPredicate(Collections.emptyList()); + PhoneMatchesDigitsPredicate predicate = new PhoneMatchesDigitsPredicate(Collections.emptyList()); assertFalse(predicate.test(new ClientBuilder().withPhone("94351253").build())); // Non-matching keyword - predicate = new PhoneContainsDigitsPredicate(List.of("95352563")); + predicate = new PhoneMatchesDigitsPredicate(List.of("95352563")); assertFalse(predicate.test(new ClientBuilder().withPhone("98765432").build())); // Keywords match name, email and address, but does not match phone - predicate = new PhoneContainsDigitsPredicate(Arrays.asList("Alice", "alice@email.com", "Main", "Street")); + predicate = new PhoneMatchesDigitsPredicate(Arrays.asList("Alice", "alice@email.com", "Main", "Street")); assertFalse(predicate.test(new ClientBuilder().withName("Alice").withPhone("12345") .withEmail("alice@email.com").withAddress("Main Street").build())); } @@ -82,9 +82,9 @@ public void test_phoneDoesNotContainDigits_returnsFalse() { @Test public void toStringMethod() { List phones = List.of("94351253", "98765432"); - PhoneContainsDigitsPredicate predicate = new PhoneContainsDigitsPredicate(phones); + PhoneMatchesDigitsPredicate predicate = new PhoneMatchesDigitsPredicate(phones); - String expected = PhoneContainsDigitsPredicate.class.getCanonicalName() + "{phones=" + phones + "}"; + String expected = PhoneMatchesDigitsPredicate.class.getCanonicalName() + "{phones=" + phones + "}"; assertEquals(expected, predicate.toString()); } } From c1e12998643ccec9c74c294714d94343a995c3cb Mon Sep 17 00:00:00 2001 From: nuyer <98694104+nuyer@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:37:02 +0800 Subject: [PATCH 24/29] Update NetConnect.java --- src/main/java/seedu/address/model/NetConnect.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/main/java/seedu/address/model/NetConnect.java b/src/main/java/seedu/address/model/NetConnect.java index 800f967c345..918196e4772 100644 --- a/src/main/java/seedu/address/model/NetConnect.java +++ b/src/main/java/seedu/address/model/NetConnect.java @@ -141,21 +141,6 @@ public void removePerson(Person key) { persons.remove(key); } - /** - * Exports the data from the address book as a CSV file with the specified - * filename. - * Returns {@code true} if the export operation is successful, {@code false} - * otherwise. - * - * @return {@code true} if the export operation is successful, {@code false} - * otherwise. - */ - public boolean exportCsv(String filename) { - CsvExporter exporter = new CsvExporter(persons, filename); - exporter.execute(); - return exporter.getIsSuccessful(); - } - //// related list operations /** * Returns true if the specified IdTuple is present in the relatedList, false otherwise. From 77b49bdeba1b9ff5da4cfa04e5248decfc74f4e9 Mon Sep 17 00:00:00 2001 From: Shaun Lee Date: Thu, 4 Apr 2024 18:32:50 +0800 Subject: [PATCH 25/29] UniquePersonListTest: Change variable name to be accurate --- .../java/seedu/address/model/person/UniquePersonListTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/seedu/address/model/person/UniquePersonListTest.java b/src/test/java/seedu/address/model/person/UniquePersonListTest.java index 27ae245154f..96fd4d0ed7b 100644 --- a/src/test/java/seedu/address/model/person/UniquePersonListTest.java +++ b/src/test/java/seedu/address/model/person/UniquePersonListTest.java @@ -264,8 +264,8 @@ public void setPerson_editedPersonHasNonUniqueIdentity_throwsDuplicatePersonExce @Test public void setPerson_editedPersonHasModifiedId_throwsIdModifiedException() { uniquePersonList.add(ALICE); - Person editedAlice = new ClientBuilder(ALICE).withId(BOB.getId().value).build(); - assertThrows(IdModifiedException.class, () -> uniquePersonList.setPerson(ALICE, editedAlice)); + Person aliceWithDifferentId = new ClientBuilder(ALICE).withId(BOB.getId().value).build(); + assertThrows(IdModifiedException.class, () -> uniquePersonList.setPerson(ALICE, aliceWithDifferentId)); } @Test From c98a4bbd6f94b99060df2e034818827f793f74f6 Mon Sep 17 00:00:00 2001 From: Shaun Lee Date: Thu, 4 Apr 2024 18:48:38 +0800 Subject: [PATCH 26/29] Remove remark command Reason: Edit command allows user to edit the remarks of person. No reason for there to be 2 commands carrying out the same function. --- .../address/logic/commands/RemarkCommand.java | 106 ----------- .../logic/parser/NetConnectParser.java | 4 - .../logic/parser/RemarkCommandParser.java | 37 ---- .../logic/commands/RemarkCommandTest.java | 171 ------------------ .../logic/parser/NetConnectParserTest.java | 11 -- .../logic/parser/RemarkCommandParserTest.java | 51 ------ 6 files changed, 380 deletions(-) delete mode 100644 src/main/java/seedu/address/logic/commands/RemarkCommand.java delete mode 100644 src/main/java/seedu/address/logic/parser/RemarkCommandParser.java delete mode 100644 src/test/java/seedu/address/logic/commands/RemarkCommandTest.java delete mode 100644 src/test/java/seedu/address/logic/parser/RemarkCommandParserTest.java diff --git a/src/main/java/seedu/address/logic/commands/RemarkCommand.java b/src/main/java/seedu/address/logic/commands/RemarkCommand.java deleted file mode 100644 index 02db21de73f..00000000000 --- a/src/main/java/seedu/address/logic/commands/RemarkCommand.java +++ /dev/null @@ -1,106 +0,0 @@ -package seedu.address.logic.commands; - -import static java.util.Objects.requireNonNull; -import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ID; -import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK; - -import seedu.address.logic.Messages; -import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.model.Model; -import seedu.address.model.person.Client; -import seedu.address.model.person.Employee; -import seedu.address.model.person.Id; -import seedu.address.model.person.Person; -import seedu.address.model.person.Remark; -import seedu.address.model.person.Supplier; - -/** - * Changes the remark of an existing person in the address book. - */ -public class RemarkCommand extends Command { - - public static final String COMMAND_WORD = "remark"; - - public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Edits the remark of the person with the specified id. " - + "Existing remark will be overwritten by the input.\n" - + "Parameters: " - + PREFIX_ID + "ID " - + PREFIX_REMARK + "[REMARK]\n" - + "Example: " + COMMAND_WORD + " " - + PREFIX_ID + "1 " - + PREFIX_REMARK + "Likes to swim."; - - public static final String MESSAGE_ADD_REMARK_SUCCESS = "Added remark to Person: %1$s"; - public static final String MESSAGE_DELETE_REMARK_SUCCESS = "Removed remark from Person: %1$s"; - - private final Id id; - private final Remark remark; - - /** - * @param id of the person in the filtered person list to edit the remark - * @param remark of the person to be updated to - */ - public RemarkCommand(Id id, Remark remark) { - requireAllNonNull(id, remark); - - this.id = id; - this.remark = remark; - } - - @Override - public CommandResult execute(Model model) throws CommandException { - requireNonNull(model); - - if (!model.hasId(id)) { - model.clearFilter(); - throw new CommandException(String.format(Messages.MESSAGE_INVALID_PERSON_ID, id.value)); - } - - Person personToEdit = model.getPersonById(id); - Person editedPerson; - if (personToEdit instanceof Client) { - editedPerson = new Client(personToEdit.getId(), personToEdit.getName(), personToEdit.getPhone(), - personToEdit.getEmail(), personToEdit.getAddress(), remark, personToEdit.getTags(), ( - (Client) personToEdit).getProducts(), ((Client) personToEdit).getPreferences()); - } else if (personToEdit instanceof Supplier) { - editedPerson = new Supplier(personToEdit.getId(), personToEdit.getName(), personToEdit.getPhone(), - personToEdit.getEmail(), personToEdit.getAddress(), remark, personToEdit.getTags(), ( - (Supplier) personToEdit).getProducts(), ((Supplier) personToEdit).getTermsOfService()); - } else if (personToEdit instanceof Employee) { - editedPerson = new Employee(personToEdit.getId(), personToEdit.getName(), personToEdit.getPhone(), - personToEdit.getEmail(), personToEdit.getAddress(), remark, personToEdit.getTags(), ( - (Employee) personToEdit).getDepartment(), ((Employee) personToEdit).getJobTitle(), ( - (Employee) personToEdit).getSkills()); - } else { - throw new CommandException(String.format(Messages.MESSAGE_INVALID_PERSON_ID, id.value)); - } - - model.setPerson(personToEdit, editedPerson); - model.clearFilter(); - - return new CommandResult(generateSuccessMessage(editedPerson)); - } - - private String generateSuccessMessage(Person personToEdit) { - String message = !remark.value.isEmpty() ? MESSAGE_ADD_REMARK_SUCCESS : MESSAGE_DELETE_REMARK_SUCCESS; - return String.format(message, Messages.format(personToEdit)); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof RemarkCommand)) { - return false; - } - - RemarkCommand e = (RemarkCommand) other; - return id.equals(e.id) - && remark.equals(e.remark); - } -} diff --git a/src/main/java/seedu/address/logic/parser/NetConnectParser.java b/src/main/java/seedu/address/logic/parser/NetConnectParser.java index ef63cad4ec6..38460721004 100644 --- a/src/main/java/seedu/address/logic/parser/NetConnectParser.java +++ b/src/main/java/seedu/address/logic/parser/NetConnectParser.java @@ -20,7 +20,6 @@ import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.RelateCommand; -import seedu.address.logic.commands.RemarkCommand; import seedu.address.logic.commands.ShowRelatedCommand; import seedu.address.logic.commands.UnrelateCommand; import seedu.address.logic.parser.exceptions.ParseException; @@ -87,9 +86,6 @@ public Command parseCommand(String userInput) throws ParseException { case ShowRelatedCommand.COMMAND_WORD: return new ShowRelatedCommandParser().parse(arguments); - case RemarkCommand.COMMAND_WORD: - return new RemarkCommandParser().parse(arguments); - case ListCommand.COMMAND_WORD: return new ListCommand(); diff --git a/src/main/java/seedu/address/logic/parser/RemarkCommandParser.java b/src/main/java/seedu/address/logic/parser/RemarkCommandParser.java deleted file mode 100644 index 0fc402d21c0..00000000000 --- a/src/main/java/seedu/address/logic/parser/RemarkCommandParser.java +++ /dev/null @@ -1,37 +0,0 @@ -package seedu.address.logic.parser; - -import static java.util.Objects.requireNonNull; -import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ID; -import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK; - -import seedu.address.logic.commands.RemarkCommand; -import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.person.Id; -import seedu.address.model.person.Remark; - -/** - * Parses input arguments and creates a new {@code RemarkCommand} object - */ -public class RemarkCommandParser implements Parser { - - /** - * Parses the given {@code String} of arguments in the context of the {@code RemarkCommand} - * and returns a {@code RemarkCommand} object for execution. - * @throws ParseException if the user input does not conform the expected format - */ - public RemarkCommand parse(String args) throws ParseException { - requireNonNull(args); - ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_ID, PREFIX_REMARK); - argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_ID, PREFIX_REMARK); - - if (argMultimap.getValue(PREFIX_ID).isEmpty()) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, RemarkCommand.MESSAGE_USAGE)); - } - Id id = ParserUtil.parseId(argMultimap.getValue(PREFIX_ID).get()); - - Remark remark = new Remark(argMultimap.getValue(PREFIX_REMARK).orElse("")); - - return new RemarkCommand(id, remark); - } -} diff --git a/src/test/java/seedu/address/logic/commands/RemarkCommandTest.java b/src/test/java/seedu/address/logic/commands/RemarkCommandTest.java deleted file mode 100644 index ce2784f0c00..00000000000 --- a/src/test/java/seedu/address/logic/commands/RemarkCommandTest.java +++ /dev/null @@ -1,171 +0,0 @@ -package seedu.address.logic.commands; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static seedu.address.logic.commands.CommandTestUtil.VALID_REMARK_AMY; -import static seedu.address.logic.commands.CommandTestUtil.VALID_REMARK_BOB; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure; -import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; -import static seedu.address.logic.commands.CommandTestUtil.showAllPersons; -import static seedu.address.logic.commands.CommandTestUtil.showPersonAtId; -import static seedu.address.testutil.TypicalIds.ID_FIRST_PERSON; -import static seedu.address.testutil.TypicalIds.ID_SECOND_PERSON; -import static seedu.address.testutil.TypicalPersons.getTypicalNetConnect; - -import org.junit.jupiter.api.Test; - -import seedu.address.logic.Messages; -import seedu.address.model.Model; -import seedu.address.model.ModelManager; -import seedu.address.model.NetConnect; -import seedu.address.model.UserPrefs; -import seedu.address.model.person.Client; -import seedu.address.model.person.Id; -import seedu.address.model.person.Person; -import seedu.address.model.person.Remark; -import seedu.address.testutil.ClientBuilder; - -/** - * Contains integration tests (interaction with the Model) and unit tests for - * RemarkCommand. - */ -public class RemarkCommandTest { - private final Model model = new ModelManager(getTypicalNetConnect(), new UserPrefs()); - - @Test - public void execute_addRemarkUnfilteredList_success() { - Person firstPerson = model.getPersonById(ID_FIRST_PERSON); - Person editedPerson = new ClientBuilder((Client) firstPerson).withRemark(VALID_REMARK_AMY).build(); - - RemarkCommand remarkCommand = new RemarkCommand(ID_FIRST_PERSON, editedPerson.getRemark()); - - String expectedMessage = String.format(RemarkCommand.MESSAGE_ADD_REMARK_SUCCESS, Messages.format(editedPerson)); - - Model expectedModel = new ModelManager(new NetConnect(model.getNetConnect()), - new UserPrefs()); - expectedModel.setPerson(firstPerson, editedPerson); - - assertCommandSuccess(remarkCommand, model, expectedMessage, expectedModel); - } - - @Test - public void execute_deleteRemarkUnfilteredList_success() { - Person firstPerson = model.getPersonById(ID_FIRST_PERSON); - Person editedPerson = new ClientBuilder((Client) firstPerson).withRemark("").build(); - - RemarkCommand remarkCommand = new RemarkCommand(ID_FIRST_PERSON, editedPerson.getRemark()); - - String expectedMessage = String.format( - RemarkCommand.MESSAGE_DELETE_REMARK_SUCCESS, Messages.format(editedPerson)); - - Model expectedModel = new ModelManager(new NetConnect(model.getNetConnect()), - new UserPrefs()); - expectedModel.setPerson(firstPerson, editedPerson); - - assertCommandSuccess(remarkCommand, model, expectedMessage, expectedModel); - } - - @Test - public void execute_filteredListIdPresent_success() { - showPersonAtId(model, ID_FIRST_PERSON); - - Person firstPerson = model.getPersonById(ID_FIRST_PERSON); - Person editedPerson = new ClientBuilder((Client) firstPerson).withRemark(VALID_REMARK_AMY).build(); - - RemarkCommand remarkCommand = new RemarkCommand(ID_FIRST_PERSON, editedPerson.getRemark()); - - String expectedMessage = String.format(RemarkCommand.MESSAGE_ADD_REMARK_SUCCESS, Messages.format(editedPerson)); - - Model expectedModel = new ModelManager(new NetConnect(model.getNetConnect()), - new UserPrefs()); - expectedModel.setPerson(firstPerson, editedPerson); - - assertCommandSuccess(remarkCommand, model, expectedMessage, expectedModel); - } - - @Test - public void execute_filteredListIdAbsent_success() { - showPersonAtId(model, ID_SECOND_PERSON); - - Person firstPerson = model.getPersonById(ID_FIRST_PERSON); - Person editedPerson = new ClientBuilder((Client) firstPerson).withRemark(VALID_REMARK_AMY).build(); - - RemarkCommand remarkCommand = new RemarkCommand(ID_FIRST_PERSON, editedPerson.getRemark()); - - String expectedMessage = String.format(RemarkCommand.MESSAGE_ADD_REMARK_SUCCESS, Messages.format(editedPerson)); - - Model expectedModel = new ModelManager(new NetConnect(model.getNetConnect()), - new UserPrefs()); - expectedModel.setPerson(firstPerson, editedPerson); - showAllPersons(expectedModel); - - assertCommandSuccess(remarkCommand, model, expectedMessage, expectedModel); - } - - @Test - public void execute_invalidIdUnfilteredList_failure() { - Id outOfBoundId = Id.generateNextId(); - RemarkCommand remarkCommand = new RemarkCommand(outOfBoundId, new Remark(VALID_REMARK_AMY)); - - assertCommandFailure(remarkCommand, model, - String.format(Messages.MESSAGE_INVALID_PERSON_ID, outOfBoundId.value)); - } - - @Test - public void execute_invalidIdFilteredList_failure() { - showPersonAtId(model, ID_FIRST_PERSON); - - Id outOfBoundId = Id.generateNextId(); - RemarkCommand remarkCommand = new RemarkCommand(outOfBoundId, new Remark(VALID_REMARK_AMY)); - - Model expectedModel = new ModelManager(new NetConnect(model.getNetConnect()), - new UserPrefs()); - showAllPersons(expectedModel); - - assertCommandFailure(remarkCommand, model, - String.format(Messages.MESSAGE_INVALID_PERSON_ID, outOfBoundId.value), expectedModel); - } - - @Test - public void equals() { - final RemarkCommand remarkCommand = new RemarkCommand(ID_FIRST_PERSON, new Remark(VALID_REMARK_AMY)); - - // same object -> returns true - assertTrue(remarkCommand.equals(remarkCommand)); - - // same values -> returns true - assertTrue(remarkCommand.equals(new RemarkCommand(ID_FIRST_PERSON, new Remark(VALID_REMARK_AMY)))); - - // null -> returns false - assertFalse(remarkCommand.equals(null)); - - // different types -> returns false - assertFalse(remarkCommand.equals(new ClearCommand())); - - // different index, same remark -> returns false - assertFalse(remarkCommand.equals(new RemarkCommand(ID_SECOND_PERSON, new Remark(VALID_REMARK_AMY)))); - - // different remark, same index -> returns false - assertFalse(remarkCommand.equals(new RemarkCommand(ID_FIRST_PERSON, new Remark(VALID_REMARK_BOB)))); - - // different remark and index -> returns false - assertFalse(remarkCommand.equals(new RemarkCommand(ID_SECOND_PERSON, new Remark(VALID_REMARK_BOB)))); - } - - @Test - public void execute_editClientRemarkUnfilteredList_success() { - Person firstPerson = model.getPersonById(ID_FIRST_PERSON); - Person editedPerson = new ClientBuilder((Client) firstPerson).withRemark(VALID_REMARK_AMY).build(); - - RemarkCommand remarkCommand = new RemarkCommand(ID_FIRST_PERSON, editedPerson.getRemark()); - - String expectedMessage = String.format(RemarkCommand.MESSAGE_ADD_REMARK_SUCCESS, Messages.format(editedPerson)); - - Model expectedModel = new ModelManager(new NetConnect(model.getNetConnect()), - new UserPrefs()); - expectedModel.setPerson(firstPerson, editedPerson); - - assertCommandSuccess(remarkCommand, model, expectedMessage, expectedModel); - } - -} diff --git a/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java b/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java index 97f2fc78321..85f45bb3a1a 100644 --- a/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java +++ b/src/test/java/seedu/address/logic/parser/NetConnectParserTest.java @@ -5,7 +5,6 @@ import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import static seedu.address.logic.Messages.MESSAGE_UNKNOWN_COMMAND; import static seedu.address.logic.parser.CliSyntax.PREFIX_ID; -import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK; import static seedu.address.testutil.Assert.assertThrows; import static seedu.address.testutil.TypicalIds.ID_FIRST_PERSON; import static seedu.address.testutil.TypicalPersons.ALICE; @@ -28,12 +27,10 @@ import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; import seedu.address.logic.commands.RelateCommand; -import seedu.address.logic.commands.RemarkCommand; import seedu.address.logic.commands.ShowRelatedCommand; import seedu.address.logic.commands.UnrelateCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.person.Person; -import seedu.address.model.person.Remark; import seedu.address.model.person.filter.NameContainsKeywordsPredicate; import seedu.address.model.person.filter.PhoneContainsDigitsPredicate; import seedu.address.testutil.ClientBuilder; @@ -107,14 +104,6 @@ public void parseCommand_list() throws Exception { assertTrue(parser.parseCommand(ListCommand.COMMAND_WORD + " 3") instanceof ListCommand); } - @Test - public void parseCommand_remark() throws Exception { - final Remark remark = new Remark("Some remark."); - RemarkCommand command = (RemarkCommand) parser.parseCommand(RemarkCommand.COMMAND_WORD + " " - + PREFIX_ID + "1 " + PREFIX_REMARK + remark.value); - assertEquals(new RemarkCommand(ID_FIRST_PERSON, remark), command); - } - @Test public void parseCommand_showRelated() throws Exception { assertTrue( diff --git a/src/test/java/seedu/address/logic/parser/RemarkCommandParserTest.java b/src/test/java/seedu/address/logic/parser/RemarkCommandParserTest.java deleted file mode 100644 index afb4bbb9511..00000000000 --- a/src/test/java/seedu/address/logic/parser/RemarkCommandParserTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package seedu.address.logic.parser; - -import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.address.logic.parser.CliSyntax.PREFIX_ID; -import static seedu.address.logic.parser.CliSyntax.PREFIX_REMARK; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; -import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; -import static seedu.address.testutil.TypicalIds.ID_FIRST_PERSON; - -import org.junit.jupiter.api.Test; - -import seedu.address.logic.Messages; -import seedu.address.logic.commands.RemarkCommand; -import seedu.address.model.person.Remark; - -public class RemarkCommandParserTest { - private final RemarkCommandParser parser = new RemarkCommandParser(); - - @Test - public void parse_validIndex_returnsDeleteCommand() { - assertParseSuccess(parser, " i/1 r/remark", - new RemarkCommand(ID_FIRST_PERSON, new Remark("remark"))); - } - - @Test - public void parse_repeatedFields_throwsParserException() { - // repeated id - assertParseFailure(parser, " i/1 i/2 r/remark", - String.format(Messages.getErrorMessageForDuplicatePrefixes(PREFIX_ID))); - - // repeated remark - assertParseFailure(parser, " i/1 r/remark r/remark", - String.format(Messages.getErrorMessageForDuplicatePrefixes(PREFIX_REMARK))); - - // repeated id and remark - assertParseFailure(parser, " i/1 i/2 r/remark r/another remark", - String.format(Messages.getErrorMessageForDuplicatePrefixes(PREFIX_ID, PREFIX_REMARK))); - } - - @Test - public void parse_invalidArgs_throwsParseException() { - assertParseFailure(parser, "a", - String.format(MESSAGE_INVALID_COMMAND_FORMAT, RemarkCommand.MESSAGE_USAGE)); - } - - @Test - public void parse_noArgs_throwsParseException() { - assertParseFailure(parser, "", - String.format(MESSAGE_INVALID_COMMAND_FORMAT, RemarkCommand.MESSAGE_USAGE)); - } -} From 03cb2db4d8e4b4697b4a3496756287d2716dfb20 Mon Sep 17 00:00:00 2001 From: Puri Virakarin Date: Thu, 4 Apr 2024 20:51:00 +0800 Subject: [PATCH 27/29] Update validation and JUnit Testing --- .../address/logic/commands/DeleteCommand.java | 10 +++------- .../seedu/address/logic/LogicManagerTest.java | 19 +++++++++++++++++-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/address/logic/commands/DeleteCommand.java index fe21d7e015a..bb2756d10ab 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteCommand.java @@ -2,8 +2,8 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.parser.CliSyntax.PREFIX_ID; -import static seedu.address.ui.MainWindow.handleDestructiveCommands; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.ui.MainWindow.handleDestructiveCommands; import java.util.Objects; @@ -54,6 +54,7 @@ private DeleteCommand(Id targetId, Name name) { /** * Factory method to create a {@code DeleteCommand} that deletes a Person * by the given id. + * * @param id The id of the {@code Person} to be deleted * @return {@code DeleteCommand} to delete by id */ @@ -65,6 +66,7 @@ public static DeleteCommand byId(Id id) { /** * Factory method to create a {@code DeleteCommand} that deletes a Person * by the given name. + * * @param name The name of the {@code Person} to be deleted * @return {@code DeleteCommand} to delete by name */ @@ -78,13 +80,7 @@ public CommandResult execute(Model model) throws CommandException { requireNonNull(model); assert targetId != null ^ targetName != null; - // check if the ID is valid - if (!model.hasId(targetId)) { - throw new CommandException(String.format(Messages.MESSAGE_INVALID_PERSON_ID, targetId.value)); - } - if (doNotSkipConfirmation) { - // obtain confirmation from boolean isConfirmed = handleDestructiveCommands(true, false); if (!isConfirmed) { return new CommandResult(MESSAGE_DELETE_CANCELLED, false, false); diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java index 6dff6e6cfbf..46a26fa5398 100644 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ b/src/test/java/seedu/address/logic/LogicManagerTest.java @@ -3,12 +3,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static seedu.address.logic.Messages.MESSAGE_INVALID_PERSON_ID; import static seedu.address.logic.Messages.MESSAGE_UNKNOWN_COMMAND; +import static seedu.address.logic.commands.DeleteCommand.cleanUpAfterTesting; +import static seedu.address.logic.commands.DeleteCommand.setUpForTesting; import static seedu.address.testutil.Assert.assertThrows; import java.io.IOException; import java.nio.file.AccessDeniedException; import java.nio.file.Path; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -35,6 +39,17 @@ public class LogicManagerTest { private final Model model = new ModelManager(); private Logic logic; + @BeforeAll + public static void setUpDelete() { + setUpForTesting(); + } + + @AfterAll + public static void close() { + cleanUpAfterTesting(); + } + + @BeforeEach public void setUp() { JsonNetConnectStorage netConnectStorage = new JsonNetConnectStorage( @@ -89,7 +104,7 @@ public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException * @see #assertCommandFailure(String, Class, String, Model) */ private void assertCommandSuccess(String inputCommand, String expectedMessage, - Model expectedModel) throws CommandException, ParseException { + Model expectedModel) throws CommandException, ParseException { CommandResult result = logic.execute(inputCommand); assertEquals(expectedMessage, result.getFeedbackToUser()); assertEquals(expectedModel, model); @@ -137,7 +152,7 @@ private void assertCommandFailure( * @see #assertCommandSuccess(String, String, Model) */ private void assertCommandFailure(String inputCommand, Class expectedException, - String expectedMessage, Model expectedModel) { + String expectedMessage, Model expectedModel) { assertThrows(expectedException, expectedMessage, () -> logic.execute(inputCommand)); assertEquals(expectedModel, model); } From 29fdd3657886ed9f3bd70ec58f1d02984163a625 Mon Sep 17 00:00:00 2001 From: Puri Virakarin <110763159+purivirakarin@users.noreply.github.com> Date: Thu, 4 Apr 2024 19:55:29 +0700 Subject: [PATCH 28/29] Update ClearCommand.java --- src/main/java/seedu/address/logic/commands/ClearCommand.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/address/logic/commands/ClearCommand.java index b40c6e54681..98e187caf4a 100644 --- a/src/main/java/seedu/address/logic/commands/ClearCommand.java +++ b/src/main/java/seedu/address/logic/commands/ClearCommand.java @@ -14,15 +14,11 @@ public class ClearCommand extends Command { public static final String COMMAND_WORD = "clear"; public static final String CLEAR_SUCCESS_MESSAGE = "Address book has been cleared!"; public static final String CLEAR_CANCELLED_MESSAGE = "Clear command cancelled"; - private static Model model; private static boolean doNotSkipConfirmation = true; - - @Override public CommandResult execute(Model model) { requireNonNull(model); - this.model = model; if (doNotSkipConfirmation) { boolean isConfirmed = handleDestructiveCommands(false, true); From 6a815842ad996580c5cb0f48e7d10225db65e492 Mon Sep 17 00:00:00 2001 From: Puri Virakarin <110763159+purivirakarin@users.noreply.github.com> Date: Thu, 4 Apr 2024 19:56:57 +0700 Subject: [PATCH 29/29] Update LogicManagerTest.java --- src/test/java/seedu/address/logic/LogicManagerTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java index 46a26fa5398..347849ca38a 100644 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ b/src/test/java/seedu/address/logic/LogicManagerTest.java @@ -49,7 +49,6 @@ public static void close() { cleanUpAfterTesting(); } - @BeforeEach public void setUp() { JsonNetConnectStorage netConnectStorage = new JsonNetConnectStorage(