From 6be91a9320024dad79b452766f2818add6408f68 Mon Sep 17 00:00:00 2001 From: pra-navi Date: Tue, 31 Oct 2023 19:54:19 +0800 Subject: [PATCH 1/3] feat: Implement addTagTask and addTagPerson commands --- .../logic/commands/AddTagPersonCommand.java | 114 ++++++++++++++ .../logic/commands/AddTagTaskCommand.java | 112 +++++++++++++ .../parser/AddTagPersonCommandParser.java | 47 ++++++ .../logic/parser/AddTagTaskCommandParser.java | 47 ++++++ .../logic/parser/AddressBookParser.java | 12 ++ .../commands/AddTagPersonCommandTest.java | 149 ++++++++++++++++++ .../logic/commands/AddTagTaskCommandTest.java | 149 ++++++++++++++++++ .../parser/AddTagPersonCommandParserTest.java | 97 ++++++++++++ .../logic/parser/AddressBookParserTest.java | 51 ++++++ .../seedu/address/testutil/PersonBuilder.java | 8 + .../seedu/address/testutil/TaskBuilder.java | 8 + 11 files changed, 794 insertions(+) create mode 100644 src/main/java/seedu/address/logic/commands/AddTagPersonCommand.java create mode 100644 src/main/java/seedu/address/logic/commands/AddTagTaskCommand.java create mode 100644 src/main/java/seedu/address/logic/parser/AddTagPersonCommandParser.java create mode 100644 src/main/java/seedu/address/logic/parser/AddTagTaskCommandParser.java create mode 100644 src/test/java/seedu/address/logic/commands/AddTagPersonCommandTest.java create mode 100644 src/test/java/seedu/address/logic/commands/AddTagTaskCommandTest.java create mode 100644 src/test/java/seedu/address/logic/parser/AddTagPersonCommandParserTest.java diff --git a/src/main/java/seedu/address/logic/commands/AddTagPersonCommand.java b/src/main/java/seedu/address/logic/commands/AddTagPersonCommand.java new file mode 100644 index 00000000000..6a2342379d3 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/AddTagPersonCommand.java @@ -0,0 +1,114 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.person.Address; +import seedu.address.model.person.Email; +import seedu.address.model.person.Name; +import seedu.address.model.person.Person; +import seedu.address.model.person.Phone; +import seedu.address.model.tag.Tag; + +/** + * Adds tags to an existing person in the address book. + */ +public class AddTagPersonCommand extends Command { + + public static final String COMMAND_WORD = "addTagPerson"; + public static final String SHORTENED_COMMAND_WORD = "atagp"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + " (alias: " + SHORTENED_COMMAND_WORD + ")" + + ": Adds new tag to the person identified " + + "by the index number used in the displayed contact list. \n" + + "Parameters: INDEX (must be a positive integer) " + + "[" + PREFIX_TAG + "TAG]...\n" + + "Example: " + COMMAND_WORD + " 1 " + + PREFIX_TAG + "catering"; + + public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Person: %1$s"; + public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book."; + + private final Set tagsToAdd; + private final Index index; + + /** + * @param index of the person in the filtered contact list to edit + * @param tagsToAdd tags to add to the person + */ + public AddTagPersonCommand(Index index, Set tagsToAdd) { + requireNonNull(index); + requireNonNull(tagsToAdd); + + this.index = index; + this.tagsToAdd = tagsToAdd; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + List lastShownPersonList = model.getFilteredPersonList(); + + if (index.getZeroBased() >= lastShownPersonList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } + + Person personToEdit = lastShownPersonList.get(index.getZeroBased()); + Person editedPerson = createEditedPerson(personToEdit, tagsToAdd); + + model.setPerson(personToEdit, editedPerson); + model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); + return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson))); + } + + /** + * Creates and returns a {@code Person} with the details of {@code personToEdit}. + */ + private static Person createEditedPerson(Person personToEdit, Set tagsToAdd) { + assert personToEdit != null; + + Name name = personToEdit.getName(); + Phone phone = personToEdit.getPhone(); + Email email = personToEdit.getEmail(); + Address address = personToEdit.getAddress(); + Set existingTags = personToEdit.getTags(); + Set updatedTags = new HashSet<>(existingTags); + updatedTags.addAll(tagsToAdd); + + return new Person(name, phone, email, address, updatedTags); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof AddTagPersonCommand)) { + return false; + } + + AddTagPersonCommand otherAddTagPersonCommand = (AddTagPersonCommand) other; + return index.equals(otherAddTagPersonCommand.index) + && tagsToAdd.equals(otherAddTagPersonCommand.tagsToAdd); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("index", index) + .add("tagsToAdd", tagsToAdd) + .toString(); + } +} diff --git a/src/main/java/seedu/address/logic/commands/AddTagTaskCommand.java b/src/main/java/seedu/address/logic/commands/AddTagTaskCommand.java new file mode 100644 index 00000000000..f335d5e483b --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/AddTagTaskCommand.java @@ -0,0 +1,112 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_TASKS; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import seedu.address.commons.core.index.Index; +import seedu.address.commons.util.ToStringBuilder; +import seedu.address.logic.Messages; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.tag.Tag; +import seedu.address.model.task.Note; +import seedu.address.model.task.Status; +import seedu.address.model.task.Task; +import seedu.address.model.task.Title; + +/** + * Adds tags to an existing task in the address book. + */ +public class AddTagTaskCommand extends Command { + + public static final String COMMAND_WORD = "addTagTask"; + public static final String SHORTENED_COMMAND_WORD = "atagt"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + " (alias: " + SHORTENED_COMMAND_WORD + ")" + + ": Adds new tag to the task identified " + + "by the index number used in the displayed task list. \n" + + "Parameters: INDEX (must be a positive integer) " + + "[" + PREFIX_TAG + "TAG]...\n" + + "Example: " + COMMAND_WORD + " 1 " + + PREFIX_TAG + "class"; + + public static final String MESSAGE_EDIT_TASK_SUCCESS = "Edited Task: %1$s"; + public static final String MESSAGE_DUPLICATE_TASK = "This task already exists in the address book."; + + private final Set tagsToAdd; + private final Index index; + + /** + * @param index of the task in the filtered task list to edit + * @param tagsToAdd tags to add to the task + */ + public AddTagTaskCommand(Index index, Set tagsToAdd) { + requireNonNull(index); + requireNonNull(tagsToAdd); + + this.index = index; + this.tagsToAdd = tagsToAdd; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + List lastShownTaskList = model.getFilteredTaskList(); + + if (index.getZeroBased() >= lastShownTaskList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } + + Task taskToEdit = lastShownTaskList.get(index.getZeroBased()); + Task editedTask = createEditedTask(taskToEdit, tagsToAdd); + + model.setTask(taskToEdit, editedTask); + model.updateFilteredTaskList(PREDICATE_SHOW_ALL_TASKS); + return new CommandResult(String.format(MESSAGE_EDIT_TASK_SUCCESS, Messages.format(editedTask))); + } + + /** + * Creates and returns a {@code Task} with the details of {@code taskToEdit}. + */ + private static Task createEditedTask(Task taskToEdit, Set tagsToAdd) { + assert taskToEdit != null; + + Title title = taskToEdit.getTitle(); + Note note = taskToEdit.getNote(); + Status taskStatus = taskToEdit.getStatus(); + Set existingTags = taskToEdit.getTags(); + Set updatedTags = new HashSet<>(existingTags); + updatedTags.addAll(tagsToAdd); + + return new Task(title, note, taskStatus, updatedTags); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof AddTagTaskCommand)) { + return false; + } + + AddTagTaskCommand otherAddTagTaskCommand = (AddTagTaskCommand) other; + return index.equals(otherAddTagTaskCommand.index) + && tagsToAdd.equals(otherAddTagTaskCommand.tagsToAdd); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .add("index", index) + .add("tagsToAdd", tagsToAdd) + .toString(); + } +} diff --git a/src/main/java/seedu/address/logic/parser/AddTagPersonCommandParser.java b/src/main/java/seedu/address/logic/parser/AddTagPersonCommandParser.java new file mode 100644 index 00000000000..632c7df0e19 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/AddTagPersonCommandParser.java @@ -0,0 +1,47 @@ +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_TAG; + +import java.util.Set; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.AddTagPersonCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.tag.Tag; + +/** + * Parses input arguments and creates a new AddTagPersonCommand object + */ +public class AddTagPersonCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the AddTagPersonCommand + * and returns an AddTagTaskCommand object for execution. + * + * @throws ParseException if the user input does not conform the expected format + */ + public AddTagPersonCommand parse(String args) throws ParseException { + requireNonNull(args); + ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_TAG); + + Index index; + + try { + index = ParserUtil.parseIndex(argMultimap.getPreamble()); + } catch (ParseException pe) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddTagPersonCommand.MESSAGE_USAGE), + pe); + } + + Set tags = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); + + if (tags.size() == 0) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddTagPersonCommand.MESSAGE_USAGE)); + } + + return new AddTagPersonCommand(index, tags); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/AddTagTaskCommandParser.java b/src/main/java/seedu/address/logic/parser/AddTagTaskCommandParser.java new file mode 100644 index 00000000000..ef89ba4110e --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/AddTagTaskCommandParser.java @@ -0,0 +1,47 @@ +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_TAG; + +import java.util.Set; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.AddTagTaskCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.tag.Tag; + +/** + * Parses input arguments and creates a new AddTagTaskCommand object + */ +public class AddTagTaskCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the AddTagTaskCommand + * and returns an AddTagTaskCommand object for execution. + * + * @throws ParseException if the user input does not conform the expected format + */ + public AddTagTaskCommand parse(String args) throws ParseException { + requireNonNull(args); + ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_TAG); + + Index index; + + try { + index = ParserUtil.parseIndex(argMultimap.getPreamble()); + } catch (ParseException pe) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddTagTaskCommand.MESSAGE_USAGE), + pe); + } + + Set tags = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); + + if (tags.size() == 0) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddTagTaskCommand.MESSAGE_USAGE)); + } + + return new AddTagTaskCommand(index, tags); + } + +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 1c4ca7efe05..606c03429c6 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -9,6 +9,8 @@ import seedu.address.commons.core.LogsCenter; import seedu.address.logic.commands.AddPersonCommand; +import seedu.address.logic.commands.AddTagPersonCommand; +import seedu.address.logic.commands.AddTagTaskCommand; import seedu.address.logic.commands.AddTaskCommand; import seedu.address.logic.commands.Command; import seedu.address.logic.commands.DeleteAllPersonCommand; @@ -75,6 +77,11 @@ public Command parseCommand(String userInput) throws ParseException { case EditPersonCommand.SHORTENED_COMMAND_WORD: return new EditPersonCommandParser().parse(arguments); + case AddTagPersonCommand.COMMAND_WORD: + // Fallthrough + case AddTagPersonCommand.SHORTENED_COMMAND_WORD: + return new AddTagPersonCommandParser().parse(arguments); + case DeletePersonCommand.COMMAND_WORD: // Fallthrough case DeletePersonCommand.SHORTENED_COMMAND_WORD: @@ -125,6 +132,11 @@ public Command parseCommand(String userInput) throws ParseException { case EditTaskCommand.SHORTENED_COMMAND_WORD: return new EditTaskCommandParser().parse(arguments); + case AddTagTaskCommand.COMMAND_WORD: + // Fallthrough + case AddTagTaskCommand.SHORTENED_COMMAND_WORD: + return new AddTagTaskCommandParser().parse(arguments); + case FindTaskCommand.COMMAND_WORD: // Fallthrough case FindTaskCommand.SHORTENED_COMMAND_WORD: diff --git a/src/test/java/seedu/address/logic/commands/AddTagPersonCommandTest.java b/src/test/java/seedu/address/logic/commands/AddTagPersonCommandTest.java new file mode 100644 index 00000000000..8f57586dd28 --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/AddTagPersonCommandTest.java @@ -0,0 +1,149 @@ +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.assertCommandFailure; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND; +import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; + +import java.util.HashSet; +import java.util.Set; + +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; +import seedu.address.model.UserPrefs; +import seedu.address.model.person.Person; +import seedu.address.model.tag.Tag; +import seedu.address.testutil.PersonBuilder; + +/** + * Contains integration tests (interaction with the Model) and unit tests for AddTagPersonCommand. + */ +public class AddTagPersonCommandTest { + + private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + + @Test + public void execute_unfilteredList_success() { + Tag tag = new Tag("caterer"); + Set tags = new HashSet<>(); + tags.add(tag); + + AddTagPersonCommand addTagPersonCommand = new AddTagPersonCommand(INDEX_FIRST, tags); + + Person personToEdit = model.getFilteredPersonList().get(INDEX_FIRST.getZeroBased()); + Set existingTags = personToEdit.getTags(); + Set updatedTags = new HashSet<>(existingTags); + updatedTags.add(tag); + + Person editedPerson = new PersonBuilder(personToEdit).editTags(updatedTags).build(); + + String expectedMessage = String.format(AddTagPersonCommand.MESSAGE_EDIT_PERSON_SUCCESS, + Messages.format(editedPerson)); + + ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.setPerson(personToEdit, editedPerson); + + assertCommandSuccess(addTagPersonCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_invalidIndexUnfilteredList_throwsCommandException() { + Tag tag = new Tag("caterer"); + Set tags = new HashSet<>(); + tags.add(tag); + + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1); + AddTagPersonCommand addTagPersonCommand = new AddTagPersonCommand(outOfBoundIndex, tags); + + assertCommandFailure(addTagPersonCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } + + @Test + public void execute_filteredList_success() { + showPersonAtIndex(model, INDEX_FIRST); + + Tag tag = new Tag("caterer"); + Set tags = new HashSet<>(); + tags.add(tag); + + Person personToEdit = model.getFilteredPersonList().get(INDEX_FIRST.getZeroBased()); + AddTagPersonCommand addTagPersonCommand = new AddTagPersonCommand(INDEX_FIRST, tags); + + Set existingTags = personToEdit.getTags(); + Set updatedTags = new HashSet<>(existingTags); + updatedTags.add(tag); + + Person editedPerson = new PersonBuilder(personToEdit).editTags(updatedTags).build(); + + String expectedMessage = String.format(AddTagPersonCommand.MESSAGE_EDIT_PERSON_SUCCESS, + Messages.format(editedPerson)); + + ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.setPerson(personToEdit, editedPerson); + + assertCommandSuccess(addTagPersonCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_invalidIndexFilteredList_throwsCommandException() { + Tag tag = new Tag("caterer"); + Set tags = new HashSet<>(); + tags.add(tag); + + showPersonAtIndex(model, INDEX_FIRST); + + Index outOfBoundIndex = INDEX_SECOND; + assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size()); + + AddTagPersonCommand addTagPersonCommand = new AddTagPersonCommand(outOfBoundIndex, tags); + + assertCommandFailure(addTagPersonCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } + + @Test + public void equals() { + Tag tag = new Tag("caterer"); + Set tags = new HashSet<>(); + tags.add(tag); + + AddTagPersonCommand addTagPersonCommand1 = new AddTagPersonCommand(INDEX_FIRST, tags); + AddTagPersonCommand addTagPersonCommand2 = new AddTagPersonCommand(INDEX_FIRST, tags); + + // Same values -> returns true + assertTrue(addTagPersonCommand1.equals(addTagPersonCommand1)); + assertTrue(addTagPersonCommand1.equals(addTagPersonCommand2)); + + // Different index -> returns false + AddTagPersonCommand addTagPersonCommandDifferentIndex = new AddTagPersonCommand(INDEX_SECOND, tags); + assertFalse(addTagPersonCommand1.equals(addTagPersonCommandDifferentIndex)); + + // Different tags -> returns false + Set differentTags = new HashSet<>(); + differentTags.add(new Tag("differentTag")); + AddTagPersonCommand addTagPersonCommandDifferentTags = new AddTagPersonCommand(INDEX_FIRST, differentTags); + assertFalse(addTagPersonCommand1.equals(addTagPersonCommandDifferentTags)); + } + + @Test + public void toStringMethod() { + Index index = Index.fromOneBased(1); + Tag tag = new Tag("caterer"); + Set tags = new HashSet<>(); + tags.add(tag); + + AddTagPersonCommand addTagPersonCommand = new AddTagPersonCommand(INDEX_FIRST, tags); + String expected = AddTagPersonCommand.class.getCanonicalName() + "{index=" + index + ", tagsToAdd=" + + tags + "}"; + assertEquals(expected, addTagPersonCommand.toString()); + } + +} diff --git a/src/test/java/seedu/address/logic/commands/AddTagTaskCommandTest.java b/src/test/java/seedu/address/logic/commands/AddTagTaskCommandTest.java new file mode 100644 index 00000000000..a11a456615e --- /dev/null +++ b/src/test/java/seedu/address/logic/commands/AddTagTaskCommandTest.java @@ -0,0 +1,149 @@ +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.assertCommandFailure; +import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess; +import static seedu.address.logic.commands.CommandTestUtil.showTaskAtIndex; +import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND; +import static seedu.address.testutil.TypicalTasks.getTypicalAddressBook; + +import java.util.HashSet; +import java.util.Set; + +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; +import seedu.address.model.UserPrefs; +import seedu.address.model.tag.Tag; +import seedu.address.model.task.Task; +import seedu.address.testutil.TaskBuilder; + +/** + * Contains integration tests (interaction with the Model) and unit tests for AddTagTaskCommand. + */ +public class AddTagTaskCommandTest { + + private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + + @Test + public void execute_unfilteredList_success() { + Tag tag = new Tag("class"); + Set tags = new HashSet<>(); + tags.add(tag); + + AddTagTaskCommand addTagTaskCommand = new AddTagTaskCommand(INDEX_FIRST, tags); + + Task taskToEdit = model.getFilteredTaskList().get(INDEX_FIRST.getZeroBased()); + Set existingTags = taskToEdit.getTags(); + Set updatedTags = new HashSet<>(existingTags); + updatedTags.add(tag); + + Task editedTask = new TaskBuilder(taskToEdit).editTags(updatedTags).build(); + + String expectedMessage = String.format(AddTagTaskCommand.MESSAGE_EDIT_TASK_SUCCESS, + Messages.format(editedTask)); + + ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.setTask(taskToEdit, editedTask); + + assertCommandSuccess(addTagTaskCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_invalidIndexUnfilteredList_throwsCommandException() { + Tag tag = new Tag("class"); + Set tags = new HashSet<>(); + tags.add(tag); + + Index outOfBoundIndex = Index.fromOneBased(model.getFilteredTaskList().size() + 1); + AddTagTaskCommand addTagTaskCommand = new AddTagTaskCommand(outOfBoundIndex, tags); + + assertCommandFailure(addTagTaskCommand, model, Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } + + @Test + public void execute_filteredList_success() { + showTaskAtIndex(model, INDEX_FIRST); + + Tag tag = new Tag("class"); + Set tags = new HashSet<>(); + tags.add(tag); + + Task taskToEdit = model.getFilteredTaskList().get(INDEX_FIRST.getZeroBased()); + AddTagTaskCommand addTagTaskCommand = new AddTagTaskCommand(INDEX_FIRST, tags); + + Set existingTags = taskToEdit.getTags(); + Set updatedTags = new HashSet<>(existingTags); + updatedTags.add(tag); + + Task editedTask = new TaskBuilder(taskToEdit).editTags(updatedTags).build(); + + String expectedMessage = String.format(AddTagTaskCommand.MESSAGE_EDIT_TASK_SUCCESS, + Messages.format(editedTask)); + + ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); + expectedModel.setTask(taskToEdit, editedTask); + + assertCommandSuccess(addTagTaskCommand, model, expectedMessage, expectedModel); + } + + @Test + public void execute_invalidIndexFilteredList_throwsCommandException() { + Tag tag = new Tag("class"); + Set tags = new HashSet<>(); + tags.add(tag); + + showTaskAtIndex(model, INDEX_FIRST); + + Index outOfBoundIndex = INDEX_SECOND; + assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getTaskList().size()); + + AddTagTaskCommand addTagTaskCommand = new AddTagTaskCommand(outOfBoundIndex, tags); + + assertCommandFailure(addTagTaskCommand, model, Messages.MESSAGE_INVALID_TASK_DISPLAYED_INDEX); + } + + @Test + public void equals() { + Tag tag = new Tag("class"); + Set tags = new HashSet<>(); + tags.add(tag); + + AddTagTaskCommand addTagTaskCommand1 = new AddTagTaskCommand(INDEX_FIRST, tags); + AddTagTaskCommand addTagTaskCommand2 = new AddTagTaskCommand(INDEX_FIRST, tags); + + // Same values -> returns true + assertTrue(addTagTaskCommand1.equals(addTagTaskCommand1)); + assertTrue(addTagTaskCommand1.equals(addTagTaskCommand2)); + + // Different index -> returns false + AddTagTaskCommand addTagTaskCommandDifferentIndex = new AddTagTaskCommand(INDEX_SECOND, tags); + assertFalse(addTagTaskCommand1.equals(addTagTaskCommandDifferentIndex)); + + // Different tags -> returns false + Set differentTags = new HashSet<>(); + differentTags.add(new Tag("differentTag")); + AddTagTaskCommand addTagTaskCommandDifferentTags = new AddTagTaskCommand(INDEX_FIRST, differentTags); + assertFalse(addTagTaskCommand1.equals(addTagTaskCommandDifferentTags)); + } + + @Test + public void toStringMethod() { + Index index = Index.fromOneBased(1); + Tag tag = new Tag("class"); + Set tags = new HashSet<>(); + tags.add(tag); + + AddTagTaskCommand addTagTaskCommand = new AddTagTaskCommand(INDEX_FIRST, tags); + String expected = AddTagTaskCommand.class.getCanonicalName() + "{index=" + index + ", tagsToAdd=" + + tags + "}"; + assertEquals(expected, addTagTaskCommand.toString()); + } + +} diff --git a/src/test/java/seedu/address/logic/parser/AddTagPersonCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddTagPersonCommandParserTest.java new file mode 100644 index 00000000000..51ef84b84e4 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/AddTagPersonCommandParserTest.java @@ -0,0 +1,97 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.CommandTestUtil.INVALID_TAG_DESC; +import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY; +import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_FRIEND; +import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_HUSBAND; +import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_AMY; +import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND; +import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.AddTagPersonCommand; +import seedu.address.model.Model; +import seedu.address.model.ModelManager; +import seedu.address.model.UserPrefs; +import seedu.address.model.person.Person; +import seedu.address.model.tag.Tag; + +public class AddTagPersonCommandParserTest { + + private static final String TAG_EMPTY = " " + PREFIX_TAG; + + private static final String MESSAGE_INVALID_FORMAT = + String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddTagPersonCommand.MESSAGE_USAGE); + + private AddTagPersonCommandParser parser = new AddTagPersonCommandParser(); + + @Test + public void parse_missingParts_failure() { + // no index specified + assertParseFailure(parser, VALID_NAME_AMY, MESSAGE_INVALID_FORMAT); + + // no field specified + assertParseFailure(parser, "1", MESSAGE_INVALID_FORMAT); + + // no index and no field specified + assertParseFailure(parser, "", MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_invalidPreamble_failure() { + // negative index + assertParseFailure(parser, "-5" + NAME_DESC_AMY, MESSAGE_INVALID_FORMAT); + + // zero index + assertParseFailure(parser, "0" + NAME_DESC_AMY, MESSAGE_INVALID_FORMAT); + + // invalid arguments being parsed as preamble + assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_FORMAT); + + // invalid prefix being parsed as preamble + assertParseFailure(parser, "1 i/ string", MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_invalidValue_failure() { + assertParseFailure(parser, "1" + INVALID_TAG_DESC, Tag.MESSAGE_CONSTRAINTS); // invalid tag + + // while parsing {@code PREFIX_TAG} together with a valid tag results in error + assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_DESC_HUSBAND + TAG_EMPTY, Tag.MESSAGE_CONSTRAINTS); + assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_EMPTY + TAG_DESC_HUSBAND, Tag.MESSAGE_CONSTRAINTS); + assertParseFailure(parser, "1" + TAG_EMPTY + TAG_DESC_FRIEND + TAG_DESC_HUSBAND, Tag.MESSAGE_CONSTRAINTS); + } + + @Test + public void parse_allFieldsSpecified_success() { + Tag tag = new Tag(VALID_TAG_FRIEND); + Set tags = new HashSet<>(); + tags.add(tag); + + Index targetIndex = INDEX_SECOND; + String userInput = targetIndex.getOneBased() + TAG_DESC_FRIEND; + + Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + + Person personToEdit = model.getFilteredPersonList().get(targetIndex.getZeroBased()); + + Set existingTags = personToEdit.getTags(); + Set updatedTags = new HashSet<>(existingTags); + updatedTags.add(tag); + + AddTagPersonCommand expectedCommand = new AddTagPersonCommand(targetIndex, tags); + + assertParseSuccess(parser, userInput, expectedCommand); + } + +} diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 6df002c277c..851effe2401 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -8,11 +8,15 @@ import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST; import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.junit.jupiter.api.Test; import seedu.address.logic.commands.AddPersonCommand; +import seedu.address.logic.commands.AddTagPersonCommand; +import seedu.address.logic.commands.AddTagTaskCommand; import seedu.address.logic.commands.AddTaskCommand; import seedu.address.logic.commands.DeleteAllPersonCommand; import seedu.address.logic.commands.DeleteAllTaskCommand; @@ -38,6 +42,7 @@ import seedu.address.model.person.NameContainsKeywordsPredicate; import seedu.address.model.person.Person; import seedu.address.model.person.PersonContainsTagsPredicate; +import seedu.address.model.tag.Tag; import seedu.address.model.task.Task; import seedu.address.model.task.TaskContainsKeywordsPredicate; import seedu.address.model.task.TaskContainsTagsPredicate; @@ -115,6 +120,28 @@ public void parseCommand_shortened_editPerson() throws Exception { assertEquals(new EditPersonCommand(INDEX_FIRST, descriptor), command); } + @Test + public void parseCommand_addTagPerson() throws Exception { + Tag tag = new Tag("caterer"); + Set tags = new HashSet<>(); + tags.add(tag); + AddTagPersonCommand command = (AddTagPersonCommand) parser + .parseCommand(AddTagPersonCommand.COMMAND_WORD + " " + + INDEX_FIRST.getOneBased() + " t/caterer"); + assertEquals(new AddTagPersonCommand(INDEX_FIRST, tags), command); + } + + @Test + public void parseCommand_shortened_addTagPerson() throws Exception { + Tag tag = new Tag("caterer"); + Set tags = new HashSet<>(); + tags.add(tag); + AddTagPersonCommand command = (AddTagPersonCommand) parser + .parseCommand(AddTagPersonCommand.SHORTENED_COMMAND_WORD + " " + + INDEX_FIRST.getOneBased() + " t/caterer"); + assertEquals(new AddTagPersonCommand(INDEX_FIRST, tags), command); + } + @Test public void parseCommand_exit() throws Exception { assertTrue(parser.parseCommand(ExitCommand.COMMAND_WORD) instanceof ExitCommand); @@ -301,12 +328,36 @@ public void parseCommand_shortened_editTask() throws Exception { assertEquals(new EditTaskCommand(INDEX_FIRST, descriptor), command); } + @Test + public void parseCommand_addTagTask() throws Exception { + Tag tag = new Tag("class"); + Set tags = new HashSet<>(); + tags.add(tag); + AddTagTaskCommand command = (AddTagTaskCommand) parser + .parseCommand(AddTagTaskCommand.COMMAND_WORD + " " + + INDEX_FIRST.getOneBased() + " " + " t/class"); + assertEquals(new AddTagTaskCommand(INDEX_FIRST, tags), command); + } + + @Test + public void parseCommand_shortened_addTagTask() throws Exception { + Tag tag = new Tag("class"); + Set tags = new HashSet<>(); + tags.add(tag); + AddTagTaskCommand command = (AddTagTaskCommand) parser + .parseCommand(AddTagTaskCommand.SHORTENED_COMMAND_WORD + " " + + INDEX_FIRST.getOneBased() + " " + " t/class"); + assertEquals(new AddTagTaskCommand(INDEX_FIRST, tags), command); + } + + @Test public void parseCommand_deleteTask() throws Exception { DeleteTaskCommand command = (DeleteTaskCommand) parser.parseCommand( DeleteTaskCommand.COMMAND_WORD + " " + INDEX_FIRST.getOneBased()); assertEquals(new DeleteTaskCommand(INDEX_FIRST), command); } + @Test public void parseCommand_shortened_deleteTask() throws Exception { DeleteTaskCommand command = (DeleteTaskCommand) parser.parseCommand( DeleteTaskCommand.SHORTENED_COMMAND_WORD + " " + INDEX_FIRST.getOneBased()); diff --git a/src/test/java/seedu/address/testutil/PersonBuilder.java b/src/test/java/seedu/address/testutil/PersonBuilder.java index 6be381d39ba..c4f88efa799 100644 --- a/src/test/java/seedu/address/testutil/PersonBuilder.java +++ b/src/test/java/seedu/address/testutil/PersonBuilder.java @@ -65,6 +65,14 @@ public PersonBuilder withTags(String ... tags) { return this; } + /** + * Sets the {@code tags} of the {@code Person} that we are building. + */ + public PersonBuilder editTags(Set tags) { + this.tags = tags; + return this; + } + /** * Sets the {@code Address} of the {@code Person} that we are building. */ diff --git a/src/test/java/seedu/address/testutil/TaskBuilder.java b/src/test/java/seedu/address/testutil/TaskBuilder.java index 2e36a5bdd81..0753d9dd4ed 100644 --- a/src/test/java/seedu/address/testutil/TaskBuilder.java +++ b/src/test/java/seedu/address/testutil/TaskBuilder.java @@ -75,6 +75,14 @@ public TaskBuilder withTags(String ... tags) { return this; } + /** + * Sets the {@code tags} of the {@code Task} that we are building. + */ + public TaskBuilder editTags(Set tags) { + this.tags = tags; + return this; + } + /** * Builds the {@code Task} with the relevant information. */ From 54a966f0a3227f11ec30e0f86f4449b680160f25 Mon Sep 17 00:00:00 2001 From: pra-navi Date: Wed, 1 Nov 2023 14:11:24 +0800 Subject: [PATCH 2/3] feat: Customise the message output of success --- .../logic/commands/AddTagPersonCommand.java | 41 +++++++- .../logic/commands/AddTagTaskCommand.java | 41 +++++++- .../commands/AddTagPersonCommandTest.java | 32 ++++++- .../logic/commands/AddTagTaskCommandTest.java | 32 ++++++- .../parser/AddTagPersonCommandParserTest.java | 8 +- .../parser/AddTagTaskCommandParserTest.java | 95 +++++++++++++++++++ .../logic/parser/AddressBookParserTest.java | 20 ++-- .../seedu/address/testutil/PersonBuilder.java | 2 +- .../seedu/address/testutil/TaskBuilder.java | 2 +- 9 files changed, 242 insertions(+), 31 deletions(-) create mode 100644 src/test/java/seedu/address/logic/parser/AddTagTaskCommandParserTest.java diff --git a/src/main/java/seedu/address/logic/commands/AddTagPersonCommand.java b/src/main/java/seedu/address/logic/commands/AddTagPersonCommand.java index 6a2342379d3..ae62f5042cc 100644 --- a/src/main/java/seedu/address/logic/commands/AddTagPersonCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddTagPersonCommand.java @@ -7,6 +7,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import seedu.address.commons.core.index.Index; import seedu.address.commons.util.ToStringBuilder; @@ -36,9 +37,12 @@ public class AddTagPersonCommand extends Command { + "Example: " + COMMAND_WORD + " 1 " + PREFIX_TAG + "catering"; - public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Person: %1$s"; + public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Person: %1$s \n" + "Successfully added these " + + "tags: %2$s \n" + "These tags were not added as they already exists: %3$s"; public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book."; + private static Set newTags = new HashSet<>(); + private static Set oldTags = new HashSet<>(); private final Set tagsToAdd; private final Index index; @@ -52,6 +56,8 @@ public AddTagPersonCommand(Index index, Set tagsToAdd) { this.index = index; this.tagsToAdd = tagsToAdd; + newTags = new HashSet<>(); + oldTags = new HashSet<>(); } @Override @@ -68,7 +74,8 @@ public CommandResult execute(Model model) throws CommandException { model.setPerson(personToEdit, editedPerson); model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); - return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson))); + return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson), + setToString(newTags), setToString(oldTags))); } /** @@ -82,12 +89,42 @@ private static Person createEditedPerson(Person personToEdit, Set tagsToAdd Email email = personToEdit.getEmail(); Address address = personToEdit.getAddress(); Set existingTags = personToEdit.getTags(); + + for (Tag tag : tagsToAdd) { + if (existingTags.contains(tag)) { + oldTags.add(tag); + } else { + newTags.add(tag); + } + } + Set updatedTags = new HashSet<>(existingTags); updatedTags.addAll(tagsToAdd); return new Person(name, phone, email, address, updatedTags); } + public static String setToString(Set tags) { + + if (tags.isEmpty()) { + return "-"; + } else { + String tagString = tags.stream() + .map(Tag::toString) + .collect(Collectors.joining(", ")); + + return tagString; + } + } + + public static Set getNewTags() { + return newTags; + } + + public static Set getOldTags() { + return oldTags; + } + @Override public boolean equals(Object other) { if (other == this) { diff --git a/src/main/java/seedu/address/logic/commands/AddTagTaskCommand.java b/src/main/java/seedu/address/logic/commands/AddTagTaskCommand.java index f335d5e483b..4caa47a6dff 100644 --- a/src/main/java/seedu/address/logic/commands/AddTagTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddTagTaskCommand.java @@ -7,6 +7,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import seedu.address.commons.core.index.Index; import seedu.address.commons.util.ToStringBuilder; @@ -35,9 +36,12 @@ public class AddTagTaskCommand extends Command { + "Example: " + COMMAND_WORD + " 1 " + PREFIX_TAG + "class"; - public static final String MESSAGE_EDIT_TASK_SUCCESS = "Edited Task: %1$s"; + public static final String MESSAGE_EDIT_TASK_SUCCESS = "Edited Task: %1$s \n" + "Successfully added these " + + "tags: %2$s \n" + "These tags were not added as they already exists: %3$s"; public static final String MESSAGE_DUPLICATE_TASK = "This task already exists in the address book."; + private static Set newTags = new HashSet<>(); + private static Set oldTags = new HashSet<>(); private final Set tagsToAdd; private final Index index; @@ -51,6 +55,8 @@ public AddTagTaskCommand(Index index, Set tagsToAdd) { this.index = index; this.tagsToAdd = tagsToAdd; + newTags = new HashSet<>(); + oldTags = new HashSet<>(); } @Override @@ -67,7 +73,8 @@ public CommandResult execute(Model model) throws CommandException { model.setTask(taskToEdit, editedTask); model.updateFilteredTaskList(PREDICATE_SHOW_ALL_TASKS); - return new CommandResult(String.format(MESSAGE_EDIT_TASK_SUCCESS, Messages.format(editedTask))); + return new CommandResult(String.format(MESSAGE_EDIT_TASK_SUCCESS, Messages.format(editedTask), + setToString(newTags), setToString(oldTags))); } /** @@ -80,12 +87,42 @@ private static Task createEditedTask(Task taskToEdit, Set tagsToAdd) { Note note = taskToEdit.getNote(); Status taskStatus = taskToEdit.getStatus(); Set existingTags = taskToEdit.getTags(); + + for (Tag tag : tagsToAdd) { + if (existingTags.contains(tag)) { + oldTags.add(tag); + } else { + newTags.add(tag); + } + } + Set updatedTags = new HashSet<>(existingTags); updatedTags.addAll(tagsToAdd); return new Task(title, note, taskStatus, updatedTags); } + public static String setToString(Set tags) { + + if (tags.isEmpty()) { + return "-"; + } else { + String tagString = tags.stream() + .map(Tag::toString) + .collect(Collectors.joining(", ")); + + return tagString; + } + } + + public static Set getNewTags() { + return newTags; + } + + public static Set getOldTags() { + return oldTags; + } + @Override public boolean equals(Object other) { if (other == this) { diff --git a/src/test/java/seedu/address/logic/commands/AddTagPersonCommandTest.java b/src/test/java/seedu/address/logic/commands/AddTagPersonCommandTest.java index 8f57586dd28..cbad3f54748 100644 --- a/src/test/java/seedu/address/logic/commands/AddTagPersonCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddTagPersonCommandTest.java @@ -44,10 +44,22 @@ public void execute_unfilteredList_success() { Set updatedTags = new HashSet<>(existingTags); updatedTags.add(tag); - Person editedPerson = new PersonBuilder(personToEdit).editTags(updatedTags).build(); + Set newTags = new HashSet<>(); + Set oldTags = new HashSet<>(); + + for (Tag t : tags) { + if (existingTags.contains(tag)) { + oldTags.add(t); + } else { + newTags.add(t); + } + } + + Person editedPerson = new PersonBuilder(personToEdit).setTags(updatedTags).build(); String expectedMessage = String.format(AddTagPersonCommand.MESSAGE_EDIT_PERSON_SUCCESS, - Messages.format(editedPerson)); + Messages.format(editedPerson), AddTagPersonCommand.setToString(newTags), + AddTagPersonCommand.setToString(oldTags)); ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); expectedModel.setPerson(personToEdit, editedPerson); @@ -82,10 +94,22 @@ public void execute_filteredList_success() { Set updatedTags = new HashSet<>(existingTags); updatedTags.add(tag); - Person editedPerson = new PersonBuilder(personToEdit).editTags(updatedTags).build(); + Set newTags = new HashSet<>(); + Set oldTags = new HashSet<>(); + + for (Tag t : tags) { + if (existingTags.contains(tag)) { + oldTags.add(t); + } else { + newTags.add(t); + } + } + + Person editedPerson = new PersonBuilder(personToEdit).setTags(updatedTags).build(); String expectedMessage = String.format(AddTagPersonCommand.MESSAGE_EDIT_PERSON_SUCCESS, - Messages.format(editedPerson)); + Messages.format(editedPerson), AddTagPersonCommand.setToString(newTags), + AddTagPersonCommand.setToString(oldTags)); ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); expectedModel.setPerson(personToEdit, editedPerson); diff --git a/src/test/java/seedu/address/logic/commands/AddTagTaskCommandTest.java b/src/test/java/seedu/address/logic/commands/AddTagTaskCommandTest.java index a11a456615e..881ee5f46d0 100644 --- a/src/test/java/seedu/address/logic/commands/AddTagTaskCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddTagTaskCommandTest.java @@ -44,10 +44,22 @@ public void execute_unfilteredList_success() { Set updatedTags = new HashSet<>(existingTags); updatedTags.add(tag); - Task editedTask = new TaskBuilder(taskToEdit).editTags(updatedTags).build(); + Set newTags = new HashSet<>(); + Set oldTags = new HashSet<>(); + + for (Tag t : tags) { + if (existingTags.contains(tag)) { + oldTags.add(t); + } else { + newTags.add(t); + } + } + + Task editedTask = new TaskBuilder(taskToEdit).setTags(updatedTags).build(); String expectedMessage = String.format(AddTagTaskCommand.MESSAGE_EDIT_TASK_SUCCESS, - Messages.format(editedTask)); + Messages.format(editedTask), AddTagTaskCommand.setToString(newTags), + AddTagTaskCommand.setToString(oldTags)); ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); expectedModel.setTask(taskToEdit, editedTask); @@ -82,10 +94,22 @@ public void execute_filteredList_success() { Set updatedTags = new HashSet<>(existingTags); updatedTags.add(tag); - Task editedTask = new TaskBuilder(taskToEdit).editTags(updatedTags).build(); + Set newTags = new HashSet<>(); + Set oldTags = new HashSet<>(); + + for (Tag t : tags) { + if (existingTags.contains(tag)) { + oldTags.add(t); + } else { + newTags.add(t); + } + } + + Task editedTask = new TaskBuilder(taskToEdit).setTags(updatedTags).build(); String expectedMessage = String.format(AddTagTaskCommand.MESSAGE_EDIT_TASK_SUCCESS, - Messages.format(editedTask)); + Messages.format(editedTask), AddTagTaskCommand.setToString(newTags), + AddTagTaskCommand.setToString(oldTags)); ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs()); expectedModel.setTask(taskToEdit, editedTask); diff --git a/src/test/java/seedu/address/logic/parser/AddTagPersonCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddTagPersonCommandParserTest.java index 51ef84b84e4..3fe6a502586 100644 --- a/src/test/java/seedu/address/logic/parser/AddTagPersonCommandParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddTagPersonCommandParserTest.java @@ -2,10 +2,8 @@ import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import static seedu.address.logic.commands.CommandTestUtil.INVALID_TAG_DESC; -import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY; import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_FRIEND; import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_HUSBAND; -import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_AMY; import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; @@ -38,7 +36,7 @@ public class AddTagPersonCommandParserTest { @Test public void parse_missingParts_failure() { // no index specified - assertParseFailure(parser, VALID_NAME_AMY, MESSAGE_INVALID_FORMAT); + assertParseFailure(parser, VALID_TAG_FRIEND, MESSAGE_INVALID_FORMAT); // no field specified assertParseFailure(parser, "1", MESSAGE_INVALID_FORMAT); @@ -50,10 +48,10 @@ public void parse_missingParts_failure() { @Test public void parse_invalidPreamble_failure() { // negative index - assertParseFailure(parser, "-5" + NAME_DESC_AMY, MESSAGE_INVALID_FORMAT); + assertParseFailure(parser, "-5" + TAG_DESC_FRIEND, MESSAGE_INVALID_FORMAT); // zero index - assertParseFailure(parser, "0" + NAME_DESC_AMY, MESSAGE_INVALID_FORMAT); + assertParseFailure(parser, "0" + TAG_DESC_FRIEND, MESSAGE_INVALID_FORMAT); // invalid arguments being parsed as preamble assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_FORMAT); diff --git a/src/test/java/seedu/address/logic/parser/AddTagTaskCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddTagTaskCommandParserTest.java new file mode 100644 index 00000000000..1bba5e86987 --- /dev/null +++ b/src/test/java/seedu/address/logic/parser/AddTagTaskCommandParserTest.java @@ -0,0 +1,95 @@ +package seedu.address.logic.parser; + +import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.address.logic.commands.CommandTestUtil.INVALID_TAG_DESC; +import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_AGENDA; +import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_BUDGET; +import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_AGENDA; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure; +import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess; +import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND; +import static seedu.address.testutil.TypicalTasks.getTypicalAddressBook; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.AddTagTaskCommand; +import seedu.address.model.Model; +import seedu.address.model.ModelManager; +import seedu.address.model.UserPrefs; +import seedu.address.model.tag.Tag; +import seedu.address.model.task.Task; + +public class AddTagTaskCommandParserTest { + + private static final String TAG_EMPTY = " " + PREFIX_TAG; + + private static final String MESSAGE_INVALID_FORMAT = + String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddTagTaskCommand.MESSAGE_USAGE); + + private AddTagTaskCommandParser parser = new AddTagTaskCommandParser(); + + @Test + public void parse_missingParts_failure() { + // no index specified + assertParseFailure(parser, VALID_TAG_AGENDA, MESSAGE_INVALID_FORMAT); + + // no field specified + assertParseFailure(parser, "1", MESSAGE_INVALID_FORMAT); + + // no index and no field specified + assertParseFailure(parser, "", MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_invalidPreamble_failure() { + // negative index + assertParseFailure(parser, "-5" + TAG_DESC_AGENDA, MESSAGE_INVALID_FORMAT); + + // zero index + assertParseFailure(parser, "0" + TAG_DESC_AGENDA, MESSAGE_INVALID_FORMAT); + + // invalid arguments being parsed as preamble + assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_FORMAT); + + // invalid prefix being parsed as preamble + assertParseFailure(parser, "1 i/ string", MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_invalidValue_failure() { + assertParseFailure(parser, "1" + INVALID_TAG_DESC, Tag.MESSAGE_CONSTRAINTS); // invalid tag + + // while parsing {@code PREFIX_TAG} together with a valid tag results in error + assertParseFailure(parser, "1" + TAG_DESC_AGENDA + TAG_DESC_BUDGET + TAG_EMPTY, Tag.MESSAGE_CONSTRAINTS); + assertParseFailure(parser, "1" + TAG_DESC_AGENDA + TAG_EMPTY + TAG_DESC_BUDGET, Tag.MESSAGE_CONSTRAINTS); + assertParseFailure(parser, "1" + TAG_EMPTY + TAG_DESC_AGENDA + TAG_DESC_BUDGET, Tag.MESSAGE_CONSTRAINTS); + } + + @Test + public void parse_allFieldsSpecified_success() { + Tag tag = new Tag(VALID_TAG_AGENDA); + Set tags = new HashSet<>(); + tags.add(tag); + + Index targetIndex = INDEX_SECOND; + String userInput = targetIndex.getOneBased() + TAG_DESC_AGENDA; + + Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + + Task taskToEdit = model.getFilteredTaskList().get(targetIndex.getZeroBased()); + + Set existingTags = taskToEdit.getTags(); + Set updatedTags = new HashSet<>(existingTags); + updatedTags.add(tag); + + AddTagTaskCommand expectedCommand = new AddTagTaskCommand(targetIndex, tags); + + assertParseSuccess(parser, userInput, expectedCommand); + } + +} diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java index 851effe2401..a8da1f0504a 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java @@ -125,9 +125,8 @@ public void parseCommand_addTagPerson() throws Exception { Tag tag = new Tag("caterer"); Set tags = new HashSet<>(); tags.add(tag); - AddTagPersonCommand command = (AddTagPersonCommand) parser - .parseCommand(AddTagPersonCommand.COMMAND_WORD + " " - + INDEX_FIRST.getOneBased() + " t/caterer"); + AddTagPersonCommand command = (AddTagPersonCommand) parser.parseCommand(AddTagPersonCommand.COMMAND_WORD + + " " + INDEX_FIRST.getOneBased() + " t/caterer"); assertEquals(new AddTagPersonCommand(INDEX_FIRST, tags), command); } @@ -136,9 +135,8 @@ public void parseCommand_shortened_addTagPerson() throws Exception { Tag tag = new Tag("caterer"); Set tags = new HashSet<>(); tags.add(tag); - AddTagPersonCommand command = (AddTagPersonCommand) parser - .parseCommand(AddTagPersonCommand.SHORTENED_COMMAND_WORD + " " - + INDEX_FIRST.getOneBased() + " t/caterer"); + AddTagPersonCommand command = (AddTagPersonCommand) parser.parseCommand( + AddTagPersonCommand.SHORTENED_COMMAND_WORD + " " + INDEX_FIRST.getOneBased() + " t/caterer"); assertEquals(new AddTagPersonCommand(INDEX_FIRST, tags), command); } @@ -333,9 +331,8 @@ public void parseCommand_addTagTask() throws Exception { Tag tag = new Tag("class"); Set tags = new HashSet<>(); tags.add(tag); - AddTagTaskCommand command = (AddTagTaskCommand) parser - .parseCommand(AddTagTaskCommand.COMMAND_WORD + " " - + INDEX_FIRST.getOneBased() + " " + " t/class"); + AddTagTaskCommand command = (AddTagTaskCommand) parser.parseCommand(AddTagTaskCommand.COMMAND_WORD + + " " + INDEX_FIRST.getOneBased() + " " + " t/class"); assertEquals(new AddTagTaskCommand(INDEX_FIRST, tags), command); } @@ -344,9 +341,8 @@ public void parseCommand_shortened_addTagTask() throws Exception { Tag tag = new Tag("class"); Set tags = new HashSet<>(); tags.add(tag); - AddTagTaskCommand command = (AddTagTaskCommand) parser - .parseCommand(AddTagTaskCommand.SHORTENED_COMMAND_WORD + " " - + INDEX_FIRST.getOneBased() + " " + " t/class"); + AddTagTaskCommand command = (AddTagTaskCommand) parser.parseCommand(AddTagTaskCommand.SHORTENED_COMMAND_WORD + + " " + INDEX_FIRST.getOneBased() + " " + " t/class"); assertEquals(new AddTagTaskCommand(INDEX_FIRST, tags), command); } diff --git a/src/test/java/seedu/address/testutil/PersonBuilder.java b/src/test/java/seedu/address/testutil/PersonBuilder.java index c4f88efa799..da354b362ee 100644 --- a/src/test/java/seedu/address/testutil/PersonBuilder.java +++ b/src/test/java/seedu/address/testutil/PersonBuilder.java @@ -68,7 +68,7 @@ public PersonBuilder withTags(String ... tags) { /** * Sets the {@code tags} of the {@code Person} that we are building. */ - public PersonBuilder editTags(Set tags) { + public PersonBuilder setTags(Set tags) { this.tags = tags; return this; } diff --git a/src/test/java/seedu/address/testutil/TaskBuilder.java b/src/test/java/seedu/address/testutil/TaskBuilder.java index 0753d9dd4ed..0ffdf313a90 100644 --- a/src/test/java/seedu/address/testutil/TaskBuilder.java +++ b/src/test/java/seedu/address/testutil/TaskBuilder.java @@ -78,7 +78,7 @@ public TaskBuilder withTags(String ... tags) { /** * Sets the {@code tags} of the {@code Task} that we are building. */ - public TaskBuilder editTags(Set tags) { + public TaskBuilder setTags(Set tags) { this.tags = tags; return this; } From b3c593e524f6bf8f740f7d582869657de82e5a9c Mon Sep 17 00:00:00 2001 From: pra-navi Date: Wed, 1 Nov 2023 23:28:16 +0800 Subject: [PATCH 3/3] refactor: Use removeAll and retainAll instead of for loop --- .../logic/commands/AddTagPersonCommand.java | 37 +++++++------------ .../logic/commands/AddTagTaskCommand.java | 37 +++++++------------ .../parser/AddTagPersonCommandParser.java | 4 +- .../logic/parser/AddTagTaskCommandParser.java | 4 +- .../commands/AddTagPersonCommandTest.java | 31 +++++++++------- .../logic/commands/AddTagTaskCommandTest.java | 31 +++++++++------- 6 files changed, 66 insertions(+), 78 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/AddTagPersonCommand.java b/src/main/java/seedu/address/logic/commands/AddTagPersonCommand.java index ae62f5042cc..f89d0fb1236 100644 --- a/src/main/java/seedu/address/logic/commands/AddTagPersonCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddTagPersonCommand.java @@ -30,19 +30,20 @@ public class AddTagPersonCommand extends Command { public static final String SHORTENED_COMMAND_WORD = "atagp"; public static final String MESSAGE_USAGE = COMMAND_WORD + " (alias: " + SHORTENED_COMMAND_WORD + ")" - + ": Adds new tag to the person identified " + + ": Adds new tags to the person identified " + "by the index number used in the displayed contact list. \n" + "Parameters: INDEX (must be a positive integer) " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " 1 " - + PREFIX_TAG + "catering"; + + PREFIX_TAG + "catering " + PREFIX_TAG + "smallBusiness"; public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Person: %1$s \n" + "Successfully added these " + "tags: %2$s \n" + "These tags were not added as they already exists: %3$s"; - public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book."; - private static Set newTags = new HashSet<>(); - private static Set oldTags = new HashSet<>(); + // newTags stores those from tagsToAdd that are not already in personToEdit's tags + private static Set newTags; + // oldTags stores those from tagsToAdd that are already in personToEdit's tags + private static Set oldTags; private final Set tagsToAdd; private final Index index; @@ -90,13 +91,13 @@ private static Person createEditedPerson(Person personToEdit, Set tagsToAdd Address address = personToEdit.getAddress(); Set existingTags = personToEdit.getTags(); - for (Tag tag : tagsToAdd) { - if (existingTags.contains(tag)) { - oldTags.add(tag); - } else { - newTags.add(tag); - } - } + Set commonTags = new HashSet<>(existingTags); + commonTags.retainAll(tagsToAdd); + + oldTags.addAll(commonTags); + + newTags.addAll(tagsToAdd); + newTags.removeAll(existingTags); Set updatedTags = new HashSet<>(existingTags); updatedTags.addAll(tagsToAdd); @@ -109,22 +110,12 @@ public static String setToString(Set tags) { if (tags.isEmpty()) { return "-"; } else { - String tagString = tags.stream() + return tags.stream() .map(Tag::toString) .collect(Collectors.joining(", ")); - - return tagString; } } - public static Set getNewTags() { - return newTags; - } - - public static Set getOldTags() { - return oldTags; - } - @Override public boolean equals(Object other) { if (other == this) { diff --git a/src/main/java/seedu/address/logic/commands/AddTagTaskCommand.java b/src/main/java/seedu/address/logic/commands/AddTagTaskCommand.java index 4caa47a6dff..b066570ba24 100644 --- a/src/main/java/seedu/address/logic/commands/AddTagTaskCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddTagTaskCommand.java @@ -29,19 +29,20 @@ public class AddTagTaskCommand extends Command { public static final String SHORTENED_COMMAND_WORD = "atagt"; public static final String MESSAGE_USAGE = COMMAND_WORD + " (alias: " + SHORTENED_COMMAND_WORD + ")" - + ": Adds new tag to the task identified " + + ": Adds new tags to the task identified " + "by the index number used in the displayed task list. \n" + "Parameters: INDEX (must be a positive integer) " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " 1 " - + PREFIX_TAG + "class"; + + PREFIX_TAG + "class " + PREFIX_TAG + "finance"; public static final String MESSAGE_EDIT_TASK_SUCCESS = "Edited Task: %1$s \n" + "Successfully added these " + "tags: %2$s \n" + "These tags were not added as they already exists: %3$s"; - public static final String MESSAGE_DUPLICATE_TASK = "This task already exists in the address book."; - private static Set newTags = new HashSet<>(); - private static Set oldTags = new HashSet<>(); + // newTags stores those from tagsToAdd that are not already in taskToEdit's tags + private static Set newTags; + // oldTags stores those from tagsToAdd that are already in taskToEdit's tags + private static Set oldTags; private final Set tagsToAdd; private final Index index; @@ -88,13 +89,13 @@ private static Task createEditedTask(Task taskToEdit, Set tagsToAdd) { Status taskStatus = taskToEdit.getStatus(); Set existingTags = taskToEdit.getTags(); - for (Tag tag : tagsToAdd) { - if (existingTags.contains(tag)) { - oldTags.add(tag); - } else { - newTags.add(tag); - } - } + Set commonTags = new HashSet<>(existingTags); + commonTags.retainAll(tagsToAdd); + + oldTags.addAll(commonTags); + + newTags.addAll(tagsToAdd); + newTags.removeAll(existingTags); Set updatedTags = new HashSet<>(existingTags); updatedTags.addAll(tagsToAdd); @@ -107,22 +108,12 @@ public static String setToString(Set tags) { if (tags.isEmpty()) { return "-"; } else { - String tagString = tags.stream() + return tags.stream() .map(Tag::toString) .collect(Collectors.joining(", ")); - - return tagString; } } - public static Set getNewTags() { - return newTags; - } - - public static Set getOldTags() { - return oldTags; - } - @Override public boolean equals(Object other) { if (other == this) { diff --git a/src/main/java/seedu/address/logic/parser/AddTagPersonCommandParser.java b/src/main/java/seedu/address/logic/parser/AddTagPersonCommandParser.java index 632c7df0e19..70adb912637 100644 --- a/src/main/java/seedu/address/logic/parser/AddTagPersonCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddTagPersonCommandParser.java @@ -12,7 +12,7 @@ import seedu.address.model.tag.Tag; /** - * Parses input arguments and creates a new AddTagPersonCommand object + * Parses input arguments and creates a new AddTagPersonCommand object. */ public class AddTagPersonCommandParser implements Parser { @@ -37,7 +37,7 @@ public AddTagPersonCommand parse(String args) throws ParseException { Set tags = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); - if (tags.size() == 0) { + if (tags.isEmpty()) { throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddTagPersonCommand.MESSAGE_USAGE)); } diff --git a/src/main/java/seedu/address/logic/parser/AddTagTaskCommandParser.java b/src/main/java/seedu/address/logic/parser/AddTagTaskCommandParser.java index ef89ba4110e..4980d4b7e2e 100644 --- a/src/main/java/seedu/address/logic/parser/AddTagTaskCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/AddTagTaskCommandParser.java @@ -12,7 +12,7 @@ import seedu.address.model.tag.Tag; /** - * Parses input arguments and creates a new AddTagTaskCommand object + * Parses input arguments and creates a new AddTagTaskCommand object. */ public class AddTagTaskCommandParser implements Parser { @@ -37,7 +37,7 @@ public AddTagTaskCommand parse(String args) throws ParseException { Set tags = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG)); - if (tags.size() == 0) { + if (tags.isEmpty()) { throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddTagTaskCommand.MESSAGE_USAGE)); } diff --git a/src/test/java/seedu/address/logic/commands/AddTagPersonCommandTest.java b/src/test/java/seedu/address/logic/commands/AddTagPersonCommandTest.java index cbad3f54748..6947cb7724a 100644 --- a/src/test/java/seedu/address/logic/commands/AddTagPersonCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddTagPersonCommandTest.java @@ -47,13 +47,13 @@ public void execute_unfilteredList_success() { Set newTags = new HashSet<>(); Set oldTags = new HashSet<>(); - for (Tag t : tags) { - if (existingTags.contains(tag)) { - oldTags.add(t); - } else { - newTags.add(t); - } - } + Set commonTags = new HashSet<>(existingTags); + commonTags.retainAll(tags); + + oldTags.addAll(commonTags); + + newTags.addAll(tags); + newTags.removeAll(existingTags); Person editedPerson = new PersonBuilder(personToEdit).setTags(updatedTags).build(); @@ -97,13 +97,13 @@ public void execute_filteredList_success() { Set newTags = new HashSet<>(); Set oldTags = new HashSet<>(); - for (Tag t : tags) { - if (existingTags.contains(tag)) { - oldTags.add(t); - } else { - newTags.add(t); - } - } + Set commonTags = new HashSet<>(existingTags); + commonTags.retainAll(tags); + + oldTags.addAll(commonTags); + + newTags.addAll(tags); + newTags.removeAll(existingTags); Person editedPerson = new PersonBuilder(personToEdit).setTags(updatedTags).build(); @@ -142,6 +142,9 @@ public void equals() { AddTagPersonCommand addTagPersonCommand1 = new AddTagPersonCommand(INDEX_FIRST, tags); AddTagPersonCommand addTagPersonCommand2 = new AddTagPersonCommand(INDEX_FIRST, tags); + // Different object -> returns false + assertFalse(addTagPersonCommand1.equals(1)); + // Same values -> returns true assertTrue(addTagPersonCommand1.equals(addTagPersonCommand1)); assertTrue(addTagPersonCommand1.equals(addTagPersonCommand2)); diff --git a/src/test/java/seedu/address/logic/commands/AddTagTaskCommandTest.java b/src/test/java/seedu/address/logic/commands/AddTagTaskCommandTest.java index 881ee5f46d0..c1be4f4b132 100644 --- a/src/test/java/seedu/address/logic/commands/AddTagTaskCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddTagTaskCommandTest.java @@ -47,13 +47,13 @@ public void execute_unfilteredList_success() { Set newTags = new HashSet<>(); Set oldTags = new HashSet<>(); - for (Tag t : tags) { - if (existingTags.contains(tag)) { - oldTags.add(t); - } else { - newTags.add(t); - } - } + Set commonTags = new HashSet<>(existingTags); + commonTags.retainAll(tags); + + oldTags.addAll(commonTags); + + newTags.addAll(tags); + newTags.removeAll(existingTags); Task editedTask = new TaskBuilder(taskToEdit).setTags(updatedTags).build(); @@ -97,13 +97,13 @@ public void execute_filteredList_success() { Set newTags = new HashSet<>(); Set oldTags = new HashSet<>(); - for (Tag t : tags) { - if (existingTags.contains(tag)) { - oldTags.add(t); - } else { - newTags.add(t); - } - } + Set commonTags = new HashSet<>(existingTags); + commonTags.retainAll(tags); + + oldTags.addAll(commonTags); + + newTags.addAll(tags); + newTags.removeAll(existingTags); Task editedTask = new TaskBuilder(taskToEdit).setTags(updatedTags).build(); @@ -142,6 +142,9 @@ public void equals() { AddTagTaskCommand addTagTaskCommand1 = new AddTagTaskCommand(INDEX_FIRST, tags); AddTagTaskCommand addTagTaskCommand2 = new AddTagTaskCommand(INDEX_FIRST, tags); + // Different object -> returns false + assertFalse(addTagTaskCommand1.equals(1)); + // Same values -> returns true assertTrue(addTagTaskCommand1.equals(addTagTaskCommand1)); assertTrue(addTagTaskCommand1.equals(addTagTaskCommand2));