diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 4abb17e3e..6352cf32a 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -37,6 +37,7 @@ What's different from AddressBook-Level1: * Support for storing address (`a/`) and tags (`t/`) * Support for marking a contact detail as 'private' (`pa/`) (`pe/`) (`pp/`) * View details of a person (`view` : shows non-private details), (`viewall` : shows all details) +* View the list an updated list of people when adding someone using the AddAndListCommand == Viewing help : `help` @@ -182,4 +183,11 @@ The file name must end in `.txt` for it to be acceptable to the program. When running the program inside IntelliJ, you can set command line parameters before running the program. -==== + +==== Adding And Listing in the program: 'Add and List' + +This gives an updated list after adding a person. + +Format: 'AddAndList' + + + diff --git a/src/seedu/addressbook/commands/AddAndList.java b/src/seedu/addressbook/commands/AddAndList.java new file mode 100644 index 000000000..d0832d1a6 --- /dev/null +++ b/src/seedu/addressbook/commands/AddAndList.java @@ -0,0 +1,75 @@ +package seedu.addressbook.commands; + +import seedu.addressbook.data.exception.IllegalValueException; +import seedu.addressbook.data.person.*; +import seedu.addressbook.data.tag.Tag; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class AddAndList extends Command{ + + /** + * Adds a person to the address book. + */ + + public static final String COMMAND_WORD = "addAndList"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the address book, and see people already in it. " + + "Contact details can be marked private by prepending 'p' to the prefix.\n" + + "Parameters: NAME [p]p/PHONE [p]e/EMAIL [p]a/ADDRESS [t/TAG]...\n" + + "Example: " + COMMAND_WORD + + " John Doe p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25 t/friends t/owesMoney"; + + public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book"; + + private final Person toAdd; + + + /** + * Convenience constructor using raw values. + * + * @throws IllegalValueException if any of the raw values are invalid + */ + public AddAndList(String name, + String phone, boolean isPhonePrivate, + String email, boolean isEmailPrivate, + String address, boolean isAddressPrivate, + Set tags) throws IllegalValueException { + final Set tagSet = new HashSet<>(); + for (String tagName : tags) { + tagSet.add(new Tag(tagName)); + } + this.toAdd = new Person( + new Name(name), + new Phone(phone, isPhonePrivate), + new Email(email, isEmailPrivate), + new Address(address, isAddressPrivate), + tagSet + ); + } + + public AddAndList(Person toAdd) { + this.toAdd = toAdd; + } + + public ReadOnlyPerson getPerson() { + return toAdd; + } + + @Override + public CommandResult execute() { + try { + addressBook.addPerson(toAdd); + List allPersons = addressBook.getAllPersons().immutableListView(); + return new CommandResult(getMessageForPersonListShownSummary(allPersons), allPersons); + } catch (UniquePersonList.DuplicatePersonException dpe) { + return new CommandResult(MESSAGE_DUPLICATE_PERSON); + } + } + + } + + + diff --git a/src/seedu/addressbook/commands/AddCommand.java b/src/seedu/addressbook/commands/AddCommand.java index ac307f1b2..a18637223 100644 --- a/src/seedu/addressbook/commands/AddCommand.java +++ b/src/seedu/addressbook/commands/AddCommand.java @@ -1,18 +1,12 @@ package seedu.addressbook.commands; -import java.util.HashSet; -import java.util.Set; - import seedu.addressbook.data.exception.IllegalValueException; -import seedu.addressbook.data.person.Address; -import seedu.addressbook.data.person.Email; -import seedu.addressbook.data.person.Name; -import seedu.addressbook.data.person.Person; -import seedu.addressbook.data.person.Phone; -import seedu.addressbook.data.person.ReadOnlyPerson; -import seedu.addressbook.data.person.UniquePersonList; +import seedu.addressbook.data.person.*; import seedu.addressbook.data.tag.Tag; +import java.util.HashSet; +import java.util.Set; + /** * Adds a person to the address book. */ @@ -31,6 +25,7 @@ public class AddCommand extends Command { private final Person toAdd; + /** * Convenience constructor using raw values. * diff --git a/src/seedu/addressbook/data/AddressBook.java b/src/seedu/addressbook/data/AddressBook.java index 537d35c89..82974ce69 100644 --- a/src/seedu/addressbook/data/AddressBook.java +++ b/src/seedu/addressbook/data/AddressBook.java @@ -38,6 +38,7 @@ public void addPerson(Person toAdd) throws DuplicatePersonException { allPersons.add(toAdd); } + /** * Returns true if an equivalent person exists in the address book. */ diff --git a/src/seedu/addressbook/parser/Parser.java b/src/seedu/addressbook/parser/Parser.java index abddb3f45..fbdcfe323 100644 --- a/src/seedu/addressbook/parser/Parser.java +++ b/src/seedu/addressbook/parser/Parser.java @@ -1,28 +1,14 @@ package seedu.addressbook.parser; -import static seedu.addressbook.common.Messages.MESSAGE_INVALID_COMMAND_FORMAT; -import static seedu.addressbook.common.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; +import seedu.addressbook.commands.*; +import seedu.addressbook.data.exception.IllegalValueException; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -import seedu.addressbook.commands.AddCommand; -import seedu.addressbook.commands.ClearCommand; -import seedu.addressbook.commands.Command; -import seedu.addressbook.commands.DeleteCommand; -import seedu.addressbook.commands.ExitCommand; -import seedu.addressbook.commands.FindCommand; -import seedu.addressbook.commands.HelpCommand; -import seedu.addressbook.commands.IncorrectCommand; -import seedu.addressbook.commands.ListCommand; -import seedu.addressbook.commands.ViewAllCommand; -import seedu.addressbook.commands.ViewCommand; -import seedu.addressbook.data.exception.IllegalValueException; +import static seedu.addressbook.common.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static seedu.addressbook.common.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; /** * Parses user input. @@ -76,6 +62,9 @@ public Command parseCommand(String userInput) { case AddCommand.COMMAND_WORD: return prepareAdd(arguments); + case AddAndList.COMMAND_WORD: + return prepareAddAndList(arguments); + case DeleteCommand.COMMAND_WORD: return prepareDelete(arguments); @@ -135,6 +124,32 @@ private Command prepareAdd(String args) { } } + private Command prepareAddAndList(String args) { + final Matcher matcher = PERSON_DATA_ARGS_FORMAT.matcher(args.trim()); + // Validate arg string format + if (!matcher.matches()) { + return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddAndList.MESSAGE_USAGE)); + } + try { + return new AddAndList( + matcher.group("name"), + + matcher.group("phone"), + isPrivatePrefixPresent(matcher.group("isPhonePrivate")), + + matcher.group("email"), + isPrivatePrefixPresent(matcher.group("isEmailPrivate")), + + matcher.group("address"), + isPrivatePrefixPresent(matcher.group("isAddressPrivate")), + + getTagsFromArgs(matcher.group("tagArguments")) + ); + } catch (IllegalValueException ive) { + return new IncorrectCommand(ive.getMessage()); + } + } + /** * Returns true if the private prefix is present for a contact detail in the add command's arguments string. */ diff --git a/test/java/seedu/addressbook/commands/AndAndListTest.java b/test/java/seedu/addressbook/commands/AndAndListTest.java new file mode 100644 index 000000000..e9700c300 --- /dev/null +++ b/test/java/seedu/addressbook/commands/AndAndListTest.java @@ -0,0 +1,139 @@ + + +package seedu.addressbook.commands; + +import org.junit.Test; +import seedu.addressbook.data.AddressBook; +import seedu.addressbook.data.exception.IllegalValueException; +import seedu.addressbook.data.person.*; +import seedu.addressbook.util.TestUtil; + +import java.util.*; + +import static org.junit.Assert.*; + +public class AndAndListTest { + + + + private static final List EMPTY_PERSON_LIST = Collections.emptyList(); + private static final Set EMPTY_STRING_SET = Collections.emptySet(); + + @Test + public void addAndList_invalidName_throwsException() { + final String[] invalidNames = { "", " ", "[]\\[;]" }; + for (String name : invalidNames) { + assertConstructingInvalidAddCmdThrowsException(name, Phone.EXAMPLE, true, Email.EXAMPLE, false, + Address.EXAMPLE, true, EMPTY_STRING_SET); + } + } + + @Test + public void addAndList_invalidPhone_throwsException() { + final String[] invalidNumbers = { "", " ", "1234-5678", "[]\\[;]", "abc", "a123", "+651234" }; + for (String number : invalidNumbers) { + assertConstructingInvalidAddCmdThrowsException(Name.EXAMPLE, number, false, Email.EXAMPLE, true, + Address.EXAMPLE, false, EMPTY_STRING_SET); + } + } + + @Test + public void addAndList_invalidEmail_throwsException() { + final String[] invalidEmails = { "", " ", "def.com", "@", "@def", "@def.com", "abc@", + "@invalid@email", "invalid@email!", "!invalid@email" }; + for (String email : invalidEmails) { + assertConstructingInvalidAddCmdThrowsException(Name.EXAMPLE, Phone.EXAMPLE, false, email, false, + Address.EXAMPLE, false, EMPTY_STRING_SET); + } + } + + @Test + public void addAndList_invalidAddress_throwsException() { + final String[] invalidAddresses = { "", " " }; + for (String address : invalidAddresses) { + assertConstructingInvalidAddCmdThrowsException(Name.EXAMPLE, Phone.EXAMPLE, true, Email.EXAMPLE, + true, address, true, EMPTY_STRING_SET); + } + } + + @Test + public void addAndList_invalidTags_throwsException() { + final String[][] invalidTags = { { "" }, { " " }, { "'" }, { "[]\\[;]" }, { "validTag", "" }, + { "", " " } }; + for (String[] tags : invalidTags) { + Set tagsToAdd = new HashSet<>(Arrays.asList(tags)); + assertConstructingInvalidAddCmdThrowsException(Name.EXAMPLE, Phone.EXAMPLE, true, Email.EXAMPLE, + true, Address.EXAMPLE, false, tagsToAdd); + } + } + + /** + * Asserts that attempting to construct an add command with the supplied + * invalid data throws an IllegalValueException + */ + private void assertConstructingInvalidAddCmdThrowsException(String name, String phone, + boolean isPhonePrivate, String email, boolean isEmailPrivate, String address, + boolean isAddressPrivate, Set tags) { + try { + new AddCommand(name, phone, isPhonePrivate, email, isEmailPrivate, address, isAddressPrivate, + tags); + } catch (IllegalValueException e) { + return; + } + String error = String.format( + "An add command was successfully constructed with invalid input: %s %s %s %s %s %s %s %s", + name, phone, isPhonePrivate, email, isEmailPrivate, address, isAddressPrivate, tags); + fail(error); + } + + @Test + public void addAndList_validData_correctlyConstructed() throws Exception { + AddCommand command = new AddCommand(Name.EXAMPLE, Phone.EXAMPLE, true, Email.EXAMPLE, false, + Address.EXAMPLE, true, EMPTY_STRING_SET); + ReadOnlyPerson p = command.getPerson(); + + // TODO: add comparison of tags to person.equals and equality methods to + // individual fields that compare privacy to simplify this + assertEquals(Name.EXAMPLE, p.getName().fullName); + assertEquals(Phone.EXAMPLE, p.getPhone().value); + assertTrue(p.getPhone().isPrivate()); + assertEquals(Email.EXAMPLE, p.getEmail().value); + assertFalse(p.getEmail().isPrivate()); + assertEquals(Address.EXAMPLE, p.getAddress().value); + assertTrue(p.getAddress().isPrivate()); + boolean isTagListEmpty = !p.getTags().iterator().hasNext(); + assertTrue(isTagListEmpty); + } + + @Test + public void addAndList_emptyAddressBook_addressBookContainsPerson() { + Person p = TestUtil.generateTestPerson(); + AddCommand command = new AddCommand(p); + AddressBook book = new AddressBook(); + command.setData(book, EMPTY_PERSON_LIST); + CommandResult result = command.execute(); + UniquePersonList people = book.getAllPersons(); + + assertTrue(people.contains(p)); + assertEquals(1, people.immutableListView().size()); + assertFalse(result.getRelevantPersons().isPresent()); + assertEquals(String.format(AddCommand.MESSAGE_SUCCESS, p), result.feedbackToUser); + } + + @Test + public void addAndList_addressBookAlreadyContainsPerson_addressBookUnmodified() throws Exception { + Person p = TestUtil.generateTestPerson(); + AddressBook book = new AddressBook(); + book.addPerson(p); + AddCommand command = new AddCommand(p); + command.setData(book, EMPTY_PERSON_LIST); + CommandResult result = command.execute(); + + assertFalse(result.getRelevantPersons().isPresent()); + assertEquals(AddCommand.MESSAGE_DUPLICATE_PERSON, result.feedbackToUser); + UniquePersonList people = book.getAllPersons(); + assertTrue(people.contains(p)); + assertEquals(1, people.immutableListView().size()); + } + } +