Skip to content

Commit

Permalink
Merge pull request nus-cs2103-AY2021S1#80 from royleochan/branch-Dele…
Browse files Browse the repository at this point in the history
…te-Contact

Make contact names unique and change delete to delete by name instead of index
  • Loading branch information
jerrylchong authored Oct 6, 2020
2 parents 0fa35de + 5dd07d8 commit e622ef3
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 43 deletions.
1 change: 1 addition & 0 deletions src/main/java/seedu/address/commons/core/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ 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 = "The person provided is not in your contacts";
public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid";
public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!";

Expand Down
29 changes: 16 additions & 13 deletions src/main/java/seedu/address/logic/commands/DeleteCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,46 @@
import static java.util.Objects.requireNonNull;

import java.util.List;
import java.util.stream.Collectors;

import seedu.address.commons.core.Messages;
import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.person.Name;
import seedu.address.model.person.Person;

/**
* Deletes a person identified using it's displayed index from the address book.
*/
public class DeleteCommand extends Command {

public static final String COMMAND_WORD = "delete";
public static final String COMMAND_WORD = "contact delete";

public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Deletes the person identified by the index number used in the displayed person list.\n"
+ "Parameters: INDEX (must be a positive integer)\n"
+ "Example: " + COMMAND_WORD + " 1";
+ ": Deletes the person identified by the name used in the displayed person list.\n"
+ "Parameters: NAME (must be a valid name)\n"
+ "Example: " + COMMAND_WORD + " Roy";

public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s";

private final Index targetIndex;
private final Name targetName;

public DeleteCommand(Index targetIndex) {
this.targetIndex = targetIndex;
public DeleteCommand(Name targetName) {
this.targetName = targetName;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Person> lastShownList = model.getFilteredPersonList();
boolean isValidContact = model.hasPersonName(targetName);

if (targetIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
if (!isValidContact) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED);
}

Person personToDelete = lastShownList.get(targetIndex.getZeroBased());
List<Person> filteredList = model.getFilteredPersonList().stream()
.filter(person -> person.isSameName(targetName)).collect(Collectors.toList());
Person personToDelete = filteredList.get(0);
model.deletePerson(personToDelete);
return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, personToDelete));
}
Expand All @@ -48,6 +51,6 @@ public CommandResult execute(Model model) throws CommandException {
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof DeleteCommand // instanceof handles nulls
&& targetIndex.equals(((DeleteCommand) other).targetIndex)); // state check
&& targetName.equals(((DeleteCommand) other).targetName)); // state check
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;

import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.DeleteCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.Name;

/**
* Parses input arguments and creates a new DeleteCommand object
Expand All @@ -18,8 +18,8 @@ public class DeleteCommandParser implements Parser<DeleteCommand> {
*/
public DeleteCommand parse(String args) throws ParseException {
try {
Index index = ParserUtil.parseIndex(args);
return new DeleteCommand(index);
Name targetName = ParserUtil.parseName(args);
return new DeleteCommand(targetName);
} catch (ParseException pe) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE), pe);
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/seedu/address/model/AddressBook.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import java.util.List;

import javafx.collections.ObservableList;
import seedu.address.model.person.Name;
import seedu.address.model.person.Person;
import seedu.address.model.person.UniquePersonList;


/**
* Wraps all data at the address-book level
* Duplicates are not allowed (by .isSamePerson comparison)
Expand Down Expand Up @@ -66,6 +68,14 @@ public boolean hasPerson(Person person) {
return persons.contains(person);
}

/**
* Returns true if a person with the same name as {@code person} exists in the address book.
*/
public boolean hasPersonName(Name name) {
requireNonNull(name);
return persons.contains(name);
}

/**
* Adds a person to the address book.
* The person must not already exist in the address book.
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.model.person.Name;
import seedu.address.model.person.Person;

/**
Expand Down Expand Up @@ -57,6 +58,11 @@ public interface Model {
*/
boolean hasPerson(Person person);

/**
* Returns true if a person with the same name as {@code person} exists in the address book.
*/
boolean hasPersonName(Name name);

