From db3978d4c091bf891c5f606d56560cb8cd092bb8 Mon Sep 17 00:00:00 2001 From: Akshay Narayan Date: Tue, 30 Aug 2016 15:25:29 +0800 Subject: [PATCH 01/24] Update regex for better Name matching Fix comment in Address.java (initially it was email for address) update tests to validate: new name regex --- src/seedu/addressbook/data/person/Address.java | 2 +- src/seedu/addressbook/data/person/Name.java | 7 ++++++- test/expected.txt | 8 ++++++++ test/input.txt | 3 +++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/seedu/addressbook/data/person/Address.java b/src/seedu/addressbook/data/person/Address.java index 8ac726444..db8701cf2 100644 --- a/src/seedu/addressbook/data/person/Address.java +++ b/src/seedu/addressbook/data/person/Address.java @@ -29,7 +29,7 @@ public Address(String address, boolean isPrivate) throws IllegalValueException { } /** - * Returns true if a given string is a valid person email. + * Returns true if a given string is a valid person address. */ public static boolean isValidAddress(String test) { return test.matches(ADDRESS_VALIDATION_REGEX); diff --git a/src/seedu/addressbook/data/person/Name.java b/src/seedu/addressbook/data/person/Name.java index 3cea2db6b..4ce597b80 100644 --- a/src/seedu/addressbook/data/person/Name.java +++ b/src/seedu/addressbook/data/person/Name.java @@ -13,7 +13,12 @@ public class Name { public static final String EXAMPLE = "John Doe"; public static final String MESSAGE_NAME_CONSTRAINTS = "Person names should be spaces or alphabetic characters"; - public static final String NAME_VALIDATION_REGEX = "[\\p{Alpha} ]+"; + public static final String NAME_VALIDATION_REGEX = "^[\\p{L} .'-]+$"; + // In the above: + // \\p{L} matches any unicode letter (like German name with accents) + // . used to match dots in the name E.g., John Paul Jr. + // ' is used to match names like d'Souza + // - is used to match names like Jolie-Pitt public final String fullName; diff --git a/test/expected.txt b/test/expected.txt index 7196c699f..5116a1bfc 100644 --- a/test/expected.txt +++ b/test/expected.txt @@ -297,6 +297,14 @@ || || 0 persons listed! || =================================================== +|| Enter command: || [Command entered: add Name with'arc p/99999999 e/name@arc.com a/1 long, #01-valid address, 890765] +|| New person added: Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: +|| =================================================== +|| Enter command: || [Command entered: list] +|| 1. Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: +|| +|| 1 persons listed! +|| =================================================== || Enter command: || [Command entered: exit] || Exiting Address Book as requested ... || =================================================== diff --git a/test/input.txt b/test/input.txt index 5ecae97f8..4a910eb49 100644 --- a/test/input.txt +++ b/test/input.txt @@ -147,6 +147,9 @@ # clears all clear list + + add Name with'arc p/99999999 e/name@arc.com a/1 long, #01-valid address, 890765 + list ########################################################## # test exit command From 730ea587205c2cbcbc3c2660dd7d3c3babe07111 Mon Sep 17 00:00:00 2001 From: Akshay Narayan Date: Tue, 30 Aug 2016 17:19:34 +0800 Subject: [PATCH 02/24] fix tests to clean up all entries before closing --- test/expected.txt | 7 +++++++ test/input.txt | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/test/expected.txt b/test/expected.txt index 5116a1bfc..b5dfddfd7 100644 --- a/test/expected.txt +++ b/test/expected.txt @@ -305,6 +305,13 @@ || || 1 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 4a910eb49..84f430771 100644 --- a/test/input.txt +++ b/test/input.txt @@ -148,8 +148,18 @@ clear list +########################################################## +# test new regex for name +########################################################## add Name with'arc p/99999999 e/name@arc.com a/1 long, #01-valid address, 890765 list + +########################################################## +# clear all test entries +########################################################## + + clear + list ########################################################## # test exit command From cec920413afec033a73f02cf99ace2128027c7f3 Mon Sep 17 00:00:00 2001 From: akshay narayan Date: Wed, 5 Oct 2016 21:55:37 +0800 Subject: [PATCH 03/24] add more tests to check for dash, dot, qote and unicode characters in the name update expected.txt to reflect the new changes --- test/expected.txt | 42 ++++++++++++++++++++++++++++++++++++++++++ test/input.txt | 17 +++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/test/expected.txt b/test/expected.txt index b5dfddfd7..2fbcbf8c5 100644 --- a/test/expected.txt +++ b/test/expected.txt @@ -305,6 +305,48 @@ || || 1 persons listed! || =================================================== +|| Enter command: || [Command entered: add John-Doe p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25] +|| New person added: John-Doe Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| =================================================== +|| Enter command: || [Command entered: list] +|| 1. Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: +|| 2. John-Doe Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| +|| 2 persons listed! +|| =================================================== +|| Enter command: || [Command entered: add John-Doe jr. p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25] +|| New person added: John-Doe jr. Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| =================================================== +|| Enter command: || [Command entered: list] +|| 1. Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: +|| 2. John-Doe Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| 3. John-Doe jr. Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| +|| 3 persons listed! +|| =================================================== +|| Enter command: || [Command entered: add Björn Borg p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25] +|| New person added: Björn Borg Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| =================================================== +|| Enter command: || [Command entered: list] +|| 1. Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: +|| 2. John-Doe Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| 3. John-Doe jr. Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| 4. Björn Borg Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| +|| 4 persons listed! +|| =================================================== +|| Enter command: || [Command entered: add José Eduardo p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25] +|| New person added: José Eduardo Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| =================================================== +|| Enter command: || [Command entered: list] +|| 1. Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: +|| 2. John-Doe Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| 3. John-Doe jr. Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| 4. Björn Borg Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| 5. José Eduardo Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| +|| 5 persons listed! +|| =================================================== || Enter command: || [Command entered: clear] || Address book has been cleared! || =================================================== diff --git a/test/input.txt b/test/input.txt index 84f430771..d66110c21 100644 --- a/test/input.txt +++ b/test/input.txt @@ -151,9 +151,26 @@ ########################################################## # test new regex for name ########################################################## + # name with quote character add Name with'arc p/99999999 e/name@arc.com a/1 long, #01-valid address, 890765 list + # name with hyphen in between + add John-Doe p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25 + list + + # name with dot in it + add John-Doe jr. p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25 + list + + # name with unicode character in it + add Björn Borg p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25 + list + + # name with another unicode character + add José Eduardo p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25 + list + ########################################################## # clear all test entries ########################################################## From adef5c60df18c413db50742800d265dda29d8acb Mon Sep 17 00:00:00 2001 From: akshay narayan Date: Wed, 5 Oct 2016 23:07:34 +0800 Subject: [PATCH 04/24] fixed regex to "^[\\p{L}0-9 .'-]+$", the prev one did not have numbers hence any name with numeric characer would be rejected. --- src/seedu/addressbook/data/person/Name.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/seedu/addressbook/data/person/Name.java b/src/seedu/addressbook/data/person/Name.java index 4ce597b80..b7b107498 100644 --- a/src/seedu/addressbook/data/person/Name.java +++ b/src/seedu/addressbook/data/person/Name.java @@ -13,7 +13,7 @@ public class Name { public static final String EXAMPLE = "John Doe"; public static final String MESSAGE_NAME_CONSTRAINTS = "Person names should be spaces or alphabetic characters"; - public static final String NAME_VALIDATION_REGEX = "^[\\p{L} .'-]+$"; + public static final String NAME_VALIDATION_REGEX = "^[\\p{L}0-9 .'-]+$"; // In the above: // \\p{L} matches any unicode letter (like German name with accents) // . used to match dots in the name E.g., John Paul Jr. From bf7f6bcafa304c93e65ee1f8665eb2cd04ba3a46 Mon Sep 17 00:00:00 2001 From: akshay narayan Date: Wed, 5 Oct 2016 23:12:55 +0800 Subject: [PATCH 05/24] add more test case to test name with numbers (the latest fix) --- test/expected.txt | 15 +++++++++++++++ test/input.txt | 14 ++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/test/expected.txt b/test/expected.txt index 2fbcbf8c5..1f994bdc0 100644 --- a/test/expected.txt +++ b/test/expected.txt @@ -354,6 +354,21 @@ || || 0 persons listed! || =================================================== +|| Enter command: || [Command entered: add George the 3rd p/99999999 e/name@arc.com a/1 long, #01-valid address, 890765] +|| New person added: George the 3rd Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: +|| =================================================== +|| Enter command: || [Command entered: list] +|| 1. George the 3rd Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: +|| +|| 1 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 d66110c21..322449bcc 100644 --- a/test/input.txt +++ b/test/input.txt @@ -178,6 +178,20 @@ clear list +########################################################## +# test new regex for name +########################################################## + # name with number character + add George the 3rd p/99999999 e/name@arc.com a/1 long, #01-valid address, 890765 + list + +########################################################## +# clear all test entries +########################################################## + + clear + list + ########################################################## # test exit command ########################################################## From 8928fefed91ddfbb964bda7804dcf72f9acdeae5 Mon Sep 17 00:00:00 2001 From: akshay narayan Date: Thu, 6 Oct 2016 22:21:51 +0800 Subject: [PATCH 06/24] convert input and expected to UTF-8 encoding. --- test/expected.txt | 16 ++++++++-------- test/input.txt | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/test/expected.txt b/test/expected.txt index 1f994bdc0..5f16c6058 100644 --- a/test/expected.txt +++ b/test/expected.txt @@ -1,4 +1,4 @@ -|| =================================================== +|| =================================================== || =================================================== || Welcome to your Address Book! || AddessBook Level 2 - Version 1.0 @@ -324,26 +324,26 @@ || || 3 persons listed! || =================================================== -|| Enter command: || [Command entered: add Björn Borg p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25] -|| New person added: Björn Borg Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| Enter command: || [Command entered: add Björn Borg p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25] +|| New person added: Björn Borg Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: || =================================================== || Enter command: || [Command entered: list] || 1. Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: || 2. John-Doe Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: || 3. John-Doe jr. Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| 4. Björn Borg Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| 4. Björn Borg Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: || || 4 persons listed! || =================================================== -|| Enter command: || [Command entered: add José Eduardo p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25] -|| New person added: José Eduardo Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| Enter command: || [Command entered: add José Eduardo p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25] +|| New person added: José Eduardo Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: || =================================================== || Enter command: || [Command entered: list] || 1. Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: || 2. John-Doe Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: || 3. John-Doe jr. Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| 4. Björn Borg Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| 5. José Eduardo Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| 4. Björn Borg Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: +|| 5. José Eduardo Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: || || 5 persons listed! || =================================================== diff --git a/test/input.txt b/test/input.txt index 322449bcc..3910f28ed 100644 --- a/test/input.txt +++ b/test/input.txt @@ -1,4 +1,4 @@ -########################################################## +########################################################## # invalid command ########################################################## @@ -164,11 +164,11 @@ list # name with unicode character in it - add Björn Borg p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25 + add Björn Borg p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25 list # name with another unicode character - add José Eduardo p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25 + add José Eduardo p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25 list ########################################################## From 02b59fc9f89c4637d902096e5786b5fa55226817 Mon Sep 17 00:00:00 2001 From: akshay narayan Date: Thu, 20 Oct 2016 17:36:36 +0800 Subject: [PATCH 07/24] encoding to UTF-8 w/o BOM for input and actual --- test/expected.txt | 2 +- test/input.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/expected.txt b/test/expected.txt index 5f16c6058..675bcd642 100644 --- a/test/expected.txt +++ b/test/expected.txt @@ -1,4 +1,4 @@ -|| =================================================== +|| =================================================== || =================================================== || Welcome to your Address Book! || AddessBook Level 2 - Version 1.0 diff --git a/test/input.txt b/test/input.txt index 3910f28ed..dd02a1687 100644 --- a/test/input.txt +++ b/test/input.txt @@ -1,4 +1,4 @@ -########################################################## +########################################################## # invalid command ########################################################## From 2283852571ac965ca5492fc1cb8a38ce4133a49b Mon Sep 17 00:00:00 2001 From: "Damith C. Rajapakse" Date: Sun, 27 Nov 2016 15:09:34 +0800 Subject: [PATCH 08/24] Add codacy badge --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e3454eef..25fc92aae 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/ad7aa7caa7ba4d40aef9440b16ea68d6)](https://www.codacy.com/app/se-edu/addressbook-level2?utm_source=github.com&utm_medium=referral&utm_content=se-edu/addressbook-level2&utm_campaign=Badge_Grade) + # AddressBook (Level 2) * This is a CLI (Command Line Interface) Address Book application **written in OOP fashion**. * It is a Java sample application intended for students learning Software Engineering while using Java as @@ -19,4 +21,4 @@ * **Bug reports, Suggestions** : Post in our [issue tracker](https://github.com/se-edu/addressbook-level2/issues) if you noticed bugs or have suggestions on how to improve. -* **Contributing** : We welcome pull requests. Follow the process described [here](https://github.com/oss-generic/process) \ No newline at end of file +* **Contributing** : We welcome pull requests. Follow the process described [here](https://github.com/oss-generic/process) From 43c506dbecfb5c883a2e45747b3634b78019dc7a Mon Sep 17 00:00:00 2001 From: Jia Yee Date: Wed, 7 Dec 2016 20:49:37 +0700 Subject: [PATCH 09/24] [#101] Remove unused imports (#114) --- src/seedu/addressbook/commands/ClearCommand.java | 3 --- src/seedu/addressbook/commands/FindCommand.java | 8 ++++++-- src/seedu/addressbook/common/Utils.java | 1 - .../addressbook/data/person/UniquePersonList.java | 9 ++++++++- src/seedu/addressbook/data/tag/UniqueTagList.java | 10 +++++++++- src/seedu/addressbook/parser/Parser.java | 6 +++++- src/seedu/addressbook/storage/StorageFile.java | 10 +++++++++- src/seedu/addressbook/ui/TextUi.java | 1 - 8 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/seedu/addressbook/commands/ClearCommand.java b/src/seedu/addressbook/commands/ClearCommand.java index f1bafb8a2..72468ac27 100644 --- a/src/seedu/addressbook/commands/ClearCommand.java +++ b/src/seedu/addressbook/commands/ClearCommand.java @@ -1,8 +1,5 @@ package seedu.addressbook.commands; -import seedu.addressbook.common.Utils; - - /** * Clears the address book. */ diff --git a/src/seedu/addressbook/commands/FindCommand.java b/src/seedu/addressbook/commands/FindCommand.java index 8937e08da..6fe255610 100644 --- a/src/seedu/addressbook/commands/FindCommand.java +++ b/src/seedu/addressbook/commands/FindCommand.java @@ -1,8 +1,12 @@ package seedu.addressbook.commands; -import seedu.addressbook.data.person.ReadOnlyPerson; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; -import java.util.*; +import seedu.addressbook.data.person.ReadOnlyPerson; /** * Finds and lists all persons in address book whose name contains any of the argument keywords. diff --git a/src/seedu/addressbook/common/Utils.java b/src/seedu/addressbook/common/Utils.java index 7718d4cc9..245f347c4 100644 --- a/src/seedu/addressbook/common/Utils.java +++ b/src/seedu/addressbook/common/Utils.java @@ -2,7 +2,6 @@ import java.util.Collection; import java.util.HashSet; -import java.util.Objects; import java.util.Set; /** diff --git a/src/seedu/addressbook/data/person/UniquePersonList.java b/src/seedu/addressbook/data/person/UniquePersonList.java index d960bd07c..60b7dcce0 100644 --- a/src/seedu/addressbook/data/person/UniquePersonList.java +++ b/src/seedu/addressbook/data/person/UniquePersonList.java @@ -1,9 +1,16 @@ package seedu.addressbook.data.person; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + import seedu.addressbook.common.Utils; import seedu.addressbook.data.exception.DuplicateDataException; -import java.util.*; + /** * A list of persons. Does not allow null elements or duplicates. diff --git a/src/seedu/addressbook/data/tag/UniqueTagList.java b/src/seedu/addressbook/data/tag/UniqueTagList.java index 039cb3458..814b35c79 100644 --- a/src/seedu/addressbook/data/tag/UniqueTagList.java +++ b/src/seedu/addressbook/data/tag/UniqueTagList.java @@ -1,9 +1,17 @@ package seedu.addressbook.data.tag; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + import seedu.addressbook.common.Utils; import seedu.addressbook.data.exception.DuplicateDataException; -import java.util.*; /** * A list of tags. Does not allow nulls or duplicates. diff --git a/src/seedu/addressbook/parser/Parser.java b/src/seedu/addressbook/parser/Parser.java index 7d8b944d7..a6cefcfc2 100644 --- a/src/seedu/addressbook/parser/Parser.java +++ b/src/seedu/addressbook/parser/Parser.java @@ -3,7 +3,11 @@ import seedu.addressbook.commands.*; import seedu.addressbook.data.exception.IllegalValueException; -import java.util.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/src/seedu/addressbook/storage/StorageFile.java b/src/seedu/addressbook/storage/StorageFile.java index 308e1b29a..684559a1b 100644 --- a/src/seedu/addressbook/storage/StorageFile.java +++ b/src/seedu/addressbook/storage/StorageFile.java @@ -8,7 +8,15 @@ import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; -import java.io.*; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/src/seedu/addressbook/ui/TextUi.java b/src/seedu/addressbook/ui/TextUi.java index 39a2c6615..208ea5668 100644 --- a/src/seedu/addressbook/ui/TextUi.java +++ b/src/seedu/addressbook/ui/TextUi.java @@ -3,7 +3,6 @@ import static seedu.addressbook.common.Messages.*; import seedu.addressbook.commands.CommandResult; -import seedu.addressbook.common.Utils; import seedu.addressbook.data.person.ReadOnlyPerson; import java.io.InputStream; From 7518552f786121d505f2ae1613901eae745d631e Mon Sep 17 00:00:00 2001 From: Jia Yee Date: Thu, 8 Dec 2016 12:29:44 +0700 Subject: [PATCH 10/24] [#102] Fix coding problem: reassigning parameters (#115) --- src/seedu/addressbook/data/person/Email.java | 6 +++--- src/seedu/addressbook/data/person/Name.java | 6 +++--- src/seedu/addressbook/data/person/Phone.java | 6 +++--- src/seedu/addressbook/data/tag/Tag.java | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/seedu/addressbook/data/person/Email.java b/src/seedu/addressbook/data/person/Email.java index c946f1eb3..967570640 100644 --- a/src/seedu/addressbook/data/person/Email.java +++ b/src/seedu/addressbook/data/person/Email.java @@ -23,11 +23,11 @@ public class Email { */ public Email(String email, boolean isPrivate) throws IllegalValueException { this.isPrivate = isPrivate; - email = email.trim(); - if (!isValidEmail(email)) { + String trimmedEmail = email.trim(); + if (!isValidEmail(trimmedEmail)) { throw new IllegalValueException(MESSAGE_EMAIL_CONSTRAINTS); } - this.value = email; + this.value = trimmedEmail; } /** diff --git a/src/seedu/addressbook/data/person/Name.java b/src/seedu/addressbook/data/person/Name.java index b7b107498..c33a56256 100644 --- a/src/seedu/addressbook/data/person/Name.java +++ b/src/seedu/addressbook/data/person/Name.java @@ -28,11 +28,11 @@ public class Name { * @throws IllegalValueException if given name string is invalid. */ public Name(String name) throws IllegalValueException { - name = name.trim(); - if (!isValidName(name)) { + String trimmedName = name.trim(); + if (!isValidName(trimmedName)) { throw new IllegalValueException(MESSAGE_NAME_CONSTRAINTS); } - this.fullName = name; + this.fullName = trimmedName; } /** diff --git a/src/seedu/addressbook/data/person/Phone.java b/src/seedu/addressbook/data/person/Phone.java index b5a556de4..942ab6619 100644 --- a/src/seedu/addressbook/data/person/Phone.java +++ b/src/seedu/addressbook/data/person/Phone.java @@ -22,11 +22,11 @@ public class Phone { */ public Phone(String phone, boolean isPrivate) throws IllegalValueException { this.isPrivate = isPrivate; - phone = phone.trim(); - if (!isValidPhone(phone)) { + String trimmedPhone = phone.trim(); + if (!isValidPhone(trimmedPhone)) { throw new IllegalValueException(MESSAGE_PHONE_CONSTRAINTS); } - this.value = phone; + this.value = trimmedPhone; } /** diff --git a/src/seedu/addressbook/data/tag/Tag.java b/src/seedu/addressbook/data/tag/Tag.java index 4e5f595dc..f363b6448 100644 --- a/src/seedu/addressbook/data/tag/Tag.java +++ b/src/seedu/addressbook/data/tag/Tag.java @@ -19,11 +19,11 @@ public class Tag { * @throws IllegalValueException if the given tag name string is invalid. */ public Tag(String name) throws IllegalValueException { - name = name.trim(); - if (!isValidTagName(name)) { + String trimmedName = name.trim(); + if (!isValidTagName(trimmedName)) { throw new IllegalValueException(MESSAGE_TAG_CONSTRAINTS); } - this.tagName = name; + this.tagName = trimmedName; } /** From f196968825df515ad93375e295618149f7a0514d Mon Sep 17 00:00:00 2001 From: Tan Wang Leng Date: Sat, 10 Dec 2016 19:31:48 +0800 Subject: [PATCH 11/24] [#109] Add unit tests for DeleteCommand class (#119) --- .../data/person/UniquePersonList.java | 6 + .../commands/DeleteCommandTest.java | 162 ++++++++++++++++++ .../java/seedu/addressbook/util/TestUtil.java | 46 +++++ 3 files changed, 214 insertions(+) create mode 100644 test/java/seedu/addressbook/commands/DeleteCommandTest.java create mode 100644 test/java/seedu/addressbook/util/TestUtil.java diff --git a/src/seedu/addressbook/data/person/UniquePersonList.java b/src/seedu/addressbook/data/person/UniquePersonList.java index 60b7dcce0..bd85a891f 100644 --- a/src/seedu/addressbook/data/person/UniquePersonList.java +++ b/src/seedu/addressbook/data/person/UniquePersonList.java @@ -125,4 +125,10 @@ public Iterator iterator() { return internalList.iterator(); } + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof UniquePersonList // instanceof handles nulls + && this.internalList.equals(((UniquePersonList) other).internalList)); + } } diff --git a/test/java/seedu/addressbook/commands/DeleteCommandTest.java b/test/java/seedu/addressbook/commands/DeleteCommandTest.java new file mode 100644 index 000000000..d4d79d760 --- /dev/null +++ b/test/java/seedu/addressbook/commands/DeleteCommandTest.java @@ -0,0 +1,162 @@ +package seedu.addressbook.commands; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Before; +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.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.PersonNotFoundException; +import seedu.addressbook.data.tag.UniqueTagList; +import seedu.addressbook.ui.TextUi; +import seedu.addressbook.util.TestUtil; + +public class DeleteCommandTest { + + private AddressBook emptyAddressBook; + private AddressBook addressBook; + + private List emptyDisplayList; + private List listWithEveryone; + private List listWithSurnameDoe; + + @Before + public void setUp() throws Exception { + Person johnDoe = new Person(new Name("John Doe"), new Phone("61234567", false), + new Email("john@doe.com", false), new Address("395C Ben Road", false), new UniqueTagList()); + Person janeDoe = new Person(new Name("Jane Doe"), new Phone("91234567", false), + new Email("jane@doe.com", false), new Address("33G Ohm Road", false), new UniqueTagList()); + Person samDoe = new Person(new Name("Sam Doe"), new Phone("63345566", false), + new Email("sam@doe.com", false), new Address("55G Abc Road", false), new UniqueTagList()); + Person davidGrant = new Person(new Name("David Grant"), new Phone("61121122", false), + new Email("david@grant.com", false), new Address("44H Define Road", false), + new UniqueTagList()); + + emptyAddressBook = TestUtil.createAddressBook(); + addressBook = TestUtil.createAddressBook(johnDoe, janeDoe, davidGrant, samDoe); + + emptyDisplayList = TestUtil.createList(); + + listWithEveryone = TestUtil.createList(johnDoe, janeDoe, davidGrant, samDoe); + listWithSurnameDoe = TestUtil.createList(johnDoe, janeDoe, samDoe); + } + + @Test + public void execute_emptyAddressBook_returnsPersonNotFoundMessage() { + assertDeletionFailsDueToNoSuchPerson(1, emptyAddressBook, listWithEveryone); + } + + @Test + public void execute_noPersonDisplayed_returnsInvalidIndexMessage() { + assertDeletionFailsDueToInvalidIndex(1, addressBook, emptyDisplayList); + } + + @Test + public void execute_targetPersonNotInAddressBook_returnsPersonNotFoundMessage() + throws IllegalValueException { + Person notInAddressBookPerson = new Person(new Name("Not In Book"), new Phone("63331444", false), + new Email("notin@book.com", false), new Address("156D Grant Road", false), new UniqueTagList()); + List listWithPersonNotInAddressBook = TestUtil.createList(notInAddressBookPerson); + + assertDeletionFailsDueToNoSuchPerson(1, addressBook, listWithPersonNotInAddressBook); + } + + @Test + public void execute_invalidIndex_returnsInvalidIndexMessage() { + assertDeletionFailsDueToInvalidIndex(0, addressBook, listWithEveryone); + assertDeletionFailsDueToInvalidIndex(-1, addressBook, listWithEveryone); + assertDeletionFailsDueToInvalidIndex(listWithEveryone.size() + 1, addressBook, listWithEveryone); + } + + @Test + public void execute_validIndex_personIsDeleted() throws PersonNotFoundException { + assertDeletionSuccessful(1, addressBook, listWithSurnameDoe); + assertDeletionSuccessful(listWithSurnameDoe.size(), addressBook, listWithSurnameDoe); + + int middleIndex = (listWithSurnameDoe.size() / 2) + 1; + assertDeletionSuccessful(middleIndex, addressBook, listWithSurnameDoe); + } + + /** + * Creates a new delete command. + * + * @param targetVisibleIndex of the person that we want to delete + */ + private DeleteCommand createDeleteCommand(int targetVisibleIndex, AddressBook addressBook, + List displayList) { + + DeleteCommand command = new DeleteCommand(targetVisibleIndex); + command.setData(addressBook, displayList); + + return command; + } + + /** + * Executes the command, and checks that the execution was what we had expected. + */ + private void assertCommandBehaviour(DeleteCommand deleteCommand, String expectedMessage, + AddressBook expectedAddressBook, AddressBook actualAddressBook) { + + CommandResult result = deleteCommand.execute(); + + assertEquals(expectedMessage, result.feedbackToUser); + assertEquals(expectedAddressBook.getAllPersons(), actualAddressBook.getAllPersons()); + } + + /** + * Asserts that the index is not valid for the given display list. + */ + private void assertDeletionFailsDueToInvalidIndex(int invalidVisibleIndex, AddressBook addressBook, + List displayList) { + + String expectedMessage = Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; + + DeleteCommand command = createDeleteCommand(invalidVisibleIndex, addressBook, displayList); + assertCommandBehaviour(command, expectedMessage, addressBook, addressBook); + } + + /** + * Asserts that the person at the specified index cannot be deleted, because that person + * is not in the address book. + */ + private void assertDeletionFailsDueToNoSuchPerson(int visibleIndex, AddressBook addressBook, + List displayList) { + + String expectedMessage = Messages.MESSAGE_PERSON_NOT_IN_ADDRESSBOOK; + + DeleteCommand command = createDeleteCommand(visibleIndex, addressBook, displayList); + assertCommandBehaviour(command, expectedMessage, addressBook, addressBook); + } + + /** + * Asserts that the person at the specified index can be successfully deleted. + * + * The addressBook passed in will not be modified (no side effects). + * + * @throws PersonNotFoundException if the selected person is not in the address book + */ + private void assertDeletionSuccessful(int targetVisibleIndex, AddressBook addressBook, + List displayList) throws PersonNotFoundException { + + ReadOnlyPerson targetPerson = displayList.get(targetVisibleIndex - TextUi.DISPLAYED_INDEX_OFFSET); + + AddressBook expectedAddressBook = TestUtil.clone(addressBook); + expectedAddressBook.removePerson(targetPerson); + String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, targetPerson); + + AddressBook actualAddressBook = TestUtil.clone(addressBook); + + DeleteCommand command = createDeleteCommand(targetVisibleIndex, actualAddressBook, displayList); + assertCommandBehaviour(command, expectedMessage, expectedAddressBook, actualAddressBook); + } +} diff --git a/test/java/seedu/addressbook/util/TestUtil.java b/test/java/seedu/addressbook/util/TestUtil.java new file mode 100644 index 000000000..42883545d --- /dev/null +++ b/test/java/seedu/addressbook/util/TestUtil.java @@ -0,0 +1,46 @@ +package seedu.addressbook.util; + +import java.util.ArrayList; +import java.util.List; + +import seedu.addressbook.data.AddressBook; +import seedu.addressbook.data.person.Person; +import seedu.addressbook.data.person.ReadOnlyPerson; +import seedu.addressbook.data.person.UniquePersonList.DuplicatePersonException; + +public class TestUtil { + /** + * Creates an address book containing the given persons. + * @throws DuplicatePersonException if two or more given persons are the same + */ + public static AddressBook createAddressBook(Person... persons) throws DuplicatePersonException { + AddressBook addressBook = new AddressBook(); + + for (Person person : persons) { + addressBook.addPerson(person); + } + + return addressBook; + } + + /** + * Creates a list of persons. + */ + public static List createList(Person...persons) { + List list = new ArrayList(); + + for (Person person : persons) { + list.add(person); + } + + return list; + } + + /** + * Creates a copy of the original address book with the same entries + * of Persons and Tags. The Persons and Tags are not cloned. + */ + public static AddressBook clone(AddressBook addressBook) { + return new AddressBook(addressBook.getAllPersons(), addressBook.getAllTags()); + } +} From 88133a62a70d24bc7fe4bb84b727cb707aad461f Mon Sep 17 00:00:00 2001 From: Neurrone Date: Sun, 11 Dec 2016 22:38:23 +0800 Subject: [PATCH 12/24] [#108] Add unit tests for AddCommand class (#118) * [#108] add unit tests for add command * renamed methods for consistency * capitalize todo --- .../addressbook/data/person/Address.java | 7 +- src/seedu/addressbook/data/person/Name.java | 2 +- .../addressbook/commands/AddCommandTest.java | 147 ++++++++++++++++++ .../java/seedu/addressbook/util/TestUtil.java | 17 ++ 4 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 test/java/seedu/addressbook/commands/AddCommandTest.java diff --git a/src/seedu/addressbook/data/person/Address.java b/src/seedu/addressbook/data/person/Address.java index db8701cf2..131d71b46 100644 --- a/src/seedu/addressbook/data/person/Address.java +++ b/src/seedu/addressbook/data/person/Address.java @@ -21,11 +21,12 @@ public class Address { * @throws IllegalValueException if given address string is invalid. */ public Address(String address, boolean isPrivate) throws IllegalValueException { + String trimmedAddress = address.trim(); this.isPrivate = isPrivate; - if (!isValidAddress(address)) { + if (!isValidAddress(trimmedAddress)) { throw new IllegalValueException(MESSAGE_ADDRESS_CONSTRAINTS); } - this.value = address; + this.value = trimmedAddress; } /** @@ -55,4 +56,4 @@ public int hashCode() { public boolean isPrivate() { return isPrivate; } -} \ No newline at end of file +} diff --git a/src/seedu/addressbook/data/person/Name.java b/src/seedu/addressbook/data/person/Name.java index c33a56256..2c701373a 100644 --- a/src/seedu/addressbook/data/person/Name.java +++ b/src/seedu/addressbook/data/person/Name.java @@ -12,7 +12,7 @@ public class Name { public static final String EXAMPLE = "John Doe"; - public static final String MESSAGE_NAME_CONSTRAINTS = "Person names should be spaces or alphabetic characters"; + public static final String MESSAGE_NAME_CONSTRAINTS = "Names should consist of letters, spaces, numbers, ', - or ."; public static final String NAME_VALIDATION_REGEX = "^[\\p{L}0-9 .'-]+$"; // In the above: // \\p{L} matches any unicode letter (like German name with accents) diff --git a/test/java/seedu/addressbook/commands/AddCommandTest.java b/test/java/seedu/addressbook/commands/AddCommandTest.java new file mode 100644 index 000000000..24c07c61e --- /dev/null +++ b/test/java/seedu/addressbook/commands/AddCommandTest.java @@ -0,0 +1,147 @@ +package seedu.addressbook.commands; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +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.data.AddressBook; +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.util.TestUtil; + +public class AddCommandTest { + private static final List EMPTY_PERSON_LIST = Collections.emptyList(); + private static final Set EMPTY_STRING_LIST = Collections.emptySet(); + + @Test + public void addCommand_invalidName_throwsException() { + final String[] invalidNames = { "", " ", "[]\\[;]" }; + for (String name : invalidNames) { + assertConstructingInvalidAddCmdThrowsException(name, Phone.EXAMPLE, true, Email.EXAMPLE, false, + Address.EXAMPLE, true, EMPTY_STRING_LIST); + } + } + + @Test + public void addCommand_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_LIST); + } + } + + @Test + public void addCommand_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_LIST); + } + } + + @Test + public void addCommand_invalidAddress_throwsException() { + final String[] invalidAddresses = { "", " " }; + for (String address : invalidAddresses) { + assertConstructingInvalidAddCmdThrowsException(Name.EXAMPLE, Phone.EXAMPLE, true, Email.EXAMPLE, + true, address, true, EMPTY_STRING_LIST); + } + } + + @Test + public void addCommand_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 addCommand_validData_correctlyConstructed() throws Exception { + AddCommand command = new AddCommand(Name.EXAMPLE, Phone.EXAMPLE, true, Email.EXAMPLE, false, + Address.EXAMPLE, true, EMPTY_STRING_LIST); + 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 addCommand_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 addCommand_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()); + } +} diff --git a/test/java/seedu/addressbook/util/TestUtil.java b/test/java/seedu/addressbook/util/TestUtil.java index 42883545d..7421ae986 100644 --- a/test/java/seedu/addressbook/util/TestUtil.java +++ b/test/java/seedu/addressbook/util/TestUtil.java @@ -1,12 +1,20 @@ package seedu.addressbook.util; +import static org.junit.Assert.fail; + import java.util.ArrayList; import java.util.List; import seedu.addressbook.data.AddressBook; +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.DuplicatePersonException; +import seedu.addressbook.data.tag.UniqueTagList; public class TestUtil { /** @@ -43,4 +51,13 @@ public static List createList(Person...persons) { public static AddressBook clone(AddressBook addressBook) { return new AddressBook(addressBook.getAllPersons(), addressBook.getAllTags()); } + public static Person generateTestPerson() { + try { + return new Person(new Name(Name.EXAMPLE), new Phone(Phone.EXAMPLE, false), + new Email(Email.EXAMPLE, true), new Address(Address.EXAMPLE, false), new UniqueTagList()); + } catch (IllegalValueException e) { + fail("test person data should be valid by definition"); + return null; + } + } } From 7d1de69dc5ab25b32e14e7bf49f89e8038eb4b67 Mon Sep 17 00:00:00 2001 From: Tan Wang Leng Date: Wed, 14 Dec 2016 02:45:11 +0800 Subject: [PATCH 13/24] [#124] Fix code style violation (#125) * Fix code style violation reported by checkstyle * Fix checkstyle issues in AddCommandTest --- src/seedu/addressbook/Main.java | 4 +- .../commands/IncorrectCommand.java | 4 +- src/seedu/addressbook/data/person/Email.java | 2 +- src/seedu/addressbook/data/person/Name.java | 7 +-- .../data/person/ReadOnlyPerson.java | 3 +- .../addressbook/data/tag/UniqueTagList.java | 4 +- src/seedu/addressbook/parser/Parser.java | 43 ++++++++++--------- src/seedu/addressbook/ui/TextUi.java | 4 +- .../addressbook/commands/AddCommandTest.java | 4 +- .../commands/DeleteCommandTest.java | 42 +++++++++--------- .../seedu/addressbook/parser/ParserTest.java | 34 +++++++-------- .../java/seedu/addressbook/util/TestUtil.java | 12 +++--- 12 files changed, 83 insertions(+), 80 deletions(-) diff --git a/src/seedu/addressbook/Main.java b/src/seedu/addressbook/Main.java index dd9f9aa65..e755a7531 100644 --- a/src/seedu/addressbook/Main.java +++ b/src/seedu/addressbook/Main.java @@ -99,7 +99,7 @@ private void recordResult(CommandResult result) { /** * Executes the command and returns the result. - * + * * @param command user command * @return result of the command */ @@ -126,4 +126,4 @@ private StorageFile initializeStorage(String[] launchArgs) throws InvalidStorage } -} \ No newline at end of file +} diff --git a/src/seedu/addressbook/commands/IncorrectCommand.java b/src/seedu/addressbook/commands/IncorrectCommand.java index 81abba7a1..46777aa61 100644 --- a/src/seedu/addressbook/commands/IncorrectCommand.java +++ b/src/seedu/addressbook/commands/IncorrectCommand.java @@ -4,11 +4,11 @@ /** * Represents an incorrect command. Upon execution, produces some feedback to the user. */ -public class IncorrectCommand extends Command{ +public class IncorrectCommand extends Command { public final String feedbackToUser; - public IncorrectCommand(String feedbackToUser){ + public IncorrectCommand(String feedbackToUser) { this.feedbackToUser = feedbackToUser; } diff --git a/src/seedu/addressbook/data/person/Email.java b/src/seedu/addressbook/data/person/Email.java index 967570640..e242e6d36 100644 --- a/src/seedu/addressbook/data/person/Email.java +++ b/src/seedu/addressbook/data/person/Email.java @@ -58,4 +58,4 @@ public int hashCode() { public boolean isPrivate() { return isPrivate; } -} \ No newline at end of file +} diff --git a/src/seedu/addressbook/data/person/Name.java b/src/seedu/addressbook/data/person/Name.java index 2c701373a..c74af03d1 100644 --- a/src/seedu/addressbook/data/person/Name.java +++ b/src/seedu/addressbook/data/person/Name.java @@ -12,13 +12,14 @@ public class Name { public static final String EXAMPLE = "John Doe"; - public static final String MESSAGE_NAME_CONSTRAINTS = "Names should consist of letters, spaces, numbers, ', - or ."; - public static final String NAME_VALIDATION_REGEX = "^[\\p{L}0-9 .'-]+$"; + public static final String MESSAGE_NAME_CONSTRAINTS = "Names should consist of letters, " + + "spaces, numbers, ', - or ."; + public static final String NAME_VALIDATION_REGEX = "^[\\p{L}0-9 .'-]+$"; // In the above: // \\p{L} matches any unicode letter (like German name with accents) // . used to match dots in the name E.g., John Paul Jr. // ' is used to match names like d'Souza - // - is used to match names like Jolie-Pitt + // - is used to match names like Jolie-Pitt public final String fullName; diff --git a/src/seedu/addressbook/data/person/ReadOnlyPerson.java b/src/seedu/addressbook/data/person/ReadOnlyPerson.java index f3678da99..d93b8a8a6 100644 --- a/src/seedu/addressbook/data/person/ReadOnlyPerson.java +++ b/src/seedu/addressbook/data/person/ReadOnlyPerson.java @@ -21,7 +21,8 @@ public interface ReadOnlyPerson { UniqueTagList getTags(); /** - * Returns true if the values inside this object is same as those of the other (Note: interfaces cannot override .equals) + * Returns true if the values inside this object is same as those of the other + * (Note: interfaces cannot override .equals) */ default boolean isSameStateAs(ReadOnlyPerson other) { return other == this // short circuit if same object diff --git a/src/seedu/addressbook/data/tag/UniqueTagList.java b/src/seedu/addressbook/data/tag/UniqueTagList.java index 814b35c79..4211752cd 100644 --- a/src/seedu/addressbook/data/tag/UniqueTagList.java +++ b/src/seedu/addressbook/data/tag/UniqueTagList.java @@ -134,8 +134,8 @@ public void mergeFrom(UniqueTagList tags) { * @throws TagNotFoundException if no such Tag could be found in the list. */ public void remove(Tag toRemove) throws TagNotFoundException { - final boolean TagFoundAndDeleted = internalList.remove(toRemove); - if (!TagFoundAndDeleted) { + final boolean tagFoundAndDeleted = internalList.remove(toRemove); + if (!tagFoundAndDeleted) { throw new TagNotFoundException(); } } diff --git a/src/seedu/addressbook/parser/Parser.java b/src/seedu/addressbook/parser/Parser.java index a6cefcfc2..55aebd274 100644 --- a/src/seedu/addressbook/parser/Parser.java +++ b/src/seedu/addressbook/parser/Parser.java @@ -62,35 +62,36 @@ public Command parseCommand(String userInput) { final String commandWord = matcher.group("commandWord"); final String arguments = matcher.group("arguments"); + switch (commandWord) { - case AddCommand.COMMAND_WORD: - return prepareAdd(arguments); + case AddCommand.COMMAND_WORD: + return prepareAdd(arguments); - case DeleteCommand.COMMAND_WORD: - return prepareDelete(arguments); + case DeleteCommand.COMMAND_WORD: + return prepareDelete(arguments); - case ClearCommand.COMMAND_WORD: - return new ClearCommand(); + case ClearCommand.COMMAND_WORD: + return new ClearCommand(); - case FindCommand.COMMAND_WORD: - return prepareFind(arguments); + case FindCommand.COMMAND_WORD: + return prepareFind(arguments); - case ListCommand.COMMAND_WORD: - return new ListCommand(); + case ListCommand.COMMAND_WORD: + return new ListCommand(); - case ViewCommand.COMMAND_WORD: - return prepareView(arguments); + case ViewCommand.COMMAND_WORD: + return prepareView(arguments); - case ViewAllCommand.COMMAND_WORD: - return prepareViewAll(arguments); + case ViewAllCommand.COMMAND_WORD: + return prepareViewAll(arguments); - case ExitCommand.COMMAND_WORD: - return new ExitCommand(); + case ExitCommand.COMMAND_WORD: + return new ExitCommand(); - case HelpCommand.COMMAND_WORD: // Fallthrough - default: - return new HelpCommand(); + case HelpCommand.COMMAND_WORD: // Fallthrough + default: + return new HelpCommand(); } } @@ -100,7 +101,7 @@ public Command parseCommand(String userInput) { * @param args full command args string * @return the prepared command */ - private Command prepareAdd(String args){ + private Command prepareAdd(String args) { final Matcher matcher = PERSON_DATA_ARGS_FORMAT.matcher(args.trim()); // Validate arg string format if (!matcher.matches()) { @@ -240,4 +241,4 @@ private Command prepareFind(String args) { } -} \ No newline at end of file +} diff --git a/src/seedu/addressbook/ui/TextUi.java b/src/seedu/addressbook/ui/TextUi.java index 208ea5668..94a9e6aa4 100644 --- a/src/seedu/addressbook/ui/TextUi.java +++ b/src/seedu/addressbook/ui/TextUi.java @@ -38,7 +38,7 @@ public class TextUi { private final Scanner in; private final PrintStream out; - public TextUi(){ + public TextUi() { this(System.in, System.out); } @@ -122,7 +122,7 @@ public void showToUser(String... message) { */ public void showResultToUser(CommandResult result) { final Optional> resultPersons = result.getRelevantPersons(); - if(resultPersons.isPresent()) { + if (resultPersons.isPresent()) { showPersonListView(resultPersons.get()); } showToUser(result.feedbackToUser, DIVIDER); diff --git a/test/java/seedu/addressbook/commands/AddCommandTest.java b/test/java/seedu/addressbook/commands/AddCommandTest.java index 24c07c61e..fd870a62e 100644 --- a/test/java/seedu/addressbook/commands/AddCommandTest.java +++ b/test/java/seedu/addressbook/commands/AddCommandTest.java @@ -49,7 +49,7 @@ public void addCommand_invalidPhone_throwsException() { @Test public void addCommand_invalidEmail_throwsException() { final String[] invalidEmails = { "", " ", "def.com", "@", "@def", "@def.com", "abc@", - "@invalid@email", "invalid@email!", "!invalid@email" }; + "@invalid@email", "invalid@email!", "!invalid@email" }; for (String email : invalidEmails) { assertConstructingInvalidAddCmdThrowsException(Name.EXAMPLE, Phone.EXAMPLE, false, email, false, Address.EXAMPLE, false, EMPTY_STRING_LIST); @@ -68,7 +68,7 @@ public void addCommand_invalidAddress_throwsException() { @Test public void addCommand_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, diff --git a/test/java/seedu/addressbook/commands/DeleteCommandTest.java b/test/java/seedu/addressbook/commands/DeleteCommandTest.java index d4d79d760..0e5ab80d9 100644 --- a/test/java/seedu/addressbook/commands/DeleteCommandTest.java +++ b/test/java/seedu/addressbook/commands/DeleteCommandTest.java @@ -46,7 +46,7 @@ public void setUp() throws Exception { addressBook = TestUtil.createAddressBook(johnDoe, janeDoe, davidGrant, samDoe); emptyDisplayList = TestUtil.createList(); - + listWithEveryone = TestUtil.createList(johnDoe, janeDoe, davidGrant, samDoe); listWithSurnameDoe = TestUtil.createList(johnDoe, janeDoe, samDoe); } @@ -82,14 +82,14 @@ public void execute_invalidIndex_returnsInvalidIndexMessage() { public void execute_validIndex_personIsDeleted() throws PersonNotFoundException { assertDeletionSuccessful(1, addressBook, listWithSurnameDoe); assertDeletionSuccessful(listWithSurnameDoe.size(), addressBook, listWithSurnameDoe); - + int middleIndex = (listWithSurnameDoe.size() / 2) + 1; assertDeletionSuccessful(middleIndex, addressBook, listWithSurnameDoe); } /** * Creates a new delete command. - * + * * @param targetVisibleIndex of the person that we want to delete */ private DeleteCommand createDeleteCommand(int targetVisibleIndex, AddressBook addressBook, @@ -112,51 +112,51 @@ private void assertCommandBehaviour(DeleteCommand deleteCommand, String expected assertEquals(expectedMessage, result.feedbackToUser); assertEquals(expectedAddressBook.getAllPersons(), actualAddressBook.getAllPersons()); } - + /** * Asserts that the index is not valid for the given display list. */ - private void assertDeletionFailsDueToInvalidIndex(int invalidVisibleIndex, AddressBook addressBook, + private void assertDeletionFailsDueToInvalidIndex(int invalidVisibleIndex, AddressBook addressBook, List displayList) { - + String expectedMessage = Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; - - DeleteCommand command = createDeleteCommand(invalidVisibleIndex, addressBook, displayList); + + DeleteCommand command = createDeleteCommand(invalidVisibleIndex, addressBook, displayList); assertCommandBehaviour(command, expectedMessage, addressBook, addressBook); } - + /** * Asserts that the person at the specified index cannot be deleted, because that person * is not in the address book. */ - private void assertDeletionFailsDueToNoSuchPerson(int visibleIndex, AddressBook addressBook, + private void assertDeletionFailsDueToNoSuchPerson(int visibleIndex, AddressBook addressBook, List displayList) { - + String expectedMessage = Messages.MESSAGE_PERSON_NOT_IN_ADDRESSBOOK; - - DeleteCommand command = createDeleteCommand(visibleIndex, addressBook, displayList); + + DeleteCommand command = createDeleteCommand(visibleIndex, addressBook, displayList); assertCommandBehaviour(command, expectedMessage, addressBook, addressBook); } - + /** * Asserts that the person at the specified index can be successfully deleted. - * + * * The addressBook passed in will not be modified (no side effects). - * + * * @throws PersonNotFoundException if the selected person is not in the address book */ - private void assertDeletionSuccessful(int targetVisibleIndex, AddressBook addressBook, + private void assertDeletionSuccessful(int targetVisibleIndex, AddressBook addressBook, List displayList) throws PersonNotFoundException { ReadOnlyPerson targetPerson = displayList.get(targetVisibleIndex - TextUi.DISPLAYED_INDEX_OFFSET); - + AddressBook expectedAddressBook = TestUtil.clone(addressBook); - expectedAddressBook.removePerson(targetPerson); + expectedAddressBook.removePerson(targetPerson); String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS, targetPerson); AddressBook actualAddressBook = TestUtil.clone(addressBook); - - DeleteCommand command = createDeleteCommand(targetVisibleIndex, actualAddressBook, displayList); + + DeleteCommand command = createDeleteCommand(targetVisibleIndex, actualAddressBook, displayList); assertCommandBehaviour(command, expectedMessage, expectedAddressBook, actualAddressBook); } } diff --git a/test/java/seedu/addressbook/parser/ParserTest.java b/test/java/seedu/addressbook/parser/ParserTest.java index 071375757..ddf7443ec 100644 --- a/test/java/seedu/addressbook/parser/ParserTest.java +++ b/test/java/seedu/addressbook/parser/ParserTest.java @@ -46,13 +46,13 @@ public void parse_unknownCommandWord_returnsHelp() { /* * Tests for 0-argument commands ======================================================================= */ - + @Test public void parse_helpCommand_parsedCorrectly() { final String input = "help"; parseAndAssertCommandType(input, HelpCommand.class); } - + @Test public void parse_clearCommand_parsedCorrectly() { final String input = "clear"; @@ -74,7 +74,7 @@ public void parse_exitCommand_parsedCorrectly() { /* * Tests for ingle index argument commands =============================================================== */ - + @Test public void parse_deleteCommandNoArgs_errorMessage() { final String[] inputs = { "delete", "delete " }; @@ -88,7 +88,7 @@ public void parse_deleteCommandArgsIsNotSingleNumber_errorMessage() { final String resultMessage = MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; parseAndAssertIncorrectWithMessage(resultMessage, inputs); } - + @Test public void parse_deleteCommandNumericArg_indexParsedCorrectly() { final int testIndex = 1; @@ -110,7 +110,7 @@ public void parse_viewCommandArgsIsNotSingleNumber_errorMessage() { final String resultMessage = MESSAGE_INVALID_PERSON_DISPLAYED_INDEX; parseAndAssertIncorrectWithMessage(resultMessage, inputs); } - + @Test public void parse_viewCommandNumericArg_indexParsedCorrectly() { final int testIndex = 2; @@ -150,8 +150,8 @@ public void parse_viewAllCommandNumericArg_indexParsedCorrectly() { public void parse_findCommandInvalidArgs_errorMessage() { // no keywords final String[] inputs = { - "find", - "find " + "find", + "find " }; final String resultMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE); @@ -184,19 +184,19 @@ public void parse_findCommandDuplicateKeys_parsedCorrectly() { /* * Tests for add person command ============================================================================== */ - + @Test public void parse_addCommandInvalidArgs_errorMessage() { final String[] inputs = { - "add", - "add ", - "add wrong args format", - // no phone prefix - String.format("add $s $s e/$s a/$s", Name.EXAMPLE, Phone.EXAMPLE, Email.EXAMPLE, Address.EXAMPLE), - // no email prefix - String.format("add $s p/$s $s a/$s", Name.EXAMPLE, Phone.EXAMPLE, Email.EXAMPLE, Address.EXAMPLE), - // no address prefix - String.format("add $s p/$s e/$s $s", Name.EXAMPLE, Phone.EXAMPLE, Email.EXAMPLE, Address.EXAMPLE) + "add", + "add ", + "add wrong args format", + // no phone prefix + String.format("add $s $s e/$s a/$s", Name.EXAMPLE, Phone.EXAMPLE, Email.EXAMPLE, Address.EXAMPLE), + // no email prefix + String.format("add $s p/$s $s a/$s", Name.EXAMPLE, Phone.EXAMPLE, Email.EXAMPLE, Address.EXAMPLE), + // no address prefix + String.format("add $s p/$s e/$s $s", Name.EXAMPLE, Phone.EXAMPLE, Email.EXAMPLE, Address.EXAMPLE) }; final String resultMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE); parseAndAssertIncorrectWithMessage(resultMessage, inputs); diff --git a/test/java/seedu/addressbook/util/TestUtil.java b/test/java/seedu/addressbook/util/TestUtil.java index 7421ae986..a18134b77 100644 --- a/test/java/seedu/addressbook/util/TestUtil.java +++ b/test/java/seedu/addressbook/util/TestUtil.java @@ -23,27 +23,27 @@ public class TestUtil { */ public static AddressBook createAddressBook(Person... persons) throws DuplicatePersonException { AddressBook addressBook = new AddressBook(); - + for (Person person : persons) { addressBook.addPerson(person); } - + return addressBook; } - + /** * Creates a list of persons. */ public static List createList(Person...persons) { List list = new ArrayList(); - + for (Person person : persons) { list.add(person); } - + return list; } - + /** * Creates a copy of the original address book with the same entries * of Persons and Tags. The Persons and Tags are not cloned. From 1a15e66024449bb65a9e9287af84f222c24bb926 Mon Sep 17 00:00:00 2001 From: zzzzwen Date: Thu, 22 Dec 2016 16:17:06 +0800 Subject: [PATCH 14/24] [#107] Add unit tests for Utils class (#127) * Add unit test for Utils class * Reduce the number of test cases in isAnyNull method * Reduce number of test cases in elementsAreUnique method * Change assertAreUnique and assertNotUnique methods to private and remove extra spaces * Remove @Before * Remove try catch clause * Inline buildTag method * Change test tag to local variable * Remove unused import * Extract createList() method and remove arraylist * Remove constant * Rearrange test cases to avoid confusion * Rename variable * add test cases to prevent false negative * Inline createList method * Rearrange test cases and remove whitespaces * Add newline at eof * Added spaces for type casting * Update comment for UtilsTest --- .../seedu/addressbook/common/UtilsTest.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 test/java/seedu/addressbook/common/UtilsTest.java diff --git a/test/java/seedu/addressbook/common/UtilsTest.java b/test/java/seedu/addressbook/common/UtilsTest.java new file mode 100644 index 000000000..82d57e126 --- /dev/null +++ b/test/java/seedu/addressbook/common/UtilsTest.java @@ -0,0 +1,72 @@ +package seedu.addressbook.common; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class UtilsTest { + @Test + public void isAnyNull() { + // empty list + assertFalse(Utils.isAnyNull()); + + // Any non-empty list + assertFalse(Utils.isAnyNull(new Object(), new Object())); + assertFalse(Utils.isAnyNull("test")); + assertFalse(Utils.isAnyNull("")); + + // non empty list with just one null at the beginning + assertTrue(Utils.isAnyNull((Object) null)); + assertTrue(Utils.isAnyNull(null, "", new Object())); + assertTrue(Utils.isAnyNull(null, new Object(), new Object())); + + // non empty list with nulls in the middle + assertTrue(Utils.isAnyNull(new Object(), null, null, "test")); + assertTrue(Utils.isAnyNull("", null, new Object())); + + // non empty list with one null as the last element + assertTrue(Utils.isAnyNull("", new Object(), null)); + assertTrue(Utils.isAnyNull(new Object(), new Object(), null)); + + // confirms nulls inside the list are not considered + List nullList = Arrays.asList((Object) null); + assertFalse(Utils.isAnyNull(nullList)); + } + + @Test + public void elementsAreUnique() throws Exception { + // empty list + assertAreUnique(); + + // only one object + assertAreUnique((Object) null); + assertAreUnique(1); + assertAreUnique(""); + assertAreUnique("abc"); + + // all objects unique + assertAreUnique("abc", "ab", "a"); + assertAreUnique(1, 2); + + // some identical objects + assertNotUnique("abc", "abc"); + assertNotUnique("abc", "", "abc", "ABC"); + assertNotUnique("", "abc", "a", "abc"); + assertNotUnique(1, new Integer(1)); + assertNotUnique(null, 1, new Integer(1)); + assertNotUnique(null, null); + assertNotUnique(null, "a", "b", null); + } + + private void assertAreUnique(Object... objects) { + assertTrue(Utils.elementsAreUnique(Arrays.asList(objects))); + } + + private void assertNotUnique(Object... objects) { + assertFalse(Utils.elementsAreUnique(Arrays.asList(objects))); + } +} From 24335db30633a4ba6c6e3339ad1736361b09bd8d Mon Sep 17 00:00:00 2001 From: Song Zhiwen Date: Wed, 28 Dec 2016 15:55:53 +0800 Subject: [PATCH 15/24] [#104] Add unit tests for StorageFile class (#128) * Add unit test for StorageFile class * Change indentation and add comments * Make invalid data file more obvious * Create Utility method getStorage * Change contains method to equals method * Style change in StorageFileTest * Style changes in StorageFileTest * Inline getStorage method * Remove unused import * Revert "Inline getStorage method" This reverts commit f431d12f12fd7bcdd30a512a85c3d1ed29f5ecfb. * Re-adjust getStorage() method * Change assertTrue() to assertEquals * Move test files to correct folder * Add test persons and extract to a method * Rework assertSaveSuccess() method * Move compareFiles method to TestUtil class * Minor changes in StorageFile class * remove trailing whitespaces and unused imports * remove unused import * Change to return directly as addressbook * Rework and rename compareFile() to assertTextFilesEqual() * Use of temporary folder and minor style issues * Remove trailing whitespaces * minor style changes * Extract temp.txt to constant string * rework assertSaveSuccess() method * change of javadoc * Minor changes * Javadoc language * Javadoc change * Javadoc change --- test/data/StorageFileTest/InvalidData.txt | 6 + test/data/StorageFileTest/ValidData.txt | 19 +++ .../addressbook/storage/StorageFileTest.java | 109 ++++++++++++++++++ .../java/seedu/addressbook/util/TestUtil.java | 15 +++ 4 files changed, 149 insertions(+) create mode 100644 test/data/StorageFileTest/InvalidData.txt create mode 100644 test/data/StorageFileTest/ValidData.txt create mode 100644 test/java/seedu/addressbook/storage/StorageFileTest.java diff --git a/test/data/StorageFileTest/InvalidData.txt b/test/data/StorageFileTest/InvalidData.txt new file mode 100644 index 000000000..91e8971a4 --- /dev/null +++ b/test/data/StorageFileTest/InvalidData.txt @@ -0,0 +1,6 @@ + + + + data + + diff --git a/test/data/StorageFileTest/ValidData.txt b/test/data/StorageFileTest/ValidData.txt new file mode 100644 index 000000000..968fccfdc --- /dev/null +++ b/test/data/StorageFileTest/ValidData.txt @@ -0,0 +1,19 @@ + + + + John Doe + 98765432 + johnd@gmail.com +
John street, block 123, #01-01
+
+ + Betsy Crowe + 1234567 + betsycrowe@gmail.com +
Newgate Prison
+ friend + criminal +
+ friend + criminal +
diff --git a/test/java/seedu/addressbook/storage/StorageFileTest.java b/test/java/seedu/addressbook/storage/StorageFileTest.java new file mode 100644 index 000000000..1bd6fcab3 --- /dev/null +++ b/test/java/seedu/addressbook/storage/StorageFileTest.java @@ -0,0 +1,109 @@ +package seedu.addressbook.storage; + +import static org.junit.Assert.assertEquals; +import java.nio.file.Paths; +import java.util.Collections; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; + +import seedu.addressbook.data.AddressBook; +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.tag.Tag; +import seedu.addressbook.data.tag.UniqueTagList; +import seedu.addressbook.storage.StorageFile.StorageOperationException; +import static seedu.addressbook.util.TestUtil.assertTextFilesEqual; + +public class StorageFileTest { + private static final String TEST_DATA_FOLDER = "test/data/StorageFileTest"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Rule + public TemporaryFolder testFolder = new TemporaryFolder(); + + @Test + public void constructor_nullFilePath_exceptionThrown() throws Exception { + thrown.expect(NullPointerException.class); + new StorageFile(null); + } + + @Test + public void constructor_noTxtExtension_exceptionThrown() throws Exception { + thrown.expect(IllegalValueException.class); + new StorageFile(TEST_DATA_FOLDER + "/" + "InvalidfileName"); + } + + @Test + public void load_invalidFormat_exceptionThrown() throws Exception { + // The file contains valid xml data, but does not match the AddressBook class + StorageFile storage = getStorage("InvalidData.txt"); + thrown.expect(StorageOperationException.class); + storage.load(); + } + + @Test + public void load_validFormat() throws Exception { + AddressBook actualAB = getStorage("ValidData.txt").load(); + AddressBook expectedAB = getTestAddressBook(); + + // ensure loaded AddressBook is properly constructed with test data + // TODO: overwrite equals method in AddressBook class and replace with equals method below + assertEquals(actualAB.getAllPersons(), expectedAB.getAllPersons()); + } + + @Test + public void save_nullAddressBook_exceptionThrown() throws Exception { + StorageFile storage = getTempStorage(); + thrown.expect(NullPointerException.class); + storage.save(null); + } + + @Test + public void save_validAddressBook() throws Exception { + AddressBook ab = getTestAddressBook(); + StorageFile storage = getTempStorage(); + storage.save(ab); + + assertStorageFilesEqual(storage, getStorage("ValidData.txt")); + } + + // getPath() method in StorageFile class is trivial so it is not tested + + /** + * Asserts that the contents of two storage files are the same. + */ + private void assertStorageFilesEqual(StorageFile sf1, StorageFile sf2) throws Exception { + assertTextFilesEqual(Paths.get(sf1.getPath()), Paths.get(sf2.getPath())); + } + + private StorageFile getStorage(String fileName) throws Exception { + return new StorageFile(TEST_DATA_FOLDER + "/" + fileName); + } + + private StorageFile getTempStorage() throws Exception { + return new StorageFile(testFolder.getRoot().getPath() + "/" + "temp.txt"); + } + + private AddressBook getTestAddressBook() throws Exception { + AddressBook ab = new AddressBook(); + ab.addPerson(new Person(new Name("John Doe"), + new Phone("98765432", false), + new Email("johnd@gmail.com", false), + new Address("John street, block 123, #01-01", false), + new UniqueTagList(Collections.emptySet()))); + ab.addPerson(new Person(new Name("Betsy Crowe"), + new Phone("1234567", true), + new Email("betsycrowe@gmail.com", false), + new Address("Newgate Prison", true), + new UniqueTagList(new Tag("friend"), new Tag("criminal")))); + return ab; + } +} diff --git a/test/java/seedu/addressbook/util/TestUtil.java b/test/java/seedu/addressbook/util/TestUtil.java index a18134b77..2b95b50bc 100644 --- a/test/java/seedu/addressbook/util/TestUtil.java +++ b/test/java/seedu/addressbook/util/TestUtil.java @@ -1,7 +1,12 @@ package seedu.addressbook.util; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; @@ -60,4 +65,14 @@ public static Person generateTestPerson() { return null; } } + + /** + * Asserts whether the text in the two given files are the same. Ignores any + * differences in line endings + */ + public static void assertTextFilesEqual(Path path1, Path path2) throws IOException { + List list1 = Files.readAllLines(path1, Charset.defaultCharset()); + List list2 = Files.readAllLines(path2, Charset.defaultCharset()); + assertEquals(String.join("\n", list1), String.join("\n", list2)); + } } From 753fcc1730855f584abff11ef5c8aea5dcd43cb7 Mon Sep 17 00:00:00 2001 From: Song Zhiwen Date: Mon, 2 Jan 2017 14:29:49 +0800 Subject: [PATCH 16/24] [#133] Test Failing due to incorrect message (#135) --- test/expected.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/expected.txt b/test/expected.txt index 675bcd642..eb43494c6 100644 --- a/test/expected.txt +++ b/test/expected.txt @@ -74,7 +74,7 @@ || Tags names should be alphanumeric || =================================================== || Enter command: || [Command entered: add []\[;] p/12345 e/valid@e.mail a/valid, address] -|| Person names should be spaces or alphabetic characters +|| Names should consist of letters, spaces, numbers, ', - or . || =================================================== || Enter command: || [Command entered: add Valid Name p/not_numbers e/valid@e.mail a/valid, address] || Person phone numbers should only contain numbers From a909e09d6c6e90ac1a0e68b69dcdae1c937f04cf Mon Sep 17 00:00:00 2001 From: awhdes Date: Tue, 3 Jan 2017 18:13:26 +0800 Subject: [PATCH 17/24] [#110] Add unit tests for FindCommand class (#120) * Add testutil classes to facilitate testing * Add TestMain class to facilitate testing of commands * Add equals() methond in AddressBook, UniquePersonList and UniqueTagList * Add FindCommandTest and CommandTest * Fix code style * Add indentation for equals() method * Reimplement FindCommandTest without use of TestMain * Remove duplicate equals() method in UniquePersonList * Remove TestPerson class * Refactor FindCommandTest * Refactor FindCommandTest * Refactor FindCommandTest * Remove empty line at top of assertCommandBehavior * Refactor TypicalPersons.java and shift instantiating a FindCommand in FindCommandTest to asserCommandBehavior method * Rename assertCommandBehavior to assertFindCommandBehavior * Remove PersonBuilder and make TypicalPersons fields non-static * Refactor FindCommandTest by inlining test methods * Remove unused imports * Add new test cases * Remove trailing empty lines * Fix coding style * Remove unused imports * Remove trailing whitespaces --- src/seedu/addressbook/commands/Command.java | 2 +- src/seedu/addressbook/data/AddressBook.java | 8 +++ .../addressbook/data/tag/UniqueTagList.java | 7 +++ .../addressbook/commands/FindCommandTest.java | 63 +++++++++++++++++++ .../addressbook/util/TypicalPersons.java | 53 ++++++++++++++++ 5 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 test/java/seedu/addressbook/commands/FindCommandTest.java create mode 100644 test/java/seedu/addressbook/util/TypicalPersons.java diff --git a/src/seedu/addressbook/commands/Command.java b/src/seedu/addressbook/commands/Command.java index 2e4708de9..67b193409 100644 --- a/src/seedu/addressbook/commands/Command.java +++ b/src/seedu/addressbook/commands/Command.java @@ -32,7 +32,7 @@ protected Command() { * @param personsDisplayed used to generate summary * @return summary message for persons displayed */ - protected String getMessageForPersonListShownSummary(List personsDisplayed) { + public static String getMessageForPersonListShownSummary(List personsDisplayed) { return String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, personsDisplayed.size()); } diff --git a/src/seedu/addressbook/data/AddressBook.java b/src/seedu/addressbook/data/AddressBook.java index 32d03913d..6a37d752d 100644 --- a/src/seedu/addressbook/data/AddressBook.java +++ b/src/seedu/addressbook/data/AddressBook.java @@ -143,4 +143,12 @@ public UniquePersonList getAllPersons() { public UniqueTagList getAllTags() { return new UniqueTagList(allTags); } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof AddressBook // instanceof handles nulls + && this.allPersons.equals(((AddressBook) other).allPersons) + && this.allTags.equals(((AddressBook) other).allTags)); + } } diff --git a/src/seedu/addressbook/data/tag/UniqueTagList.java b/src/seedu/addressbook/data/tag/UniqueTagList.java index 4211752cd..cfea05b86 100644 --- a/src/seedu/addressbook/data/tag/UniqueTagList.java +++ b/src/seedu/addressbook/data/tag/UniqueTagList.java @@ -160,4 +160,11 @@ public Iterator iterator() { return internalList.iterator(); } + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof UniqueTagList // instanceof handles nulls + && this.internalList.equals(((UniqueTagList) other).internalList)); + } + } diff --git a/test/java/seedu/addressbook/commands/FindCommandTest.java b/test/java/seedu/addressbook/commands/FindCommandTest.java new file mode 100644 index 000000000..f21b1e8e7 --- /dev/null +++ b/test/java/seedu/addressbook/commands/FindCommandTest.java @@ -0,0 +1,63 @@ +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.data.AddressBook; +import seedu.addressbook.data.exception.IllegalValueException; +import seedu.addressbook.data.person.ReadOnlyPerson; +import seedu.addressbook.util.TypicalPersons; + +public class FindCommandTest { + + private final AddressBook addressBook = new TypicalPersons().getTypicalAddressBook(); + private final TypicalPersons td = new TypicalPersons(); + + @Test + public void execute() throws IllegalValueException { + //same word, same case: matched + assertFindCommandBehavior(new String[]{"Amy"}, Arrays.asList(td.amy)); + + //same word, different case: not matched + assertFindCommandBehavior(new String[]{"aMy"}, Collections.emptyList()); + + //partial word: not matched + assertFindCommandBehavior(new String[]{"my"}, Collections.emptyList()); + + //multiple words: matched + assertFindCommandBehavior(new String[]{"Amy", "Bill", "Candy", "Destiny"}, + Arrays.asList(td.amy, td.bill, td.candy)); + + //repeated keywords: matched + assertFindCommandBehavior(new String[]{"Amy", "Amy"}, Arrays.asList(td.amy)); + + //Keyword matching a word in address: not matched + assertFindCommandBehavior(new String[]{"Clementi"}, Collections.emptyList()); + } + + /** + * Executes the find command for the given keywords and verifies + * the result matches the persons in the expectedPersonList exactly. + */ + private void assertFindCommandBehavior(String[] keywords, List expectedPersonList) { + FindCommand command = createFindCommand(keywords); + CommandResult result = command.execute(); + + assertEquals(Command.getMessageForPersonListShownSummary(expectedPersonList), result.feedbackToUser); + } + + private FindCommand createFindCommand(String[] keywords) { + final Set keywordSet = new HashSet<>(Arrays.asList(keywords)); + FindCommand command = new FindCommand(keywordSet); + command.setData(addressBook, Collections.emptyList()); + return command; + } + +} diff --git a/test/java/seedu/addressbook/util/TypicalPersons.java b/test/java/seedu/addressbook/util/TypicalPersons.java new file mode 100644 index 000000000..64e0d99c8 --- /dev/null +++ b/test/java/seedu/addressbook/util/TypicalPersons.java @@ -0,0 +1,53 @@ +package seedu.addressbook.util; + +import seedu.addressbook.data.AddressBook; +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.tag.UniqueTagList; + +/** + * Class to generate typical test persons + */ +public class TypicalPersons { + + public Person amy, bill, candy; + + public TypicalPersons() { + try { + amy = new Person(new Name("Amy Buck"), new Phone("91119111", false), new Email("ab@gmail.com", false), + new Address("1 Clementi Road", false), new UniqueTagList()); + bill = new Person(new Name("Bill Clint"), new Phone("92229222", false), new Email("bc@gmail.com", false), + new Address("2 Clementi Road", false), new UniqueTagList()); + candy = new Person(new Name("Candy Destiny"), new Phone("93339333", false), + new Email("cd@gmail.com", false), new Address("3 Clementi Road", false), new UniqueTagList()); + } catch (IllegalValueException e) { + e.printStackTrace(); + assert false : "not possible"; + } + } + + private void loadAddressBookWithSampleData(AddressBook ab) { + try { + for (Person p : this.getTypicalPersons()) { + ab.addPerson(new Person(p)); + } + } catch (IllegalValueException e) { + assert false : "not possible"; + } + } + + public Person[] getTypicalPersons() { + return new Person[]{amy, bill, candy}; + } + + public AddressBook getTypicalAddressBook() { + AddressBook ab = new AddressBook(); + loadAddressBookWithSampleData(ab); + return ab; + } + +} From 2fdb124ef2b69cb3e6b981a40a90eb38ce9bb4a6 Mon Sep 17 00:00:00 2001 From: Song Zhiwen Date: Tue, 3 Jan 2017 18:17:59 +0800 Subject: [PATCH 18/24] [#130] Change file extension requirement from .txt to .xml (#132) * change file ext requirement from txt to xml * test script change --- .gitignore | 2 +- doc/UserGuide.md | 6 +++--- src/seedu/addressbook/storage/StorageFile.java | 8 ++++---- .../StorageFileTest/{InvalidData.txt => InvalidData.xml} | 0 .../data/StorageFileTest/{ValidData.txt => ValidData.xml} | 0 test/expected.txt | 2 +- test/java/seedu/addressbook/storage/StorageFileTest.java | 8 ++++---- 7 files changed, 13 insertions(+), 13 deletions(-) rename test/data/StorageFileTest/{InvalidData.txt => InvalidData.xml} (100%) rename test/data/StorageFileTest/{ValidData.txt => ValidData.xml} (100%) diff --git a/.gitignore b/.gitignore index 0b30e2916..8a18db8d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Default storage file for addressbook : don't need to cleanup when running from IDE -addressbook.txt +addressbook.xml # Compiled classfiles bin/ diff --git a/doc/UserGuide.md b/doc/UserGuide.md index d38914a95..2f4e37b34 100644 --- a/doc/UserGuide.md +++ b/doc/UserGuide.md @@ -123,13 +123,13 @@ Address book data are saved in the hard disk automatically after any command tha There is no need to save manually. #### Changing the save location -Address book data are saved in a file called `addressbook.txt` in the project root folder. +Address book data are saved in a file called `addressbook.xml` in the project root folder. You can change the location by specifying the file path as a program argument. Example: -* `java seedu.addressbook.Main mydata.txt` +* `java seedu.addressbook.Main mydata.xml` -> The file name must end in `.txt` for it to be acceptable to the program. +> The file name must end in `.xml` for it to be acceptable to the program. > > When running the program inside Eclipse, you can set command line parameters before running the program. diff --git a/src/seedu/addressbook/storage/StorageFile.java b/src/seedu/addressbook/storage/StorageFile.java index 684559a1b..92ff9c3f1 100644 --- a/src/seedu/addressbook/storage/StorageFile.java +++ b/src/seedu/addressbook/storage/StorageFile.java @@ -26,7 +26,7 @@ public class StorageFile { /** Default file path used if the user doesn't provide the file name. */ - public static final String DEFAULT_STORAGE_FILEPATH = "addressbook.txt"; + public static final String DEFAULT_STORAGE_FILEPATH = "addressbook.xml"; /* Note: Note the use of nested classes below. * More info https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html @@ -74,16 +74,16 @@ public StorageFile(String filePath) throws InvalidStorageFilePathException { path = Paths.get(filePath); if (!isValidPath(path)) { - throw new InvalidStorageFilePathException("Storage file should end with '.txt'"); + throw new InvalidStorageFilePathException("Storage file should end with '.xml'"); } } /** * Returns true if the given path is acceptable as a storage file. - * The file path is considered acceptable if it ends with '.txt' + * The file path is considered acceptable if it ends with '.xml' */ private static boolean isValidPath(Path filePath) { - return filePath.toString().endsWith(".txt"); + return filePath.toString().endsWith(".xml"); } /** diff --git a/test/data/StorageFileTest/InvalidData.txt b/test/data/StorageFileTest/InvalidData.xml similarity index 100% rename from test/data/StorageFileTest/InvalidData.txt rename to test/data/StorageFileTest/InvalidData.xml diff --git a/test/data/StorageFileTest/ValidData.txt b/test/data/StorageFileTest/ValidData.xml similarity index 100% rename from test/data/StorageFileTest/ValidData.txt rename to test/data/StorageFileTest/ValidData.xml diff --git a/test/expected.txt b/test/expected.txt index eb43494c6..a57efcc33 100644 --- a/test/expected.txt +++ b/test/expected.txt @@ -3,7 +3,7 @@ || Welcome to your Address Book! || AddessBook Level 2 - Version 1.0 || Launch command format: java seedu.addressbook.Main [STORAGE_FILE_PATH] -|| Using storage file : addressbook.txt +|| Using storage file : addressbook.xml || =================================================== || Enter command: || [Command entered: sfdfd] || add: Adds a person to the address book. Contact details can be marked private by prepending 'p' to the prefix. diff --git a/test/java/seedu/addressbook/storage/StorageFileTest.java b/test/java/seedu/addressbook/storage/StorageFileTest.java index 1bd6fcab3..3c0db33e2 100644 --- a/test/java/seedu/addressbook/storage/StorageFileTest.java +++ b/test/java/seedu/addressbook/storage/StorageFileTest.java @@ -44,14 +44,14 @@ public void constructor_noTxtExtension_exceptionThrown() throws Exception { @Test public void load_invalidFormat_exceptionThrown() throws Exception { // The file contains valid xml data, but does not match the AddressBook class - StorageFile storage = getStorage("InvalidData.txt"); + StorageFile storage = getStorage("InvalidData.xml"); thrown.expect(StorageOperationException.class); storage.load(); } @Test public void load_validFormat() throws Exception { - AddressBook actualAB = getStorage("ValidData.txt").load(); + AddressBook actualAB = getStorage("ValidData.xml").load(); AddressBook expectedAB = getTestAddressBook(); // ensure loaded AddressBook is properly constructed with test data @@ -72,7 +72,7 @@ public void save_validAddressBook() throws Exception { StorageFile storage = getTempStorage(); storage.save(ab); - assertStorageFilesEqual(storage, getStorage("ValidData.txt")); + assertStorageFilesEqual(storage, getStorage("ValidData.xml")); } // getPath() method in StorageFile class is trivial so it is not tested @@ -89,7 +89,7 @@ private StorageFile getStorage(String fileName) throws Exception { } private StorageFile getTempStorage() throws Exception { - return new StorageFile(testFolder.getRoot().getPath() + "/" + "temp.txt"); + return new StorageFile(testFolder.getRoot().getPath() + "/" + "temp.xml"); } private AddressBook getTestAddressBook() throws Exception { From 70f60ba80f0bbf2477c3f7cfca46efe21848d8c6 Mon Sep 17 00:00:00 2001 From: Neurrone Date: Sun, 8 Jan 2017 15:09:47 +0800 Subject: [PATCH 19/24] [#117] Names with unicode characters are treated as invalid (#138) This reverts commit c61e65bd35f0562ba1cee10ad16f72c78d17ee06, reversing changes made to 4070eff9238c73f0cd8af51005c127108d1f15c1. --- .../addressbook/data/person/Address.java | 2 +- src/seedu/addressbook/data/person/Name.java | 11 +-- test/expected.txt | 74 +------------------ test/input.txt | 44 ----------- 4 files changed, 4 insertions(+), 127 deletions(-) diff --git a/src/seedu/addressbook/data/person/Address.java b/src/seedu/addressbook/data/person/Address.java index 131d71b46..25e462ad6 100644 --- a/src/seedu/addressbook/data/person/Address.java +++ b/src/seedu/addressbook/data/person/Address.java @@ -30,7 +30,7 @@ public Address(String address, boolean isPrivate) throws IllegalValueException { } /** - * Returns true if a given string is a valid person address. + * Returns true if a given string is a valid person email. */ public static boolean isValidAddress(String test) { return test.matches(ADDRESS_VALIDATION_REGEX); diff --git a/src/seedu/addressbook/data/person/Name.java b/src/seedu/addressbook/data/person/Name.java index c74af03d1..a57385407 100644 --- a/src/seedu/addressbook/data/person/Name.java +++ b/src/seedu/addressbook/data/person/Name.java @@ -12,15 +12,8 @@ public class Name { public static final String EXAMPLE = "John Doe"; - public static final String MESSAGE_NAME_CONSTRAINTS = "Names should consist of letters, " - + "spaces, numbers, ', - or ."; - public static final String NAME_VALIDATION_REGEX = "^[\\p{L}0-9 .'-]+$"; - // In the above: - // \\p{L} matches any unicode letter (like German name with accents) - // . used to match dots in the name E.g., John Paul Jr. - // ' is used to match names like d'Souza - // - is used to match names like Jolie-Pitt - + public static final String MESSAGE_NAME_CONSTRAINTS = "Person names should be spaces or alphabetic characters"; + public static final String NAME_VALIDATION_REGEX = "[\\p{Alpha} ]+"; public final String fullName; /** diff --git a/test/expected.txt b/test/expected.txt index a57efcc33..84f7f8bf3 100644 --- a/test/expected.txt +++ b/test/expected.txt @@ -74,7 +74,7 @@ || Tags names should be alphanumeric || =================================================== || Enter command: || [Command entered: add []\[;] p/12345 e/valid@e.mail a/valid, address] -|| Names should consist of letters, spaces, numbers, ', - or . +|| Person names should be spaces or alphabetic characters || =================================================== || Enter command: || [Command entered: add Valid Name p/not_numbers e/valid@e.mail a/valid, address] || Person phone numbers should only contain numbers @@ -297,78 +297,6 @@ || || 0 persons listed! || =================================================== -|| Enter command: || [Command entered: add Name with'arc p/99999999 e/name@arc.com a/1 long, #01-valid address, 890765] -|| New person added: Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: -|| =================================================== -|| Enter command: || [Command entered: list] -|| 1. Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: -|| -|| 1 persons listed! -|| =================================================== -|| Enter command: || [Command entered: add John-Doe p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25] -|| New person added: John-Doe Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| =================================================== -|| Enter command: || [Command entered: list] -|| 1. Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: -|| 2. John-Doe Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| -|| 2 persons listed! -|| =================================================== -|| Enter command: || [Command entered: add John-Doe jr. p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25] -|| New person added: John-Doe jr. Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| =================================================== -|| Enter command: || [Command entered: list] -|| 1. Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: -|| 2. John-Doe Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| 3. John-Doe jr. Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| -|| 3 persons listed! -|| =================================================== -|| Enter command: || [Command entered: add Björn Borg p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25] -|| New person added: Björn Borg Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| =================================================== -|| Enter command: || [Command entered: list] -|| 1. Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: -|| 2. John-Doe Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| 3. John-Doe jr. Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| 4. Björn Borg Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| -|| 4 persons listed! -|| =================================================== -|| Enter command: || [Command entered: add José Eduardo p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25] -|| New person added: José Eduardo Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| =================================================== -|| Enter command: || [Command entered: list] -|| 1. Name with'arc Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: -|| 2. John-Doe Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| 3. John-Doe jr. Phone: 98765432 Email: johnd@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| 4. Björn Borg Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| 5. José Eduardo Phone: 98765432 Email: borg@gmail.com Address: 311, Clementi Ave 2, #02-25 Tags: -|| -|| 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: add George the 3rd p/99999999 e/name@arc.com a/1 long, #01-valid address, 890765] -|| New person added: George the 3rd Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: -|| =================================================== -|| Enter command: || [Command entered: list] -|| 1. George the 3rd Phone: 99999999 Email: name@arc.com Address: 1 long, #01-valid address, 890765 Tags: -|| -|| 1 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 dd02a1687..5ecae97f8 100644 --- a/test/input.txt +++ b/test/input.txt @@ -147,50 +147,6 @@ # clears all clear list - -########################################################## -# test new regex for name -########################################################## - # name with quote character - add Name with'arc p/99999999 e/name@arc.com a/1 long, #01-valid address, 890765 - list - - # name with hyphen in between - add John-Doe p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25 - list - - # name with dot in it - add John-Doe jr. p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25 - list - - # name with unicode character in it - add Björn Borg p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25 - list - - # name with another unicode character - add José Eduardo p/98765432 e/borg@gmail.com a/311, Clementi Ave 2, #02-25 - list - -########################################################## -# clear all test entries -########################################################## - - clear - list - -########################################################## -# test new regex for name -########################################################## - # name with number character - add George the 3rd p/99999999 e/name@arc.com a/1 long, #01-valid address, 890765 - list - -########################################################## -# clear all test entries -########################################################## - - clear - list ########################################################## # test exit command From 6dc39b271fb3a500ab266cdda634e8a18c6521b6 Mon Sep 17 00:00:00 2001 From: zeticous Date: Fri, 27 Jan 2017 12:37:25 +0800 Subject: [PATCH 20/24] T3A2: Encapsulated feedbackToUser --- src/seedu/addressbook/commands/CommandResult.java | 8 ++++++-- src/seedu/addressbook/ui/TextUi.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/seedu/addressbook/commands/CommandResult.java b/src/seedu/addressbook/commands/CommandResult.java index cf4e72585..d2bff7359 100644 --- a/src/seedu/addressbook/commands/CommandResult.java +++ b/src/seedu/addressbook/commands/CommandResult.java @@ -11,8 +11,12 @@ public class CommandResult { /** The feedback message to be shown to the user. Contains a description of the execution result */ - public final String feedbackToUser; - + private final String feedbackToUser; + + public String getFeedbackToUser(){ + return feedbackToUser; + } + /** The list of persons that was produced by the command */ private final List relevantPersons; diff --git a/src/seedu/addressbook/ui/TextUi.java b/src/seedu/addressbook/ui/TextUi.java index 94a9e6aa4..a371e42f3 100644 --- a/src/seedu/addressbook/ui/TextUi.java +++ b/src/seedu/addressbook/ui/TextUi.java @@ -125,7 +125,7 @@ public void showResultToUser(CommandResult result) { if (resultPersons.isPresent()) { showPersonListView(resultPersons.get()); } - showToUser(result.feedbackToUser, DIVIDER); + showToUser(result.getFeedbackToUser(), DIVIDER); } /** From 91d0dacd4421d4e9a22c6f96c2a9c8ee1eb5c758 Mon Sep 17 00:00:00 2001 From: zeticous Date: Fri, 27 Jan 2017 15:02:02 +0800 Subject: [PATCH 21/24] T3A3: Create Class Buggy implementation. To be fixed. --- .../addressbook/commands/AddCommand.java | 4 +- .../addressbook/data/person/Address.java | 48 +++++++++++++++---- src/seedu/addressbook/data/person/Block.java | 17 +++++++ .../addressbook/data/person/PostalCode.java | 17 +++++++ src/seedu/addressbook/data/person/Street.java | 17 +++++++ src/seedu/addressbook/data/person/Unit.java | 28 +++++++++++ 6 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 src/seedu/addressbook/data/person/Block.java create mode 100644 src/seedu/addressbook/data/person/PostalCode.java create mode 100644 src/seedu/addressbook/data/person/Street.java create mode 100644 src/seedu/addressbook/data/person/Unit.java diff --git a/src/seedu/addressbook/commands/AddCommand.java b/src/seedu/addressbook/commands/AddCommand.java index 7ed3cf359..7fbddd272 100644 --- a/src/seedu/addressbook/commands/AddCommand.java +++ b/src/seedu/addressbook/commands/AddCommand.java @@ -17,9 +17,9 @@ public class AddCommand extends Command { public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the address book. " + "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" + + "Parameters: NAME [p]p/PHONE [p]e/EMAIL [p]a/BLOCK, STREET, UNIT, POSTAL CODE [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"; + + " John Doe p/98765432 e/johnd@gmail.com a/311, Clementi Ave 2, #02-25, 622311 t/friends t/owesMoney"; public static final String MESSAGE_SUCCESS = "New person added: %1$s"; public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book"; diff --git a/src/seedu/addressbook/data/person/Address.java b/src/seedu/addressbook/data/person/Address.java index 25e462ad6..39c805e5d 100644 --- a/src/seedu/addressbook/data/person/Address.java +++ b/src/seedu/addressbook/data/person/Address.java @@ -11,34 +11,62 @@ public class Address { public static final String EXAMPLE = "123, some street"; public static final String MESSAGE_ADDRESS_CONSTRAINTS = "Person addresses can be in any format"; public static final String ADDRESS_VALIDATION_REGEX = ".+"; - - public final String value; + + public static final int ADDRESS_INDEX_BLOCK = 0; + public static final int ADDRESS_INDEX_STREET = 1; + public static final int ADDRESS_INDEX_UNIT = 2; + public static final int ADDRESS_INDEX_POSTAL_CODE = 3; + public static final int ADDRESS_FIELD_COUNT = 4; + private boolean isPrivate; - - /** + + private Block addressBlock; + private Street addressStreet; + private Unit addressUnit; + private PostalCode addressPostalCode; + + public String value; + /* * Validates given address. - * * @throws IllegalValueException if given address string is invalid. */ public Address(String address, boolean isPrivate) throws IllegalValueException { - String trimmedAddress = address.trim(); + /* + * Address Format: a/ BLOCK, STREET, FLOOR-UNIT, POSTAL_CODE + */ + + String[] addressField = splitAddress(address); this.isPrivate = isPrivate; - if (!isValidAddress(trimmedAddress)) { + if (!isValidAddress(address)) { throw new IllegalValueException(MESSAGE_ADDRESS_CONSTRAINTS); } - this.value = trimmedAddress; + + fillAddressField(addressField); + value = toString(); + } + + public String[] splitAddress(String address){ + return address.split(","); + } + + public void fillAddressField(String[] addressField){ + addressBlock = new Block(addressField[ADDRESS_INDEX_BLOCK].trim()); + addressStreet = new Street(addressField[ADDRESS_INDEX_STREET].trim()); + addressUnit = new Unit(addressField[ADDRESS_INDEX_UNIT].trim()); + addressPostalCode = new PostalCode(addressField[ADDRESS_INDEX_POSTAL_CODE].trim()); } /** * Returns true if a given string is a valid person email. */ public static boolean isValidAddress(String test) { - return test.matches(ADDRESS_VALIDATION_REGEX); + return test.matches("(.*),(.*),(.*)-(.*),(.*)"); } @Override public String toString() { - return value; + return addressBlock.getBlockNumber()+", "+addressStreet.getStreetName()+", " + +addressUnit.getUnitNumber()+", "+addressPostalCode.getPostalCode(); } @Override diff --git a/src/seedu/addressbook/data/person/Block.java b/src/seedu/addressbook/data/person/Block.java new file mode 100644 index 000000000..b5c033311 --- /dev/null +++ b/src/seedu/addressbook/data/person/Block.java @@ -0,0 +1,17 @@ +package seedu.addressbook.data.person; + +public class Block { + private int blockNumber; + + public Block(String blockNumber){ + setBlockNumber(blockNumber); + } + + public int getBlockNumber(){ + return blockNumber; + } + + public void setBlockNumber(String blockNumber){ + this.blockNumber = Integer.parseInt(blockNumber); + } +} diff --git a/src/seedu/addressbook/data/person/PostalCode.java b/src/seedu/addressbook/data/person/PostalCode.java new file mode 100644 index 000000000..31b5e5135 --- /dev/null +++ b/src/seedu/addressbook/data/person/PostalCode.java @@ -0,0 +1,17 @@ +package seedu.addressbook.data.person; + +public class PostalCode { + private int postalCode; + + public PostalCode(String postalCode){ + setPostalCode(postalCode); + } + + public int getPostalCode(){ + return postalCode; + } + + public void setPostalCode(String postalCode){ + this.postalCode = Integer.parseInt(postalCode); + } +} diff --git a/src/seedu/addressbook/data/person/Street.java b/src/seedu/addressbook/data/person/Street.java new file mode 100644 index 000000000..fbdd4dc36 --- /dev/null +++ b/src/seedu/addressbook/data/person/Street.java @@ -0,0 +1,17 @@ +package seedu.addressbook.data.person; + +public class Street { + private String streetName; + + public Street(String streetName){ + setStreetName(streetName); + } + + public String getStreetName(){ + return streetName; + } + + public void setStreetName(String streetName){ + this.streetName = streetName; + } +} diff --git a/src/seedu/addressbook/data/person/Unit.java b/src/seedu/addressbook/data/person/Unit.java new file mode 100644 index 000000000..b7b2217cb --- /dev/null +++ b/src/seedu/addressbook/data/person/Unit.java @@ -0,0 +1,28 @@ +package seedu.addressbook.data.person; + +public class Unit { + private static final int FLOOR = 0; + private static final int UNIT_NUMBER = 1; + + /* + * UNIT NUMBER FORMAT: (FLOOR)-(UNIT_NUMBER) + * Example: B1-82 + */ + + private int unitNumber; + private String floor; + + public Unit(String unitNumberString){ + setUnitNumber(unitNumberString); + } + + public String getUnitNumber(){ + return floor+"-"+unitNumber; + } + + public void setUnitNumber(String unitNumberString){ + String[] unitNumberField = unitNumberString.split("-"); + floor = unitNumberField[FLOOR]; + this.unitNumber = Integer.parseInt(unitNumberField[UNIT_NUMBER]); + } +} From 7274ea8771ed4e7e91fc779734c94e055aa5d853 Mon Sep 17 00:00:00 2001 From: zeticous Date: Mon, 30 Jan 2017 15:54:52 +0800 Subject: [PATCH 22/24] Fixes for StorageOperationException and T3A2 StorageOperationException: - Delete addressbook.xml before testing. Buggy implementation of T3A2: - Change feedbackToUser to getFeedbackToUser in Add, Delete and Find Command. --- test/java/seedu/addressbook/commands/AddCommandTest.java | 4 ++-- test/java/seedu/addressbook/commands/DeleteCommandTest.java | 2 +- test/java/seedu/addressbook/commands/FindCommandTest.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/java/seedu/addressbook/commands/AddCommandTest.java b/test/java/seedu/addressbook/commands/AddCommandTest.java index fd870a62e..1a630f91a 100644 --- a/test/java/seedu/addressbook/commands/AddCommandTest.java +++ b/test/java/seedu/addressbook/commands/AddCommandTest.java @@ -126,7 +126,7 @@ public void addCommand_emptyAddressBook_addressBookContainsPerson() { assertTrue(people.contains(p)); assertEquals(1, people.immutableListView().size()); assertFalse(result.getRelevantPersons().isPresent()); - assertEquals(String.format(AddCommand.MESSAGE_SUCCESS, p), result.feedbackToUser); + assertEquals(String.format(AddCommand.MESSAGE_SUCCESS, p), result.getFeedbackToUser()); } @Test @@ -139,7 +139,7 @@ public void addCommand_addressBookAlreadyContainsPerson_addressBookUnmodified() CommandResult result = command.execute(); assertFalse(result.getRelevantPersons().isPresent()); - assertEquals(AddCommand.MESSAGE_DUPLICATE_PERSON, result.feedbackToUser); + assertEquals(AddCommand.MESSAGE_DUPLICATE_PERSON, result.getFeedbackToUser()); UniquePersonList people = book.getAllPersons(); assertTrue(people.contains(p)); assertEquals(1, people.immutableListView().size()); diff --git a/test/java/seedu/addressbook/commands/DeleteCommandTest.java b/test/java/seedu/addressbook/commands/DeleteCommandTest.java index 0e5ab80d9..4f71f198d 100644 --- a/test/java/seedu/addressbook/commands/DeleteCommandTest.java +++ b/test/java/seedu/addressbook/commands/DeleteCommandTest.java @@ -109,7 +109,7 @@ private void assertCommandBehaviour(DeleteCommand deleteCommand, String expected CommandResult result = deleteCommand.execute(); - assertEquals(expectedMessage, result.feedbackToUser); + assertEquals(expectedMessage, result.getFeedbackToUser()); assertEquals(expectedAddressBook.getAllPersons(), actualAddressBook.getAllPersons()); } diff --git a/test/java/seedu/addressbook/commands/FindCommandTest.java b/test/java/seedu/addressbook/commands/FindCommandTest.java index f21b1e8e7..1baa0aa12 100644 --- a/test/java/seedu/addressbook/commands/FindCommandTest.java +++ b/test/java/seedu/addressbook/commands/FindCommandTest.java @@ -50,7 +50,7 @@ private void assertFindCommandBehavior(String[] keywords, List e FindCommand command = createFindCommand(keywords); CommandResult result = command.execute(); - assertEquals(Command.getMessageForPersonListShownSummary(expectedPersonList), result.feedbackToUser); + assertEquals(Command.getMessageForPersonListShownSummary(expectedPersonList), result.getFeedbackToUser()); } private FindCommand createFindCommand(String[] keywords) { From 0fdfc4ff5efc334ed7d932a166b7880dd34bda67 Mon Sep 17 00:00:00 2001 From: zeticous Date: Mon, 30 Jan 2017 16:52:09 +0800 Subject: [PATCH 23/24] [T3A5] Added PrefixFormatter PrefixFormatter: Implemented SRP to formatting the messages for printing. --- src/seedu/addressbook/ui/PrefixFormatter.java | 33 +++++++++++++++++++ src/seedu/addressbook/ui/TextUi.java | 20 +++++------ 2 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 src/seedu/addressbook/ui/PrefixFormatter.java diff --git a/src/seedu/addressbook/ui/PrefixFormatter.java b/src/seedu/addressbook/ui/PrefixFormatter.java new file mode 100644 index 000000000..6fd4106ee --- /dev/null +++ b/src/seedu/addressbook/ui/PrefixFormatter.java @@ -0,0 +1,33 @@ +package seedu.addressbook.ui; + +import static seedu.addressbook.common.Messages.*; + +import seedu.addressbook.commands.CommandResult; +import seedu.addressbook.data.person.ReadOnlyPerson; + +import java.io.InputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Scanner; + +/** + * Adds line prefix to appropriate messages + */ +public class PrefixFormatter { + /** A decorative prefix added to the beginning of lines printed by AddressBook */ + private static final String LINE_PREFIX = "|| "; + + /** A platform independent line separator. */ + private static final String LS = System.lineSeparator(); + + /** + * Adds decorative prefix to the front of the printed messages. + * + * @param message to be printed + */ + public static String addPrefix(String message){ + return LINE_PREFIX + message.replace("\n", LS + LINE_PREFIX); + } +} diff --git a/src/seedu/addressbook/ui/TextUi.java b/src/seedu/addressbook/ui/TextUi.java index a371e42f3..83828287b 100644 --- a/src/seedu/addressbook/ui/TextUi.java +++ b/src/seedu/addressbook/ui/TextUi.java @@ -16,19 +16,12 @@ * Text UI of the application. */ public class TextUi { - - /** A decorative prefix added to the beginning of lines printed by AddressBook */ - private static final String LINE_PREFIX = "|| "; - - /** A platform independent line separator. */ - private static final String LS = System.lineSeparator(); - + private static final String DIVIDER = "==================================================="; /** Format of indexed list item */ private static final String MESSAGE_INDEXED_LIST_ITEM = "\t%1$d. %2$s"; - /** Offset required to convert between 1-indexing and 0-indexing. */ public static final int DISPLAYED_INDEX_OFFSET = 1; @@ -75,7 +68,7 @@ private boolean isCommentLine(String rawInputLine) { * @return command (full line) entered by the user */ public String getUserCommand() { - out.print(LINE_PREFIX + "Enter command: "); + showToUser("Enter command: "); String fullInputLine = in.nextLine(); // silently consume all ignored lines @@ -111,8 +104,13 @@ public void showInitFailedMessage() { /** Shows message(s) to the user */ public void showToUser(String... message) { - for (String m : message) { - out.println(LINE_PREFIX + m.replace("\n", LS + LINE_PREFIX)); + if (message.length == 1){ + out.print(PrefixFormatter.addPrefix(message[0])); + + } else{ + for (String m : message) { + out.println(PrefixFormatter.addPrefix(m)); + } } } From 71ccd264b4c9199960ab4abce038031b1443aeac Mon Sep 17 00:00:00 2001 From: zeticous Date: Wed, 8 Feb 2017 20:26:25 +0800 Subject: [PATCH 24/24] [T4A5] Add Tagging association class. - Unsure on how to incorperate methods into the current program. --- src/seedu/addressbook/data/AddressBook.java | 30 ++++++++++++++++++- src/seedu/addressbook/data/tag/Tagging.java | 32 +++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/seedu/addressbook/data/tag/Tagging.java diff --git a/src/seedu/addressbook/data/AddressBook.java b/src/seedu/addressbook/data/AddressBook.java index 6a37d752d..bbd972ab4 100644 --- a/src/seedu/addressbook/data/AddressBook.java +++ b/src/seedu/addressbook/data/AddressBook.java @@ -5,7 +5,9 @@ import seedu.addressbook.data.tag.UniqueTagList; import seedu.addressbook.data.tag.UniqueTagList.*; import seedu.addressbook.data.tag.Tag; +import seedu.addressbook.data.tag.Tagging; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -22,13 +24,14 @@ public class AddressBook { private final UniquePersonList allPersons; private final UniqueTagList allTags; // can contain tags not attached to any person - + private final ArrayList allTaggings; /** * Creates an empty address book. */ public AddressBook() { allPersons = new UniquePersonList(); allTags = new UniqueTagList(); + allTaggings = new ArrayList(); } /** @@ -44,6 +47,8 @@ public AddressBook(UniquePersonList persons, UniqueTagList tags) { for (Person p : allPersons) { syncTagsWithMasterList(p); } + + allTaggings = new ArrayList(); } /** @@ -89,6 +94,29 @@ public void addPerson(Person toAdd) throws DuplicatePersonException { public void addTag(Tag toAdd) throws DuplicateTagException { allTags.add(toAdd); } + + /** + * Records any tags that are added to a person into allTaggings. + */ + public void addTaggings(Tag tag, Person person){ + allTaggings.add(new Tagging(tag,person,Tagging.STATE_ADD_TAG)); + } + + /** + * Records any tags that are removed from a person into allTaggings. + */ + public void removeTaggings(Tag tag, Person person){ + allTaggings.add(new Tagging(tag,person,Tagging.STATE_REMOVE_TAG)); + } + + /** + * Print all records of tagging. + */ + public void printTaggings(){ + for(Tagging tagging: allTaggings){ + System.out.println(tagging.toString()); + } + } /** * Checks if an equivalent person exists in the address book. diff --git a/src/seedu/addressbook/data/tag/Tagging.java b/src/seedu/addressbook/data/tag/Tagging.java new file mode 100644 index 000000000..84e672e46 --- /dev/null +++ b/src/seedu/addressbook/data/tag/Tagging.java @@ -0,0 +1,32 @@ +package seedu.addressbook.data.tag; + +import java.util.ArrayList; + +import seedu.addressbook.data.person.Person; + +public class Tagging { + public static final int STATE_ADD_TAG = 0; + public static final int STATE_REMOVE_TAG = 1; + + Tag tag; + Person person; + int state; + + public Tagging(Tag tag, Person person, int state){ + this.tag = tag; + this.person = person; + this.state = state; + } + + @Override + public String toString(){ + switch(state){ + case STATE_ADD_TAG: + return "+ "+person.getName()+" "+tag.toString(); + case STATE_REMOVE_TAG: + return "+ "+person.getName()+" "+tag.toString(); + default: + return "INVALID_STRING"; + } + } +}