From 68054bcca5e0163b6ead7f1064b5cf0b1c71fce1 Mon Sep 17 00:00:00 2001 From: Adam Chew Date: Thu, 13 Sep 2018 21:49:47 +0800 Subject: [PATCH 1/5] Add sort feature --- .../addressbook/commands/SortCommand.java | 48 +++++++++++++++++++ src/seedu/addressbook/common/Messages.java | 1 + src/seedu/addressbook/data/AddressBook.java | 6 +++ .../data/person/UniquePersonList.java | 5 ++ src/seedu/addressbook/parser/Parser.java | 15 ++---- .../seedu/addressbook/common/UtilsTest.java | 13 +++++ 6 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 src/seedu/addressbook/commands/SortCommand.java diff --git a/src/seedu/addressbook/commands/SortCommand.java b/src/seedu/addressbook/commands/SortCommand.java new file mode 100644 index 000000000..234bde666 --- /dev/null +++ b/src/seedu/addressbook/commands/SortCommand.java @@ -0,0 +1,48 @@ +package seedu.addressbook.commands; + +import seedu.addressbook.common.Messages; +import seedu.addressbook.data.person.ReadOnlyPerson; + +import java.security.InvalidParameterException; +import java.util.List; + + +/** + * Lists all persons in the address book to the user. + */ +public class SortCommand extends Command { + + public static final String COMMAND_WORD = "sort"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Sorts all persons in the address book according to the specifier (name, phone, email, address) and " + + "display in a sorted list.\n" + + "Example: " + COMMAND_WORD + " address"; + + private final String keyword; + + public SortCommand(String keyword) { + this.keyword = keyword; + } + + @Override + public CommandResult execute() { + try { + System.out.println("keyword: $" + keyword); + addressBook.sort((ReadOnlyPerson p1, ReadOnlyPerson p2) -> { + switch (keyword) { + case " name": return p1.getName().toString().compareTo(p2.getName().toString()); + case " phone": return p1.getPhone().toString().compareTo(p2.getPhone().toString()); + case " email": return p1.getEmail().toString().compareTo(p2.getEmail().toString()); + case " address": return p1.getAddress().toString().compareTo(p2.getAddress().toString()); + default: + throw new InvalidParameterException(); + } + }); + List allPersons = addressBook.getAllPersons().immutableListView(); + return new CommandResult(getMessageForPersonListShownSummary(allPersons), allPersons); + } catch (InvalidParameterException e) { + return new CommandResult(Messages.MESSAGE_INVALID_SORT); + } + } +} \ No newline at end of file diff --git a/src/seedu/addressbook/common/Messages.java b/src/seedu/addressbook/common/Messages.java index 9e30d0f28..ca1b4bd81 100644 --- a/src/seedu/addressbook/common/Messages.java +++ b/src/seedu/addressbook/common/Messages.java @@ -15,4 +15,5 @@ public class Messages { "java seedu.addressbook.Main [STORAGE_FILE_PATH]"; public static final String MESSAGE_WELCOME = "Welcome to your Address Book!"; public static final String MESSAGE_USING_STORAGE_FILE = "Using storage file : %1$s"; + public static final String MESSAGE_INVALID_SORT = "Keyword is invalid."; } diff --git a/src/seedu/addressbook/data/AddressBook.java b/src/seedu/addressbook/data/AddressBook.java index 537d35c89..511346c3d 100644 --- a/src/seedu/addressbook/data/AddressBook.java +++ b/src/seedu/addressbook/data/AddressBook.java @@ -1,5 +1,7 @@ package seedu.addressbook.data; +import java.util.Comparator; + import seedu.addressbook.data.person.Person; import seedu.addressbook.data.person.ReadOnlyPerson; import seedu.addressbook.data.person.UniquePersonList; @@ -67,6 +69,10 @@ public void clear() { public UniquePersonList getAllPersons() { return new UniquePersonList(allPersons); } + + public void sort(Comparator comparator) { + allPersons.sort(comparator); + } @Override public boolean equals(Object other) { diff --git a/src/seedu/addressbook/data/person/UniquePersonList.java b/src/seedu/addressbook/data/person/UniquePersonList.java index d7acd8b4a..22330ec83 100644 --- a/src/seedu/addressbook/data/person/UniquePersonList.java +++ b/src/seedu/addressbook/data/person/UniquePersonList.java @@ -6,6 +6,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Comparator; import seedu.addressbook.common.Utils; import seedu.addressbook.data.exception.DuplicateDataException; @@ -140,4 +141,8 @@ public boolean equals(Object other) { || (other instanceof UniquePersonList // instanceof handles nulls && this.internalList.equals(((UniquePersonList) other).internalList)); } + + public void sort(Comparator comparator) { + internalList.sort(comparator); + } } diff --git a/src/seedu/addressbook/parser/Parser.java b/src/seedu/addressbook/parser/Parser.java index abddb3f45..5263489d7 100644 --- a/src/seedu/addressbook/parser/Parser.java +++ b/src/seedu/addressbook/parser/Parser.java @@ -11,17 +11,7 @@ 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.commands.*; import seedu.addressbook.data.exception.IllegalValueException; /** @@ -96,6 +86,9 @@ public Command parseCommand(String userInput) { case ExitCommand.COMMAND_WORD: return new ExitCommand(); + + case SortCommand.COMMAND_WORD: + return new SortCommand(arguments); case HelpCommand.COMMAND_WORD: // Fallthrough default: diff --git a/test/java/seedu/addressbook/common/UtilsTest.java b/test/java/seedu/addressbook/common/UtilsTest.java index 23ea62b45..3410de514 100644 --- a/test/java/seedu/addressbook/common/UtilsTest.java +++ b/test/java/seedu/addressbook/common/UtilsTest.java @@ -34,6 +34,15 @@ public void elementsAreUnique() throws Exception { assertNotUnique(null, 1, Integer.valueOf(1)); assertNotUnique(null, null); assertNotUnique(null, "a", "b", null); + + // some empty objects + assertAnyNull(1, 2, null); + assertAnyNull(null); + + // non-empty objects + assertAnyNull(1, 2, 3); + assertAnyNull("a", "b", "c"); + } private void assertAreUnique(Object... objects) { @@ -43,4 +52,8 @@ private void assertAreUnique(Object... objects) { private void assertNotUnique(Object... objects) { assertFalse(Utils.elementsAreUnique(Arrays.asList(objects))); } + + private void assertAnyNull(Object... objects) { + assertTrue(Utils.isAnyNull(objects)); + } } From 9ef3c3c6e7a8aedca18170f1424c445498a38e98 Mon Sep 17 00:00:00 2001 From: Adam Chew Date: Thu, 13 Sep 2018 22:30:05 +0800 Subject: [PATCH 2/5] Add junit tests for sort command --- .../addressbook/commands/SortCommand.java | 11 ++-- src/seedu/addressbook/common/Utils.java | 3 + .../addressbook/commands/SortCommandTest.java | 60 +++++++++++++++++++ .../seedu/addressbook/common/UtilsTest.java | 8 ++- .../addressbook/util/TypicalPersons.java | 4 +- 5 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 test/java/seedu/addressbook/commands/SortCommandTest.java diff --git a/src/seedu/addressbook/commands/SortCommand.java b/src/seedu/addressbook/commands/SortCommand.java index 234bde666..fade8e3aa 100644 --- a/src/seedu/addressbook/commands/SortCommand.java +++ b/src/seedu/addressbook/commands/SortCommand.java @@ -22,19 +22,18 @@ public class SortCommand extends Command { private final String keyword; public SortCommand(String keyword) { - this.keyword = keyword; + this.keyword = keyword.trim(); } @Override public CommandResult execute() { try { - System.out.println("keyword: $" + keyword); addressBook.sort((ReadOnlyPerson p1, ReadOnlyPerson p2) -> { switch (keyword) { - case " name": return p1.getName().toString().compareTo(p2.getName().toString()); - case " phone": return p1.getPhone().toString().compareTo(p2.getPhone().toString()); - case " email": return p1.getEmail().toString().compareTo(p2.getEmail().toString()); - case " address": return p1.getAddress().toString().compareTo(p2.getAddress().toString()); + case "name": return p1.getName().toString().compareTo(p2.getName().toString()); + case "phone": return p1.getPhone().toString().compareTo(p2.getPhone().toString()); + case "email": return p1.getEmail().toString().compareTo(p2.getEmail().toString()); + case "address": return p1.getAddress().toString().compareTo(p2.getAddress().toString()); default: throw new InvalidParameterException(); } diff --git a/src/seedu/addressbook/common/Utils.java b/src/seedu/addressbook/common/Utils.java index 23cc9def3..1e6a4b920 100644 --- a/src/seedu/addressbook/common/Utils.java +++ b/src/seedu/addressbook/common/Utils.java @@ -13,6 +13,9 @@ public class Utils { * Returns true if any of the given items are null. */ public static boolean isAnyNull(Object... items) { + if (items == null) { + return true; + } for (Object item : items) { if (item == null) { return true; diff --git a/test/java/seedu/addressbook/commands/SortCommandTest.java b/test/java/seedu/addressbook/commands/SortCommandTest.java new file mode 100644 index 000000000..7bf3de0fb --- /dev/null +++ b/test/java/seedu/addressbook/commands/SortCommandTest.java @@ -0,0 +1,60 @@ +package seedu.addressbook.commands; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.junit.Test; + +import seedu.addressbook.common.Messages; +import seedu.addressbook.data.AddressBook; +import seedu.addressbook.data.exception.IllegalValueException; +import seedu.addressbook.data.person.ReadOnlyPerson; +import seedu.addressbook.util.TypicalPersons; + +public class SortCommandTest { + + private final AddressBook addressBook = new TypicalPersons().getTypicalAddressBook(); + private final TypicalPersons td = new TypicalPersons(); + + @Test + public void execute() throws IllegalValueException { + //sort by valid keyword + assertSortCommandBehavior("phone", Arrays.asList( td.dan, td.amy, td.bill, td.candy)); + assertSortCommandBehavior("address", Arrays.asList(td.amy, td.dan, td.bill, td.candy)); + + //sort by invalid keyword + assertSortCommandBehavior("emale", Messages.MESSAGE_INVALID_SORT); + assertSortCommandBehavior("Name", Messages.MESSAGE_INVALID_SORT); + } + + /** + * Executes the sort command for the given keywords and verifies + * the result matches the persons in the expectedPersonList exactly. + */ + private void assertSortCommandBehavior(String keyword, List expectedPersonList) { + SortCommand command = createSortCommand(keyword); + CommandResult result = command.execute(); + + assertEquals(Command.getMessageForPersonListShownSummary(expectedPersonList), result.feedbackToUser); + } + + private void assertSortCommandBehavior(String keyword, String errorMessage) { + SortCommand command = createSortCommand(keyword); + CommandResult result = command.execute(); + System.out.println(result.feedbackToUser); + + assertEquals(errorMessage, result.feedbackToUser); + } + + private SortCommand createSortCommand(String keyword) { + SortCommand command = new SortCommand(keyword); + command.setData(addressBook, Collections.emptyList()); + return command; + } + +} diff --git a/test/java/seedu/addressbook/common/UtilsTest.java b/test/java/seedu/addressbook/common/UtilsTest.java index 3410de514..196682068 100644 --- a/test/java/seedu/addressbook/common/UtilsTest.java +++ b/test/java/seedu/addressbook/common/UtilsTest.java @@ -40,8 +40,8 @@ public void elementsAreUnique() throws Exception { assertAnyNull(null); // non-empty objects - assertAnyNull(1, 2, 3); - assertAnyNull("a", "b", "c"); + assertNoneNull(1, 2, 3); + assertNoneNull("a", "b", "c"); } @@ -56,4 +56,8 @@ private void assertNotUnique(Object... objects) { private void assertAnyNull(Object... objects) { assertTrue(Utils.isAnyNull(objects)); } + + private void assertNoneNull(Object... objects) { + assertFalse(Utils.isAnyNull(objects)); + } } diff --git a/test/java/seedu/addressbook/util/TypicalPersons.java b/test/java/seedu/addressbook/util/TypicalPersons.java index cd3a3f819..690baed41 100644 --- a/test/java/seedu/addressbook/util/TypicalPersons.java +++ b/test/java/seedu/addressbook/util/TypicalPersons.java @@ -16,7 +16,7 @@ */ public class TypicalPersons { - public Person amy, bill, candy, dan; + public Person amy, bill, candy, dan, emily; public TypicalPersons() { try { @@ -27,7 +27,7 @@ public TypicalPersons() { candy = new Person(new Name("Candy Destiny"), new Phone("93339333", true), new Email("cd@gmail.com", false), new Address("3 Clementi Road", true), Collections.emptySet()); dan = new Person(new Name("Dan Smith"), new Phone("1234556", true), new Email("ss@tt.com", true), - new Address("NUS", true), Collections.singleton(new Tag("test"))); + new Address("2 Ang Mo Kio", true), Collections.singleton(new Tag("test"))); } catch (IllegalValueException e) { e.printStackTrace(); assert false : "not possible"; From a275d905e47a66cfae67a1543a0b0dee723c7220 Mon Sep 17 00:00:00 2001 From: Adam Chew Date: Thu, 13 Sep 2018 22:36:34 +0800 Subject: [PATCH 3/5] Update I/O tests --- test/expected.txt | 67 +++++++++++++++++++++++++++++++++++++++++++++++ test/input.txt | 28 ++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/test/expected.txt b/test/expected.txt index 56fe5fcac..bd44bef62 100644 --- a/test/expected.txt +++ b/test/expected.txt @@ -297,6 +297,73 @@ || || 0 persons listed! || =================================================== +|| Enter command: || [Command entered: add Adam Brown p/111111 e/adam@gmail.com a/111, alpha street] +|| New person added: Adam Brown Phone: 111111 Email: adam@gmail.com Address: 111, alpha street Tags: +|| =================================================== +|| Enter command: || [Command entered: add Betsy Choo pp/222222 pe/benchoo@nus.edu.sg pa/222, beta street t/secretive] +|| New person added: Betsy Choo Phone: (private) 222222 Email: (private) benchoo@nus.edu.sg Address: (private) 222, beta street Tags: [secretive] +|| =================================================== +|| Enter command: || [Command entered: add Charlie Dickson pp/333333 e/charlie.d@nus.edu.sg a/333, gamma street t/friends t/school] +|| New person added: Charlie Dickson Phone: (private) 333333 Email: charlie.d@nus.edu.sg Address: 333, gamma street Tags: [school][friends] +|| =================================================== +|| Enter command: || [Command entered: add Dickson Ee p/444444 pe/dickson@nus.edu.sg a/444, delta street t/friends] +|| New person added: Dickson Ee Phone: 444444 Email: (private) dickson@nus.edu.sg Address: 444, delta street Tags: [friends] +|| =================================================== +|| Enter command: || [Command entered: add Esther Potato p/155555 e/aesther@not.a.real.potato pa/355, epsilon street t/tubers t/starchy] +|| New person added: Esther Potato Phone: 155555 Email: aesther@not.a.real.potato Address: (private) 355, epsilon street Tags: [tubers][starchy] +|| =================================================== +|| Enter command: || [Command entered: list] +|| 1. Adam Brown Phone: 111111 Email: adam@gmail.com Address: 111, alpha street Tags: +|| 2. Betsy Choo Tags: [secretive] +|| 3. Charlie Dickson Email: charlie.d@nus.edu.sg Address: 333, gamma street Tags: [school][friends] +|| 4. Dickson Ee Phone: 444444 Address: 444, delta street Tags: [friends] +|| 5. Esther Potato Phone: 155555 Email: aesther@not.a.real.potato Tags: [tubers][starchy] +|| +|| 5 persons listed! +|| =================================================== +|| Enter command: || [Command entered: sort phone] +|| 1. Adam Brown Phone: 111111 Email: adam@gmail.com Address: 111, alpha street Tags: +|| 2. Esther Potato Phone: 155555 Email: aesther@not.a.real.potato Tags: [tubers][starchy] +|| 3. Betsy Choo Tags: [secretive] +|| 4. Charlie Dickson Email: charlie.d@nus.edu.sg Address: 333, gamma street Tags: [school][friends] +|| 5. Dickson Ee Phone: 444444 Address: 444, delta street Tags: [friends] +|| +|| 5 persons listed! +|| =================================================== +|| Enter command: || [Command entered: sort email] +|| 1. Adam Brown Phone: 111111 Email: adam@gmail.com Address: 111, alpha street Tags: +|| 2. Esther Potato Phone: 155555 Email: aesther@not.a.real.potato Tags: [tubers][starchy] +|| 3. Betsy Choo Tags: [secretive] +|| 4. Charlie Dickson Email: charlie.d@nus.edu.sg Address: 333, gamma street Tags: [school][friends] +|| 5. Dickson Ee Phone: 444444 Address: 444, delta street Tags: [friends] +|| +|| 5 persons listed! +|| =================================================== +|| Enter command: || [Command entered: sort address] +|| 1. Adam Brown Phone: 111111 Email: adam@gmail.com Address: 111, alpha street Tags: +|| 2. Betsy Choo Tags: [secretive] +|| 3. Charlie Dickson Email: charlie.d@nus.edu.sg Address: 333, gamma street Tags: [school][friends] +|| 4. Esther Potato Phone: 155555 Email: aesther@not.a.real.potato Tags: [tubers][starchy] +|| 5. Dickson Ee Phone: 444444 Address: 444, delta street Tags: [friends] +|| +|| 5 persons listed! +|| =================================================== +|| Enter command: || [Command entered: sort name] +|| 1. Adam Brown Phone: 111111 Email: adam@gmail.com Address: 111, alpha street Tags: +|| 2. Betsy Choo Tags: [secretive] +|| 3. Charlie Dickson Email: charlie.d@nus.edu.sg Address: 333, gamma street Tags: [school][friends] +|| 4. Dickson Ee Phone: 444444 Address: 444, delta street Tags: [friends] +|| 5. Esther Potato Phone: 155555 Email: aesther@not.a.real.potato Tags: [tubers][starchy] +|| +|| 5 persons listed! +|| =================================================== +|| Enter command: || [Command entered: clear] +|| Address book has been cleared! +|| =================================================== +|| Enter command: || [Command entered: list] +|| +|| 0 persons listed! +|| =================================================== || Enter command: || [Command entered: exit] || Exiting Address Book as requested ... || =================================================== diff --git a/test/input.txt b/test/input.txt index eb8df81f8..c2d422ac4 100644 --- a/test/input.txt +++ b/test/input.txt @@ -147,6 +147,34 @@ # clears all clear list + +########################################################## +# test sort command +########################################################## + + # add some users first + add Adam Brown p/111111 e/adam@gmail.com a/111, alpha street + add Betsy Choo pp/222222 pe/benchoo@nus.edu.sg pa/222, beta street t/secretive + add Charlie Dickson pp/333333 e/charlie.d@nus.edu.sg a/333, gamma street t/friends t/school + add Dickson Ee p/444444 pe/dickson@nus.edu.sg a/444, delta street t/friends + add Esther Potato p/155555 e/aesther@not.a.real.potato pa/355, epsilon street t/tubers t/starchy + list + + # test sorting by phone + sort phone + + # test sorting by email + sort email + + # test sorting by address + sort address + + # test sorting by name + sort name + + # clears all + clear + list ########################################################## # test exit command From 45694baa13cda573b13e814745c5c0e4fce6b8d1 Mon Sep 17 00:00:00 2001 From: Adam Chew Date: Thu, 13 Sep 2018 22:41:36 +0800 Subject: [PATCH 4/5] Update user guide --- docs/UserGuide.adoc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 4abb17e3e..c0b8ab8cd 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -72,6 +72,22 @@ Examples: Shows a list of all persons, along with their non-private details, in the address book. + Format: `list` +== Sorting the address book: `sort` + +Sorts the address book by the specified keyword and display the sorted address book in a list. + +Format: `sort KEYWORD` + +[NOTE] +==== +The sorting keyword is case sensitive. +==== + +Examples: + +* `sort email` + +* `sort address` + == Finding all persons containing any keyword in their name: `find` Finds persons whose names contain any of the given keywords. + From bf49e8ca717299790b380dc023e5ebe9a863ecf8 Mon Sep 17 00:00:00 2001 From: Adam Chew Date: Wed, 19 Sep 2018 11:47:55 +0800 Subject: [PATCH 5/5] Fix test log --- test/java/seedu/addressbook/commands/SortCommandTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/test/java/seedu/addressbook/commands/SortCommandTest.java b/test/java/seedu/addressbook/commands/SortCommandTest.java index 7bf3de0fb..4c422cdc4 100644 --- a/test/java/seedu/addressbook/commands/SortCommandTest.java +++ b/test/java/seedu/addressbook/commands/SortCommandTest.java @@ -46,7 +46,6 @@ private void assertSortCommandBehavior(String keyword, List expe private void assertSortCommandBehavior(String keyword, String errorMessage) { SortCommand command = createSortCommand(keyword); CommandResult result = command.execute(); - System.out.println(result.feedbackToUser); assertEquals(errorMessage, result.feedbackToUser); }