/**
* Deletes the given person.
* The person must exist in the address book.
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import javafx.collections.transformation.FilteredList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.commons.core.LogsCenter;
import seedu.address.model.person.Name;
import seedu.address.model.person.Person;

/**
Expand Down Expand Up @@ -94,6 +95,12 @@ public boolean hasPerson(Person person) {
return addressBook.hasPerson(person);
}

@Override
public boolean hasPersonName(Name name) {
requireNonNull(name);
return addressBook.hasPersonName(name);
}

@Override
public void deletePerson(Person target) {
addressBook.removePerson(target);
Expand Down
13 changes: 9 additions & 4 deletions src/main/java/seedu/address/model/person/Person.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,22 @@ public Set<Tag> getTags() {
}

/**
* Returns true if both persons of the same name have at least one other identity field that is the same.
* This defines a weaker notion of equality between two persons.
* Returns true if both persons have the same name.
*/
public boolean isSamePerson(Person otherPerson) {
if (otherPerson == this) {
return true;
}

return otherPerson != null
&& otherPerson.getName().equals(getName())
&& (otherPerson.getPhone().equals(getPhone()) || otherPerson.getEmail().equals(getEmail()));
&& otherPerson.getName().equals(getName());
}

/**
* Returns true if both persons have the same name.
*/
public boolean isSameName(Name otherName) {
return name.equals(otherName);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ public boolean contains(Person toCheck) {
return internalList.stream().anyMatch(toCheck::isSamePerson);
}

/**
* Returns true if the list contains a person with the same name.
*/
public boolean contains(Name toCheck) {
requireNonNull(toCheck);
return internalList.stream().anyMatch(person -> person.isSameName(toCheck));
}

/**
* Adds a person to the list.
* The person must not already exist in the list.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import seedu.address.model.Model;
import seedu.address.model.ReadOnlyAddressBook;
import seedu.address.model.ReadOnlyUserPrefs;
import seedu.address.model.person.Name;
import seedu.address.model.person.Person;
import seedu.address.testutil.PersonBuilder;

Expand Down Expand Up @@ -128,6 +129,11 @@ public boolean hasPerson(Person person) {
throw new AssertionError("This method should not be called.");
}

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

@Override
public void deletePerson(Person target) {
throw new AssertionError("This method should not be called.");
Expand Down
30 changes: 16 additions & 14 deletions src/test/java/seedu/address/logic/commands/DeleteCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex;
import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
import static seedu.address.testutil.TypicalPersons.ALICE;
import static seedu.address.testutil.TypicalPersons.BOB;
import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;

import org.junit.jupiter.api.Test;
Expand All @@ -16,6 +18,7 @@
import seedu.address.model.Model;
import seedu.address.model.ModelManager;
import seedu.address.model.UserPrefs;
import seedu.address.model.person.Name;
import seedu.address.model.person.Person;

/**
Expand All @@ -27,9 +30,9 @@ public class DeleteCommandTest {
private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());

@Test
public void execute_validIndexUnfilteredList_success() {
public void execute_validNameUnfilteredList_success() {
Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_PERSON);
DeleteCommand deleteCommand = new DeleteCommand(personToDelete.getName());

String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, personToDelete);

Expand All @@ -40,19 +43,18 @@ public void execute_validIndexUnfilteredList_success() {
}

@Test
public void execute_invalidIndexUnfilteredList_throwsCommandException() {
Index outOfBoundIndex = Index.fromOneBased(model.getFilteredPersonList().size() + 1);
DeleteCommand deleteCommand = new DeleteCommand(outOfBoundIndex);
public void execute_invalidNameUnfilteredList_throwsCommandException() {
DeleteCommand deleteCommand = new DeleteCommand(new Name("123"));

assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED);
}

@Test
public void execute_validIndexFilteredList_success() {
public void execute_validNameFilteredList_success() {
showPersonAtIndex(model, INDEX_FIRST_PERSON);

Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_PERSON);
DeleteCommand deleteCommand = new DeleteCommand(personToDelete.getName());

String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, personToDelete);

Expand All @@ -64,28 +66,28 @@ public void execute_validIndexFilteredList_success() {
}

@Test
public void execute_invalidIndexFilteredList_throwsCommandException() {
public void execute_invalidNameFilteredList_throwsCommandException() {
showPersonAtIndex(model, INDEX_FIRST_PERSON);

Index outOfBoundIndex = INDEX_SECOND_PERSON;
// ensures that outOfBoundIndex is still in bounds of address book list
assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size());

DeleteCommand deleteCommand = new DeleteCommand(outOfBoundIndex);
DeleteCommand deleteCommand = new DeleteCommand(new Name("123"));

assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
assertCommandFailure(deleteCommand, model, Messages.MESSAGE_INVALID_PERSON_DISPLAYED);
}

@Test
public void equals() {
DeleteCommand deleteFirstCommand = new DeleteCommand(INDEX_FIRST_PERSON);
DeleteCommand deleteSecondCommand = new DeleteCommand(INDEX_SECOND_PERSON);
DeleteCommand deleteFirstCommand = new DeleteCommand(ALICE.getName());
DeleteCommand deleteSecondCommand = new DeleteCommand(BOB.getName());

// same object -> returns true
assertTrue(deleteFirstCommand.equals(deleteFirstCommand));

// same values -> returns true
DeleteCommand deleteFirstCommandCopy = new DeleteCommand(INDEX_FIRST_PERSON);
DeleteCommand deleteFirstCommandCopy = new DeleteCommand(ALICE.getName());
assertTrue(deleteFirstCommand.equals(deleteFirstCommandCopy));

// different types -> returns false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
import static seedu.address.testutil.TypicalPersons.ALICE;

import org.junit.jupiter.api.Test;

Expand All @@ -22,11 +22,11 @@ public class DeleteCommandParserTest {

@Test
public void parse_validArgs_returnsDeleteCommand() {
assertParseSuccess(parser, "1", new DeleteCommand(INDEX_FIRST_PERSON));
assertParseSuccess(parser, "Alice Pauline", new DeleteCommand(ALICE.getName()));
}

@Test
public void parse_invalidArgs_throwsParseException() {
assertParseFailure(parser, "a", String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE));
assertParseFailure(parser, "", String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE));
}
}
4 changes: 2 additions & 2 deletions src/test/java/seedu/address/model/person/PersonTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ public void isSamePerson() {
// null -> returns false
assertFalse(ALICE.isSamePerson(null));

// different phone and email -> returns false
// different phone and email but same name -> returns true
Person editedAlice = new PersonBuilder(ALICE).withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB).build();
assertFalse(ALICE.isSamePerson(editedAlice));
assertTrue(ALICE.isSamePerson(editedAlice));

// different name -> returns false
editedAlice = new PersonBuilder(ALICE).withName(VALID_NAME_BOB).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ public class UniquePersonListTest {

private final UniquePersonList uniquePersonList = new UniquePersonList();

@Test
public void contains_nullName_throwsNullPointerException() {
assertThrows(NullPointerException.class, () -> uniquePersonList.contains((Name) null));
}

@Test
public void contains_nullPerson_throwsNullPointerException() {
assertThrows(NullPointerException.class, () -> uniquePersonList.contains(null));
assertThrows(NullPointerException.class, () -> uniquePersonList.contains((Person) null));
}

@Test
Expand Down
5 changes: 2 additions & 3 deletions src/test/java/seedu/address/testutil/PersonBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
*/
public class PersonBuilder {

public static final String DEFAULT_NAME = "Alice Pauline";
public static final String DEFAULT_NAME = "Sally Toh";
public static final String DEFAULT_PHONE = "85355255";
public static final String DEFAULT_EMAIL = "[email protected]";
public static final String DEFAULT_ADDRESS = "123, Jurong West Ave 6, #08-111";
public static final String DEFAULT_EMAIL = "[email protected]";

private Name name;
private Phone phone;
Expand Down

0 comments on commit e622ef3

Please sign in to comment.