From 8e601942ad1b4a490c4bdaaf997cb6bd06b19482 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Thu, 2 Nov 2023 23:08:32 +0800 Subject: [PATCH 01/22] feat(main): More realistic/varied sample contacts --- .../model/util/SampleContactsUtil.java | 63 ++++++++++++------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/src/main/java/swe/context/model/util/SampleContactsUtil.java b/src/main/java/swe/context/model/util/SampleContactsUtil.java index dc6c88bbfcb..713728f4ed7 100644 --- a/src/main/java/swe/context/model/util/SampleContactsUtil.java +++ b/src/main/java/swe/context/model/util/SampleContactsUtil.java @@ -14,36 +14,53 @@ import swe.context.model.tag.Tag; + /** * Contains utility methods for working with sample {@link Contact}s. */ public class SampleContactsUtil { private static Contact[] getSampleContactsArray() { return new Contact[] { - new Contact(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"), - new Note("CS2103 tutorial mate."), - getTagSet("friends"), - getAlternateContactSet("Example: Alexyeoh")), - new Contact(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"), - new Note("CS2103 tutorial mate."), - getTagSet("colleagues", "friends"), - getAlternateContactSet("Example: berniceyu123")), - new Contact(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"), - new Note("CS2103 tutorial mate."), - getTagSet("neighbours"), - getAlternateContactSet("Example: Charlotte21")), - new Contact(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"), - new Note("CS2103 tutorial mate."), - getTagSet("family"), - getAlternateContactSet("Example: dl312")), - new Contact(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"), - new Note("CS2103 tutorial mate."), - getTagSet("classmates"), - getAlternateContactSet("Example: IrfanIbrahim")), - new Contact(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"), + new Contact( + new Name("Amy Bee"), + new Phone("87438807"), + new Email("e0705018@u.nus.edu"), new Note("CS2103 tutorial mate."), - getTagSet("colleagues"), - getAlternateContactSet("Example: RoyBalakrishnan")) + getTagSet("NUS", "CS2013 course"), + getAlternateContactSet("Telegram: amy_bee") + ), + new Contact( + new Name("Ben Lee"), + new Phone("99272758"), + new Email("ben-lee@gmail.com"), + new Note("Dorm at 42 Wallaby Way."), + getTagSet("friend"), + getAlternateContactSet("HousePhone: 67280491", "Discord: ben.games") + ), + new Contact( + new Name("Charlotte Oliveiro"), + new Phone("83210283"), + new Email("coliveiro@comp.nus.edu.sg"), + new Note("CS2103 Prof."), + getTagSet("NUS", "CS2013 course", "prof"), + getAlternateContactSet() + ), + new Contact( + new Name("David Li"), + new Phone("91031282"), + new Email("e0789123@u.nus.edu"), + new Note(""), + getTagSet("NUS", "CS1101S", "CS1231S"), + getAlternateContactSet("Telegram: David99") + ), + new Contact( + new Name("Ethan Ibrahim"), + new Phone("92492021"), + new Email("ethan.ibrahim@my-mail.com"), + new Note("(teaching assistant)"), + getTagSet("NUS", "CS3241", "TA"), + getAlternateContactSet("X: ethaaan", "Telegram: ethaaan") + ) }; } From caf1d935e728cc1af4874470daab7ea0eaaac6b6 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Thu, 2 Nov 2023 23:18:18 +0800 Subject: [PATCH 02/22] docs(): Tweaks for new samples --- docs/DeveloperGuide.md | 4 ++-- docs/UserGuide.md | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 50c7d21f797..b55ecca8493 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -208,8 +208,8 @@ The following activity diagram summarises what happens when a user executes an e - Can type fast and prefer typing - Are reasonably comfortable with command-line inputs -- Wish to label contacts by category (e.g. professors, classmates from certain courses) -- Have many different ways to reach their contacts (e.g. local/overseas phone number, Telegram, Discord etc.) +- Wish to label contacts by category (e.g. professors, classmates from certain courses, friends) +- Have many different ways to reach their contacts (e.g. social media like Telegram/Discord, additional phone numbers like house phone) **Value proposition**: Manage contacts quickly via text commands, with useful features relevant to SoC students. diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 2190911f2b6..aa9339d5fc6 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -8,9 +8,9 @@ It is optimized for use via an in-app Command Line Interface (CLI), while still It has useful features relevant to NUS SoC students: -- Tagging contacts by category: You can tag your professors and classmates with custom tags such as "Professor", "Tutorial mate", "CS2103" etc., then filter by tag to view all contacts with a certain tag. -- Storing different ways to reach people: By adding alternate contact details, you could have local phone number, overseas phone number, Telegram, Discord etc. all in the same contact. -- Works like a usual CLI: You can use the up/down arrow keys to switch between previously-entered commands, making entering and repeating commands (e.g. adding many new contacts) easier. +- Tagging contacts by category: You can tag your professors and classmates with custom tags such as "prof", "friend", "CS2103 course" etc., then filter by tag to view all contacts with a certain tag. +- Storing different ways to reach people: By adding alternate contact details, you could have Telegram, Discord, mobile phone, house phone etc. all in the same contact. +- Works like a usual CLI: You can use the up/down arrow keys to switch between previously-entered commands, making entering and repeating commands (e.g. adding many new contacts) easier. If you can type fast, prefer typing, and are reasonably comfortable with CLI inputs, ConText can let you manage contacts faster than traditional GUI apps. @@ -199,7 +199,7 @@ e.g. `find Bee John` will match the names `Amy Bee` and `John Doe`. **Examples:** - `find John` -- `find alex Bernice CHARLOTTE` +- `find alex Ben CHARLOTTE` ### Filtering by tag: `filter` @@ -210,7 +210,7 @@ Search and display contacts with tag matching the given keywords (case-insensiti **Example:** -- `filter Friend` +- `filter NUS` ### Viewing help: `help` From e6e111f5cfe80c3a670501315614179681d48418 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Thu, 2 Nov 2023 23:27:38 +0800 Subject: [PATCH 03/22] feat(): Merge add command usage --- docs/UserGuide.md | 2 +- .../context/logic/commands/AddCommand.java | 38 +++++++++++-------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index aa9339d5fc6..e25c5d441b1 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -99,7 +99,7 @@ The format for `ALTERNATE_CONTACT` is `TYPE: USERNAME`, roughly looking like `So **Examples:** - `add n/John Doe p/98765432 e/john.doe@email.com` -- `add n/John Doe p/98765432 e/john.doe@email.com o/Good at SE. t/NUS t/CS2103 course a/Telegram: JohnDoe` +- `add n/John Doe p/98765432 e/john.doe@email.com o/Likes SE. t/NUS t/CS2103 course a/Telegram: JohnDoe` ### Editing a contact: `edit` diff --git a/src/main/java/swe/context/logic/commands/AddCommand.java b/src/main/java/swe/context/logic/commands/AddCommand.java index 3e92bef3454..d8b223261ac 100644 --- a/src/main/java/swe/context/logic/commands/AddCommand.java +++ b/src/main/java/swe/context/logic/commands/AddCommand.java @@ -22,22 +22,28 @@ public class AddCommand extends Command { public static final String COMMAND_WORD = "add"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a contact. " - + "Parameters: " - + PREFIX_NAME + "NAME " - + PREFIX_PHONE + "PHONE " - + PREFIX_EMAIL + "EMAIL " - + "[" + PREFIX_NOTE + "NOTE] " - + "[" + PREFIX_TAG + "TAG]... " - + "[" + PREFIX_ALTERNATE + "ALTERNATE CONTACTS]...\n" - + "Example: " + COMMAND_WORD + " " - + PREFIX_NAME + "John Doe " - + PREFIX_PHONE + "98765432 " - + PREFIX_EMAIL + "john.doe@email.com " - + PREFIX_NOTE + "CS2103 Prof. " - + PREFIX_TAG + "NUS " - + PREFIX_TAG + "CS2103 course " - + PREFIX_ALTERNATE + "Telegram@JohnDoe"; + public static final String MESSAGE_USAGE = String.format( + "%s: Adds a contact." + + "%nParameters: %sNAME %sPHONE_NUMBER %sEMAIL" + + " [%sNOTE] [%sTAG]... [%sALTERNATE_CONTACT]..." + + "%nExample: %s %sJohn Doe %s98765432 %sjohn.doe@email.com" + + " %sLikes SE. %sNUS %sCS2103 course %sTelegram: JohnDoe", + AddCommand.COMMAND_WORD, + PREFIX_NAME, + PREFIX_PHONE, + PREFIX_EMAIL, + PREFIX_NOTE, + PREFIX_TAG, + PREFIX_ALTERNATE, + AddCommand.COMMAND_WORD, + PREFIX_NAME, + PREFIX_PHONE, + PREFIX_EMAIL, + PREFIX_NOTE, + PREFIX_TAG, + PREFIX_TAG, + PREFIX_ALTERNATE + ); private final Contact toAdd; /** From 21a48e332e696846615a93ce2fd0afda1f17c7f7 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Thu, 2 Nov 2023 23:53:11 +0800 Subject: [PATCH 04/22] feat(Contact): Format sets with string glue --- .../swe/context/model/contact/Contact.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main/java/swe/context/model/contact/Contact.java b/src/main/java/swe/context/model/contact/Contact.java index ce07fdedeb6..96c5626e1fb 100644 --- a/src/main/java/swe/context/model/contact/Contact.java +++ b/src/main/java/swe/context/model/contact/Contact.java @@ -6,6 +6,7 @@ import java.util.HashSet; import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; import swe.context.commons.util.ToStringBuilder; import swe.context.model.alternate.AlternateContact; @@ -91,10 +92,21 @@ public boolean isSameContact(Contact otherContact) { } /** - * Formats the {@code contact} for display to the user. + * Formats this for display to the user. */ public static String format(Contact contact) { - final StringBuilder builder = new StringBuilder(); + String tags = contact + .getTags() + .stream() + .map(Tag::toString) + .collect(Collectors.joining(", ")); + String alternates = contact + .getAlternates() + .stream() + .map(AlternateContact::toString) + .collect(Collectors.joining(", ")); + + StringBuilder builder = new StringBuilder(); builder.append(contact.getName()) .append("; Phone: ") .append(contact.getPhone()) @@ -102,10 +114,10 @@ public static String format(Contact contact) { .append(contact.getEmail()) .append("; Note: ") .append(contact.getNote()) - .append("; Tags: "); - contact.getTags().forEach(builder::append); - builder.append("; Alternate Contacts: "); - contact.getAlternates().forEach(builder::append); + .append("; Tags: ") + .append(tags) + .append("; Alternate Contacts: ") + .append(alternates); return builder.toString(); } From 8e3c63a9b00fa6908d8171b1fad3c018b132253f Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Thu, 2 Nov 2023 23:53:30 +0800 Subject: [PATCH 05/22] feat(main): Merge edit command usage --- .../context/logic/commands/EditCommand.java | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/main/java/swe/context/logic/commands/EditCommand.java b/src/main/java/swe/context/logic/commands/EditCommand.java index d9b72a8658d..b2692c588db 100644 --- a/src/main/java/swe/context/logic/commands/EditCommand.java +++ b/src/main/java/swe/context/logic/commands/EditCommand.java @@ -30,27 +30,30 @@ import swe.context.model.contact.Phone; import swe.context.model.tag.Tag; + + /** * Edits an existing {@link Contact}. */ public class EditCommand extends Command { - public static final String COMMAND_WORD = "edit"; - public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Edits the details of the contact identified " - + "by the index number used in the displayed contact list. " - + "Existing values will be overwritten by the input values.\n" - + "Parameters: INDEX (must be a positive integer) " - + "[" + PREFIX_NAME + "NAME] " - + "[" + PREFIX_PHONE + "PHONE] " - + "[" + PREFIX_EMAIL + "EMAIL] " - + "[" + PREFIX_NOTE + "NOTE] " - + "[" + PREFIX_TAG + "TAG]... " - + "[" + PREFIX_ALTERNATE + "ALTERNATE CONTACT]...\n" - + "Example: " + COMMAND_WORD + " 1 " - + PREFIX_PHONE + "91234567 " - + PREFIX_EMAIL + "johndoe@example.com"; + public static final String MESSAGE_USAGE = String.format( + "%s: Edits a contact. At least one optional parameter required." + + "%nParameters: INDEX [%sNAME] [%sPHONE_NUMBER] [%sEMAIL]" + + " [%sNOTE] [%sTAG]... [%sALTERNATE_CONTACT]..." + + "%nExample: %s 3 %sMember of NUS S/U %s", + EditCommand.COMMAND_WORD, + PREFIX_NAME, + PREFIX_PHONE, + PREFIX_EMAIL, + PREFIX_NOTE, + PREFIX_TAG, + PREFIX_ALTERNATE, + EditCommand.COMMAND_WORD, + PREFIX_NOTE, + PREFIX_TAG + ); private final Index index; private final EditContactDescriptor editContactDescriptor; From 89df94777afa8ba98f57c102afe467cb0b77fafe Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Thu, 2 Nov 2023 23:53:40 +0800 Subject: [PATCH 06/22] feat(main): Merge delete command usage --- .../swe/context/logic/commands/DeleteCommand.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/swe/context/logic/commands/DeleteCommand.java b/src/main/java/swe/context/logic/commands/DeleteCommand.java index 399f7f5006a..66c3a1bd944 100644 --- a/src/main/java/swe/context/logic/commands/DeleteCommand.java +++ b/src/main/java/swe/context/logic/commands/DeleteCommand.java @@ -13,18 +13,22 @@ import swe.context.model.Model; import swe.context.model.contact.Contact; + + /** * Deletes one or more {@link Contact}s based on their displayed indices in the UI list. * Duplicate indices are considered only once. */ public class DeleteCommand extends Command { - public static final String COMMAND_WORD = "delete"; - public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Deletes the contacts identified by the index number(s) used in the displayed contact list.\n" - + "Parameters: INDEX_1 INDEX_2 ... (must be 1 or more positive integers)\n" - + "Example: " + COMMAND_WORD + " 1 3 5"; + public static final String MESSAGE_USAGE = String.format( + "%s: Deletes contact(s)." + + "%nParameters: INDEX..." + + "%nExample: %s 1 3 5", + DeleteCommand.COMMAND_WORD, + DeleteCommand.COMMAND_WORD + ); private final List targetIndices; From 014272a445f162b2606a98dbca8c8091289729bf Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Thu, 2 Nov 2023 23:57:39 +0800 Subject: [PATCH 07/22] dev(gradle): Clean app data/log files --- build.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build.gradle b/build.gradle index 96d861ab655..b2cb9515fda 100644 --- a/build.gradle +++ b/build.gradle @@ -63,6 +63,13 @@ application { mainClass = 'swe.context.Main' } +clean { + delete './data/' + delete './config.json' + delete './settings.json' + delete fileTree('./') { include '*.log.*' } +} + run { enableAssertions true } From 6d99674b92bbf73ba8e797bf7d794afc57cbc36e Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Thu, 2 Nov 2023 23:59:14 +0800 Subject: [PATCH 08/22] dev(gradle): Don't delete config --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index b2cb9515fda..5a047ecc6fd 100644 --- a/build.gradle +++ b/build.gradle @@ -65,7 +65,6 @@ application { clean { delete './data/' - delete './config.json' delete './settings.json' delete fileTree('./') { include '*.log.*' } } From b704a020b3f68cf75de1ad024e3b7558dce190d3 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:12:42 +0800 Subject: [PATCH 09/22] feat(src): Message edits --- .../swe/context/commons/util/StringUtil.java | 6 +- src/main/java/swe/context/logic/Messages.java | 61 +++++++++---------- .../context/logic/commands/HelpCommand.java | 2 +- .../context/logic/commands/ListCommand.java | 3 +- .../logic/parser/EditCommandParser.java | 2 +- .../swe/context/logic/parser/ParserUtil.java | 4 +- .../swe/context/logic/LogicManagerTest.java | 2 +- .../logic/commands/HelpCommandTest.java | 2 +- .../logic/commands/ListCommandTest.java | 4 +- .../logic/parser/EditCommandParserTest.java | 2 +- .../context/logic/parser/ParserUtilTest.java | 5 +- 11 files changed, 46 insertions(+), 47 deletions(-) diff --git a/src/main/java/swe/context/commons/util/StringUtil.java b/src/main/java/swe/context/commons/util/StringUtil.java index b986e7782d7..4675db574cf 100644 --- a/src/main/java/swe/context/commons/util/StringUtil.java +++ b/src/main/java/swe/context/commons/util/StringUtil.java @@ -7,8 +7,6 @@ import java.io.StringWriter; import java.util.Arrays; -import swe.context.logic.Messages; - /** * Helper functions for handling strings. */ @@ -30,8 +28,8 @@ public static boolean containsWordIgnoreCase(String sentence, String word) { requireNonNull(word); String preppedWord = word.trim(); - checkArgument(!preppedWord.isEmpty(), Messages.EMPTY_WORD_PARAMETER); - checkArgument(preppedWord.split("\\s+").length == 1, Messages.SINGLE_WORD_EXPECTED); + checkArgument(!preppedWord.isEmpty(), "Keyword cannot be empty."); + checkArgument(preppedWord.split("\\s+").length == 1, "Keyword should be a single word."); String preppedSentence = sentence; String[] wordsInPreppedSentence = preppedSentence.split("\\s+"); diff --git a/src/main/java/swe/context/logic/Messages.java b/src/main/java/swe/context/logic/Messages.java index 8a6d9f3d7f9..62927bc0ce2 100644 --- a/src/main/java/swe/context/logic/Messages.java +++ b/src/main/java/swe/context/logic/Messages.java @@ -12,41 +12,38 @@ public final class Messages { // Generic commands public static final String COMMAND_UNKNOWN = "Unknown command."; - public static final String DUPLICATE_FIELDS = - "Multiple values specified for the following single-valued field(s): "; - public static final String EMPTY_WORD_PARAMETER = "Word parameter cannot be empty"; - public static final String SINGLE_WORD_EXPECTED = "Word parameter should be a single word"; - public static final String COMMAND_DUPLICATE_CONTACT = "This contact is already in your contact list."; - public static final String EDIT_COMMAND_NOT_EDITED = "At least one field to edit must be provided."; - public static final String HELP_COMMAND_SHOW_HELP = "Opened help window."; - public static final String LIST_COMMAND_SUCCESS = "Listed all contacts"; + public static final String DUPLICATE_FIELDS + = "Multiple values specified for the following single-valued parameters(s): "; + public static final String COMMAND_DUPLICATE_CONTACT = "There is an existing contact with the same name."; private static final String UNFORMATTED_COMMAND_INVALID_FORMAT = "Invalid command format.\n%s"; - private static final String UNFORMATTED_CONTACTS_LISTED_OVERVIEW = "%d contacts listed!"; + private static final String UNFORMATTED_CONTACTS_LISTED_OVERVIEW = "%d contacts listed."; private static final String UNFORMATTED_ADD_COMMAND_SUCCESS = "New contact added: %1$s"; - private static final String UNFORMATTED_DELETE_COMMAND_SUCCESS = "Deleted Contact(s): \n%1$s"; - private static final String UNFORMATTED_EDIT_COMMAND_SUCCESS = "Edited Contact: %1$s"; + private static final String UNFORMATTED_DELETE_COMMAND_SUCCESS = "Deleted contact(s): \n%1$s"; + private static final String UNFORMATTED_EDIT_COMMAND_SUCCESS = "Edited contact: %1$s"; // Specific commands - public static final String COMMAND_CLEAR_SUCCESS = "All contacts have been removed!"; + public static final String COMMAND_EDIT_NO_PARAM = "At least one optional parameter to edit must be provided."; + public static final String COMMAND_CLEAR_SUCCESS = "Removed all contacts!"; + public static final String COMMAND_LIST_SUCCESS = "Listed all contacts."; + public static final String COMMAND_HELP_SUCCESS = "Opened help window."; public static final String COMMAND_EXIT_SUCCESS = "Exiting app..."; - public static final String INVALID_DELETE_INDEX = - "One or more of the contact indices provided are invalid"; - public static final String INVALID_EDIT_INDEX = "The contact index provided is invalid"; - public static final String INVALID_PARSER_INDEX = "Index is not a non-zero unsigned integer."; - // Contacts + public static final String INVALID_DELETE_INDEX + = "One or more of the contact indices provided are invalid."; + public static final String INVALID_EDIT_INDEX = "The contact index provided is invalid."; + // Messages associated with Attributes constraints - public static final String NAME_INVALID = - "Names must be alphanumeric (spaces allowed)."; - public static final String PHONE_INVALID = - "Phone numbers must start with at least 3 digits."; - public static final String EMAIL_INVALID = - "Emails must roughly be of the form \"example_email@foo-domain.sg.\""; - private static final String UNFORMATTED_TAG_INVALID = - "\"%s\" is not a valid tag. Tags must be alphanumeric (spaces allowed)."; - - private static final String UNFORMATTED_ALTERNATECONTACT_INVALID = - "\"%s\" is not a valid alternate contact. " + public static final String NAME_INVALID + = "Names must be alphanumeric (spaces allowed)."; + public static final String PHONE_INVALID + = "Phone numbers must start with at least 3 digits."; + public static final String EMAIL_INVALID + = "Emails must roughly be of the form \"example_email@foo-domain.sg.\""; + private static final String UNFORMATTED_TAG_INVALID + = "\"%s\" is not a valid tag. Tags must be alphanumeric (spaces allowed)."; + + private static final String UNFORMATTED_ALTERNATECONTACT_INVALID + = "\"%s\" is not a valid alternate contact. " + "Alternate contacts must roughly be of the form \"socialMedia: name\""; // JSON @@ -54,10 +51,10 @@ public final class Messages { // Exceptions public static final String DUPLICATE_CONTACT_EXCEPTION = "Operation would result in duplicate contacts"; - private static final String UNFORMATTED_FILE_OPS_ERROR_FORMAT = - "Could not save data due to the following error: %s"; - private static final String UNFORMATTED_FILE_OPS_PERMISSION_ERROR_FORMAT = - "Could not save data to file %s due to insufficient permissions to write to the file or the folder."; + private static final String UNFORMATTED_FILE_OPS_ERROR_FORMAT + = "Could not save data due to the following error: %s"; + private static final String UNFORMATTED_FILE_OPS_PERMISSION_ERROR_FORMAT + = "Could not save data to file %s due to insufficient permissions to write to the file or the folder."; private static final String UNFORMATTED_FIELD_MISSING = "Contact's %s field is missing."; diff --git a/src/main/java/swe/context/logic/commands/HelpCommand.java b/src/main/java/swe/context/logic/commands/HelpCommand.java index 2f15f0bb90b..b271841f1e4 100644 --- a/src/main/java/swe/context/logic/commands/HelpCommand.java +++ b/src/main/java/swe/context/logic/commands/HelpCommand.java @@ -15,6 +15,6 @@ public class HelpCommand extends Command { @Override public CommandResult execute(Model model) { - return new CommandResult(Messages.HELP_COMMAND_SHOW_HELP, true, false); + return new CommandResult(Messages.COMMAND_HELP_SUCCESS, true, false); } } diff --git a/src/main/java/swe/context/logic/commands/ListCommand.java b/src/main/java/swe/context/logic/commands/ListCommand.java index 06bb8fa968b..be78a359360 100644 --- a/src/main/java/swe/context/logic/commands/ListCommand.java +++ b/src/main/java/swe/context/logic/commands/ListCommand.java @@ -5,6 +5,7 @@ import swe.context.logic.Messages; import swe.context.model.Model; import swe.context.model.ModelManager; +import swe.context.model.contact.Contact; @@ -18,6 +19,6 @@ public class ListCommand extends Command { public CommandResult execute(Model model) { requireNonNull(model); model.setContactsFilter(ModelManager.FILTER_NONE); - return new CommandResult(Messages.LIST_COMMAND_SUCCESS); + return new CommandResult(Messages.COMMAND_LIST_SUCCESS); } } diff --git a/src/main/java/swe/context/logic/parser/EditCommandParser.java b/src/main/java/swe/context/logic/parser/EditCommandParser.java index e5642d35eb4..658cdbda2a9 100644 --- a/src/main/java/swe/context/logic/parser/EditCommandParser.java +++ b/src/main/java/swe/context/logic/parser/EditCommandParser.java @@ -76,7 +76,7 @@ public EditCommand parse(String args) throws ParseException { .ifPresent(editContactDescriptor::setAlternateContacts); if (!editContactDescriptor.isAnyFieldEdited()) { - throw new ParseException(Messages.EDIT_COMMAND_NOT_EDITED); + throw new ParseException(Messages.COMMAND_EDIT_NO_PARAM); } return new EditCommand(index, editContactDescriptor); diff --git a/src/main/java/swe/context/logic/parser/ParserUtil.java b/src/main/java/swe/context/logic/parser/ParserUtil.java index 29974b316ab..dd9145978eb 100644 --- a/src/main/java/swe/context/logic/parser/ParserUtil.java +++ b/src/main/java/swe/context/logic/parser/ParserUtil.java @@ -21,6 +21,8 @@ * Contains utility methods used for parsing strings in the various *Parser classes. */ public class ParserUtil { + public static final String MESSAGE_INDEX_NOT_POSITIVE + = "Index is not a non-zero unsigned integer."; /** * Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing whitespaces will be @@ -30,7 +32,7 @@ public class ParserUtil { public static Index parseIndex(String oneBasedIndex) throws ParseException { String trimmedIndex = oneBasedIndex.trim(); if (!StringUtil.isNonZeroUnsignedInteger(trimmedIndex)) { - throw new ParseException(Messages.INVALID_PARSER_INDEX); + throw new ParseException(ParserUtil.MESSAGE_INDEX_NOT_POSITIVE); } return Index.fromOneBased(Integer.parseInt(trimmedIndex)); } diff --git a/src/test/java/swe/context/logic/LogicManagerTest.java b/src/test/java/swe/context/logic/LogicManagerTest.java index b596dd5ba33..46abb2ca216 100644 --- a/src/test/java/swe/context/logic/LogicManagerTest.java +++ b/src/test/java/swe/context/logic/LogicManagerTest.java @@ -61,7 +61,7 @@ public void execute_commandExecutionError_throwsCommandException() { @Test public void execute_validCommand_success() throws Exception { String listCommand = ListCommand.COMMAND_WORD; - assertCommandSuccess(listCommand, Messages.LIST_COMMAND_SUCCESS, model); + assertCommandSuccess(listCommand, Messages.COMMAND_LIST_SUCCESS, model); } @Test diff --git a/src/test/java/swe/context/logic/commands/HelpCommandTest.java b/src/test/java/swe/context/logic/commands/HelpCommandTest.java index b0ab5a4b337..e220ec43855 100644 --- a/src/test/java/swe/context/logic/commands/HelpCommandTest.java +++ b/src/test/java/swe/context/logic/commands/HelpCommandTest.java @@ -14,7 +14,7 @@ public class HelpCommandTest { @Test public void execute_help_success() { - CommandResult expectedCommandResult = new CommandResult(Messages.HELP_COMMAND_SHOW_HELP, true, false); + CommandResult expectedCommandResult = new CommandResult(Messages.COMMAND_HELP_SUCCESS, true, false); assertCommandSuccess(new HelpCommand(), model, expectedCommandResult, expectedModel); } } diff --git a/src/test/java/swe/context/logic/commands/ListCommandTest.java b/src/test/java/swe/context/logic/commands/ListCommandTest.java index 9bc73698109..51d3d072aa0 100644 --- a/src/test/java/swe/context/logic/commands/ListCommandTest.java +++ b/src/test/java/swe/context/logic/commands/ListCommandTest.java @@ -28,12 +28,12 @@ public void setUp() { @Test public void execute_listIsNotFiltered_showsSameList() { - assertCommandSuccess(new ListCommand(), model, Messages.LIST_COMMAND_SUCCESS, expectedModel); + assertCommandSuccess(new ListCommand(), model, Messages.COMMAND_LIST_SUCCESS, expectedModel); } @Test public void execute_listIsFiltered_showsEverything() { showContactAtIndex(model, TestData.IndexContact.FIRST_CONTACT); - assertCommandSuccess(new ListCommand(), model, Messages.LIST_COMMAND_SUCCESS, expectedModel); + assertCommandSuccess(new ListCommand(), model, Messages.COMMAND_LIST_SUCCESS, expectedModel); } } diff --git a/src/test/java/swe/context/logic/parser/EditCommandParserTest.java b/src/test/java/swe/context/logic/parser/EditCommandParserTest.java index be230920f41..954879a57b4 100644 --- a/src/test/java/swe/context/logic/parser/EditCommandParserTest.java +++ b/src/test/java/swe/context/logic/parser/EditCommandParserTest.java @@ -27,7 +27,7 @@ public void parse_missingParts_failure() { assertParseFailure(parser, TestData.Valid.NAME_AMY, MESSAGE_INVALID_FORMAT); // no field specified - assertParseFailure(parser, "1", Messages.EDIT_COMMAND_NOT_EDITED); + assertParseFailure(parser, "1", Messages.COMMAND_EDIT_NO_PARAM); // no index and no field specified assertParseFailure(parser, "", MESSAGE_INVALID_FORMAT); diff --git a/src/test/java/swe/context/logic/parser/ParserUtilTest.java b/src/test/java/swe/context/logic/parser/ParserUtilTest.java index 694e21804d5..5600164d21a 100644 --- a/src/test/java/swe/context/logic/parser/ParserUtilTest.java +++ b/src/test/java/swe/context/logic/parser/ParserUtilTest.java @@ -11,7 +11,6 @@ import org.junit.jupiter.api.Test; -import swe.context.logic.Messages; import swe.context.logic.parser.exceptions.ParseException; import swe.context.model.alternate.AlternateContact; import swe.context.model.contact.Email; @@ -21,6 +20,8 @@ import swe.context.model.tag.Tag; import swe.context.testutil.TestData; + + public class ParserUtilTest { @Test @@ -30,7 +31,7 @@ public void parseIndex_invalidInput_throwsParseException() { @Test public void parseIndex_outOfRangeInput_throwsParseException() { - assertThrows(ParseException.class, Messages.INVALID_PARSER_INDEX, () + assertThrows(ParseException.class, ParserUtil.MESSAGE_INDEX_NOT_POSITIVE, () -> ParserUtil.parseIndex(Long.toString(Integer.MAX_VALUE + 1))); } From fe46d62b233a5724e22d9c58f6707b6c4f7c0a0e Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:16:15 +0800 Subject: [PATCH 10/22] fix(src): Fix tests with message reuse --- .../java/swe/context/commons/util/StringUtil.java | 6 ++++-- .../swe/context/commons/util/StringUtilTest.java | 14 ++++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main/java/swe/context/commons/util/StringUtil.java b/src/main/java/swe/context/commons/util/StringUtil.java index 4675db574cf..27fdf5449ea 100644 --- a/src/main/java/swe/context/commons/util/StringUtil.java +++ b/src/main/java/swe/context/commons/util/StringUtil.java @@ -11,6 +11,8 @@ * Helper functions for handling strings. */ public class StringUtil { + public static final String MESSAGE_KEYWORD_EMPTY = "Keyword cannot be empty."; + public static final String MESSAGE_KEYWORD_MULTI_WORD = "Keyword should be a single word."; /** * Returns true if the {@code sentence} contains the {@code word}. @@ -28,8 +30,8 @@ public static boolean containsWordIgnoreCase(String sentence, String word) { requireNonNull(word); String preppedWord = word.trim(); - checkArgument(!preppedWord.isEmpty(), "Keyword cannot be empty."); - checkArgument(preppedWord.split("\\s+").length == 1, "Keyword should be a single word."); + checkArgument(!preppedWord.isEmpty(), StringUtil.MESSAGE_KEYWORD_EMPTY); + checkArgument(preppedWord.split("\\s+").length == 1, StringUtil.MESSAGE_KEYWORD_MULTI_WORD); String preppedSentence = sentence; String[] wordsInPreppedSentence = preppedSentence.split("\\s+"); diff --git a/src/test/java/swe/context/commons/util/StringUtilTest.java b/src/test/java/swe/context/commons/util/StringUtilTest.java index b752132a4b3..85f7a14a1cb 100644 --- a/src/test/java/swe/context/commons/util/StringUtilTest.java +++ b/src/test/java/swe/context/commons/util/StringUtilTest.java @@ -63,14 +63,20 @@ public void containsWordIgnoreCase_nullWord_throwsNullPointerException() { @Test public void containsWordIgnoreCase_emptyWord_throwsIllegalArgumentException() { - assertThrows(IllegalArgumentException.class, "Word parameter cannot be empty", () - -> StringUtil.containsWordIgnoreCase("typical sentence", " ")); + assertThrows( + IllegalArgumentException.class, + StringUtil.MESSAGE_KEYWORD_EMPTY, + () -> StringUtil.containsWordIgnoreCase("typical sentence", " ") + ); } @Test public void containsWordIgnoreCase_multipleWords_throwsIllegalArgumentException() { - assertThrows(IllegalArgumentException.class, "Word parameter should be a single word", () - -> StringUtil.containsWordIgnoreCase("typical sentence", "aaa BBB")); + assertThrows( + IllegalArgumentException.class, + StringUtil.MESSAGE_KEYWORD_MULTI_WORD, + () -> StringUtil.containsWordIgnoreCase("typical sentence", "aaa BBB") + ); } @Test From a908c70bc7f2a8f827713b5780f900f0367dddf0 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:19:42 +0800 Subject: [PATCH 11/22] feat(main): Merge find command usage --- .../java/swe/context/logic/commands/FindCommand.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/swe/context/logic/commands/FindCommand.java b/src/main/java/swe/context/logic/commands/FindCommand.java index 1d07074e730..3e4e2d9bc0e 100644 --- a/src/main/java/swe/context/logic/commands/FindCommand.java +++ b/src/main/java/swe/context/logic/commands/FindCommand.java @@ -17,11 +17,13 @@ public class FindCommand extends Command { public static final String COMMAND_WORD = "find"; - public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Finds and lists all contacts whose names match any of the" - + " specified words in full. Case insensitive." - + "\nParameters: [KEYWORD]..." - + "\nExample: " + COMMAND_WORD + " alice bob charlie"; + public static final String MESSAGE_USAGE = String.format( + "%s: Finds contacts by name. Case insensitive. Requires full word match." + + "%nParameters: KEYWORD..." + + "%nExample: %s alex Ben CHARLOTTE", + FindCommand.COMMAND_WORD, + FindCommand.COMMAND_WORD + ); private final NameContainsKeywordsPredicate predicate; From ea3cb9af9125a609289ed995697d8768c0faac28 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:22:24 +0800 Subject: [PATCH 12/22] feat(): Tweak names, formatting --- docs/UserGuide.md | 6 +++--- src/main/java/swe/context/logic/commands/FindCommand.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index e25c5d441b1..b05a44fba36 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -78,8 +78,8 @@ Adds a new contact. Note that contacts are identified by their name in ConText, and contacts with exactly the same name (including casing) are considered the same contact. Hence, you will not be able to add a new contact with the same name as an existing contact. -For example, if you already have a contact with name "John Doe", you will not be able to add another contact with the same name "John Doe". -However, you may add another contact with name "John Alex Doe", or "John doe", or you may first modify the name of the existing contact. +For example, if you already have a contact with name `John Doe`, you will not be able to add another contact with the same name `John Doe`. +However, you may add another contact with name `John doe`, or `Alex John Doe`. You may also first modify the name of the existing contact. Should you need to make changes to an existing contact, use the `edit` command as explained below. @@ -199,7 +199,7 @@ e.g. `find Bee John` will match the names `Amy Bee` and `John Doe`. **Examples:** - `find John` -- `find alex Ben CHARLOTTE` +- `find amy Ben CHARLOTTE` ### Filtering by tag: `filter` diff --git a/src/main/java/swe/context/logic/commands/FindCommand.java b/src/main/java/swe/context/logic/commands/FindCommand.java index 3e4e2d9bc0e..e69a62ec2ad 100644 --- a/src/main/java/swe/context/logic/commands/FindCommand.java +++ b/src/main/java/swe/context/logic/commands/FindCommand.java @@ -20,7 +20,7 @@ public class FindCommand extends Command { public static final String MESSAGE_USAGE = String.format( "%s: Finds contacts by name. Case insensitive. Requires full word match." + "%nParameters: KEYWORD..." - + "%nExample: %s alex Ben CHARLOTTE", + + "%nExample: %s amy Ben CHARLOTTE", FindCommand.COMMAND_WORD, FindCommand.COMMAND_WORD ); From 98f8afbb0d757bf0b1fcd183cc18aba7a47864a1 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:23:56 +0800 Subject: [PATCH 13/22] docs(UG): Fix filter keywords being optional --- docs/UserGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index b05a44fba36..be301e6093b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -206,7 +206,7 @@ e.g. `find Bee John` will match the names `Amy Bee` and `John Doe`. Search and display contacts with tag matching the given keywords (case-insensitive). **Format:** -`filter [KEYWORDS]` +`filter KEYWORDS` **Example:** From 4070deb17befe4499a666f98fb3c99e9296f3bed Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:28:08 +0800 Subject: [PATCH 14/22] feat(): Merge filter command usage with UG --- docs/UserGuide.md | 7 ++++--- .../swe/context/logic/commands/FilterCommand.java | 12 +++++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index be301e6093b..a6d6a5ecff9 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -203,14 +203,15 @@ e.g. `find Bee John` will match the names `Amy Bee` and `John Doe`. ### Filtering by tag: `filter` -Search and display contacts with tag matching the given keywords (case-insensitive). +Shows contacts with a tag that fully matches the specified tag (case-insensitive). **Format:** -`filter KEYWORDS` +`filter TAG` -**Example:** +**Examples:** - `filter NUS` +- `filter CS2103 course` ### Viewing help: `help` diff --git a/src/main/java/swe/context/logic/commands/FilterCommand.java b/src/main/java/swe/context/logic/commands/FilterCommand.java index a04b994926d..f36efb369a6 100644 --- a/src/main/java/swe/context/logic/commands/FilterCommand.java +++ b/src/main/java/swe/context/logic/commands/FilterCommand.java @@ -15,11 +15,13 @@ public class FilterCommand extends Command { public static final String COMMAND_WORD = "filter"; - public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Filters and lists all contacts whose tags match the" - + " specified tag in full. Case insensitive." - + "\nParameters: TAG" - + "\nExample: " + COMMAND_WORD + " Friend"; + public static final String MESSAGE_USAGE = String.format( + "%s: Filters contacts by tag. Case insensitive. Requires full tag match." + + "%nParameters: TAG" + + "%nExample: %s CS2103 course", + FilterCommand.COMMAND_WORD, + FilterCommand.COMMAND_WORD + ); private final ContainsTagPredicate predicate; From 70442135e471e8251fd7c3cc8c41376aa495901d Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:28:55 +0800 Subject: [PATCH 15/22] fix(src): Fix CS2103 typos --- src/main/java/swe/context/model/util/SampleContactsUtil.java | 4 ++-- src/test/java/swe/context/testutil/TestData.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/swe/context/model/util/SampleContactsUtil.java b/src/main/java/swe/context/model/util/SampleContactsUtil.java index 713728f4ed7..ba33496f905 100644 --- a/src/main/java/swe/context/model/util/SampleContactsUtil.java +++ b/src/main/java/swe/context/model/util/SampleContactsUtil.java @@ -26,7 +26,7 @@ private static Contact[] getSampleContactsArray() { new Phone("87438807"), new Email("e0705018@u.nus.edu"), new Note("CS2103 tutorial mate."), - getTagSet("NUS", "CS2013 course"), + getTagSet("NUS", "CS2103 course"), getAlternateContactSet("Telegram: amy_bee") ), new Contact( @@ -42,7 +42,7 @@ private static Contact[] getSampleContactsArray() { new Phone("83210283"), new Email("coliveiro@comp.nus.edu.sg"), new Note("CS2103 Prof."), - getTagSet("NUS", "CS2013 course", "prof"), + getTagSet("NUS", "CS2103 course", "prof"), getAlternateContactSet() ), new Contact( diff --git a/src/test/java/swe/context/testutil/TestData.java b/src/test/java/swe/context/testutil/TestData.java index b8cf7e6d334..302521874a4 100644 --- a/src/test/java/swe/context/testutil/TestData.java +++ b/src/test/java/swe/context/testutil/TestData.java @@ -48,7 +48,7 @@ public static final class Valid { public static final String EMAIL_AMY = "amy@example.com"; public static final String EMAIL_BOB = "bob@example.com"; public static final String NOTE_AMY = ""; - public static final String NOTE_BOB = "CS2013 tutorial mate."; + public static final String NOTE_BOB = "CS2103 tutorial mate."; public static final String NAME_DESC_AMY = " " + PREFIX_NAME + NAME_AMY; public static final String NAME_DESC_BOB = " " + PREFIX_NAME + NAME_BOB; public static final String PHONE_DESC_AMY = " " + PREFIX_PHONE + PHONE_AMY; From 05adbd8b230dd9280d3e44df5020595466ad9189 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:40:05 +0800 Subject: [PATCH 16/22] feat(src): Improve help command's uses --- src/main/java/swe/context/logic/Messages.java | 23 ++++++++++++++----- .../context/logic/commands/HelpCommand.java | 9 +++++--- .../swe/context/logic/parser/InputParser.java | 4 +++- .../swe/context/logic/LogicManagerTest.java | 3 ++- .../context/logic/parser/InputParserTest.java | 2 +- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/main/java/swe/context/logic/Messages.java b/src/main/java/swe/context/logic/Messages.java index 62927bc0ce2..835d999e35a 100644 --- a/src/main/java/swe/context/logic/Messages.java +++ b/src/main/java/swe/context/logic/Messages.java @@ -11,15 +11,15 @@ */ public final class Messages { // Generic commands - public static final String COMMAND_UNKNOWN = "Unknown command."; public static final String DUPLICATE_FIELDS - = "Multiple values specified for the following single-valued parameters(s): "; + = "Multiple values specified for the following single-valued parameters(s): "; public static final String COMMAND_DUPLICATE_CONTACT = "There is an existing contact with the same name."; - private static final String UNFORMATTED_COMMAND_INVALID_FORMAT = "Invalid command format.\n%s"; + private static final String UNFORMATTED_COMMAND_INVALID_FORMAT = "Invalid command format.%n%s"; + private static final String UNFORMATTED_COMMAND_UNKNOWN = "Unknown command.%n%s"; private static final String UNFORMATTED_CONTACTS_LISTED_OVERVIEW = "%d contacts listed."; - private static final String UNFORMATTED_ADD_COMMAND_SUCCESS = "New contact added: %1$s"; - private static final String UNFORMATTED_DELETE_COMMAND_SUCCESS = "Deleted contact(s): \n%1$s"; - private static final String UNFORMATTED_EDIT_COMMAND_SUCCESS = "Edited contact: %1$s"; + private static final String UNFORMATTED_ADD_COMMAND_SUCCESS = "New contact added: %s"; + private static final String UNFORMATTED_DELETE_COMMAND_SUCCESS = "Deleted contact(s):%n%s"; + private static final String UNFORMATTED_EDIT_COMMAND_SUCCESS = "Edited contact: %s"; // Specific commands public static final String COMMAND_EDIT_NO_PARAM = "At least one optional parameter to edit must be provided."; @@ -69,6 +69,17 @@ public static String commandInvalidFormat(String helpText) { ); } + /** + * Returns a formatted message about the command being unknown, with the + * specified help text. + */ + public static String commandUnknown(String helpText) { + return String.format( + Messages.UNFORMATTED_COMMAND_UNKNOWN, + helpText + ); + } + /** * Returns a formatted message about the specified tag name being invalid. */ diff --git a/src/main/java/swe/context/logic/commands/HelpCommand.java b/src/main/java/swe/context/logic/commands/HelpCommand.java index b271841f1e4..4a9d441f44b 100644 --- a/src/main/java/swe/context/logic/commands/HelpCommand.java +++ b/src/main/java/swe/context/logic/commands/HelpCommand.java @@ -3,15 +3,18 @@ import swe.context.logic.Messages; import swe.context.model.Model; + + /** * Format full help instructions for every command for display. */ public class HelpCommand extends Command { - public static final String COMMAND_WORD = "help"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Shows program usage instructions.\n" - + "Example: " + COMMAND_WORD; + public static final String MESSAGE_USAGE = String.format( + "%s: Opens the help window.", + HelpCommand.COMMAND_WORD + ); @Override public CommandResult execute(Model model) { diff --git a/src/main/java/swe/context/logic/parser/InputParser.java b/src/main/java/swe/context/logic/parser/InputParser.java index f86263e1b14..fed90f6b3a4 100644 --- a/src/main/java/swe/context/logic/parser/InputParser.java +++ b/src/main/java/swe/context/logic/parser/InputParser.java @@ -66,7 +66,9 @@ public static Command parseCommand(String userInput) throws ParseException { case ExitCommand.COMMAND_WORD: return new ExitCommand(); default: - throw new ParseException(Messages.COMMAND_UNKNOWN); + throw new ParseException( + Messages.commandUnknown(HelpCommand.MESSAGE_USAGE) + ); } } diff --git a/src/test/java/swe/context/logic/LogicManagerTest.java b/src/test/java/swe/context/logic/LogicManagerTest.java index 46abb2ca216..88598211f39 100644 --- a/src/test/java/swe/context/logic/LogicManagerTest.java +++ b/src/test/java/swe/context/logic/LogicManagerTest.java @@ -13,6 +13,7 @@ import swe.context.logic.commands.AddCommand; import swe.context.logic.commands.CommandResult; +import swe.context.logic.commands.HelpCommand; import swe.context.logic.commands.ListCommand; import swe.context.logic.commands.exceptions.CommandException; import swe.context.logic.parser.exceptions.ParseException; @@ -49,7 +50,7 @@ public void setUp() { @Test public void execute_invalidCommandFormat_throwsParseException() { String invalidCommand = "uicfhmowqewca"; - assertParseException(invalidCommand, Messages.COMMAND_UNKNOWN); + assertParseException(invalidCommand, Messages.commandUnknown(HelpCommand.MESSAGE_USAGE)); } @Test diff --git a/src/test/java/swe/context/logic/parser/InputParserTest.java b/src/test/java/swe/context/logic/parser/InputParserTest.java index 42a4c9aea47..3f92e70ec24 100644 --- a/src/test/java/swe/context/logic/parser/InputParserTest.java +++ b/src/test/java/swe/context/logic/parser/InputParserTest.java @@ -127,7 +127,7 @@ public void parseCommand_unrecognisedInput_throwsParseException() { public void parseCommand_unknownCommand_throwsParseException() { assertThrows( ParseException.class, - Messages.COMMAND_UNKNOWN, + Messages.commandUnknown(HelpCommand.MESSAGE_USAGE), () -> InputParser.parseCommand("unknownCommand") ); } From cb4122ab29d08b38beec2b13de4288376829eb43 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:46:08 +0800 Subject: [PATCH 17/22] docs(): Update from mockup to v1.3 UI --- .../{UI_Mockup.pptx => UiMockup.pptx} | Bin docs/images/Ui.png | Bin 17956 -> 63580 bytes 2 files changed, 0 insertions(+), 0 deletions(-) rename docs/diagrams/{UI_Mockup.pptx => UiMockup.pptx} (100%) diff --git a/docs/diagrams/UI_Mockup.pptx b/docs/diagrams/UiMockup.pptx similarity index 100% rename from docs/diagrams/UI_Mockup.pptx rename to docs/diagrams/UiMockup.pptx diff --git a/docs/images/Ui.png b/docs/images/Ui.png index 960dd2d5ff7662bc7a1303819b0ecdf19c89c4f3..23d8e203243c4c1e8c458b415632188b9d5dbbc1 100644 GIT binary patch literal 63580 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 V3A%ds5pYR}>P;=h!W;L{{{!EHL(%{M From 7c76f8aa4ebd0672dae240c03b8bd652c34a7173 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:53:20 +0800 Subject: [PATCH 18/22] style(Messages): Fix checkstyle --- src/main/java/swe/context/logic/Messages.java | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/main/java/swe/context/logic/Messages.java b/src/main/java/swe/context/logic/Messages.java index 835d999e35a..c4c22bd4ef7 100644 --- a/src/main/java/swe/context/logic/Messages.java +++ b/src/main/java/swe/context/logic/Messages.java @@ -13,7 +13,8 @@ public final class Messages { // Generic commands public static final String DUPLICATE_FIELDS = "Multiple values specified for the following single-valued parameters(s): "; - public static final String COMMAND_DUPLICATE_CONTACT = "There is an existing contact with the same name."; + public static final String COMMAND_DUPLICATE_CONTACT = + "There is an existing contact with the same name."; private static final String UNFORMATTED_COMMAND_INVALID_FORMAT = "Invalid command format.%n%s"; private static final String UNFORMATTED_COMMAND_UNKNOWN = "Unknown command.%n%s"; private static final String UNFORMATTED_CONTACTS_LISTED_OVERVIEW = "%d contacts listed."; @@ -22,7 +23,8 @@ public final class Messages { private static final String UNFORMATTED_EDIT_COMMAND_SUCCESS = "Edited contact: %s"; // Specific commands - public static final String COMMAND_EDIT_NO_PARAM = "At least one optional parameter to edit must be provided."; + public static final String COMMAND_EDIT_NO_PARAM = + "At least one optional parameter to edit must be provided."; public static final String COMMAND_CLEAR_SUCCESS = "Removed all contacts!"; public static final String COMMAND_LIST_SUCCESS = "Listed all contacts."; public static final String COMMAND_HELP_SUCCESS = "Opened help window."; @@ -32,29 +34,28 @@ public final class Messages { = "One or more of the contact indices provided are invalid."; public static final String INVALID_EDIT_INDEX = "The contact index provided is invalid."; - // Messages associated with Attributes constraints - public static final String NAME_INVALID - = "Names must be alphanumeric (spaces allowed)."; - public static final String PHONE_INVALID - = "Phone numbers must start with at least 3 digits."; - public static final String EMAIL_INVALID - = "Emails must roughly be of the form \"example_email@foo-domain.sg.\""; - private static final String UNFORMATTED_TAG_INVALID - = "\"%s\" is not a valid tag. Tags must be alphanumeric (spaces allowed)."; - - private static final String UNFORMATTED_ALTERNATECONTACT_INVALID - = "\"%s\" is not a valid alternate contact. " + // Validation messages for command parameter constraints + public static final String NAME_INVALID = "Names must be alphanumeric (spaces allowed)."; + public static final String PHONE_INVALID = "Phone numbers must start with at least 3 digits."; + public static final String EMAIL_INVALID = + "Emails must roughly be of the form \"example_email@foo-domain.sg.\""; + private static final String UNFORMATTED_TAG_INVALID = + "\"%s\" is not a valid tag. Tags must be alphanumeric (spaces allowed)."; + private static final String UNFORMATTED_ALTERNATECONTACT_INVALID = + "\"%s\" is not a valid alternate contact. " + "Alternate contacts must roughly be of the form \"socialMedia: name\""; // JSON - public static final String CONVERT_CONTACTS_DUPLICATE = "Encountered duplicate while converting contacts."; + public static final String CONVERT_CONTACTS_DUPLICATE = + "Encountered duplicate while converting contacts."; // Exceptions - public static final String DUPLICATE_CONTACT_EXCEPTION = "Operation would result in duplicate contacts"; - private static final String UNFORMATTED_FILE_OPS_ERROR_FORMAT - = "Could not save data due to the following error: %s"; - private static final String UNFORMATTED_FILE_OPS_PERMISSION_ERROR_FORMAT - = "Could not save data to file %s due to insufficient permissions to write to the file or the folder."; + public static final String DUPLICATE_CONTACT_EXCEPTION = + "Operation would result in duplicate contacts"; + private static final String UNFORMATTED_FILE_OPS_ERROR_FORMAT = + "Could not save data due to the following error: %s"; + private static final String UNFORMATTED_FILE_OPS_PERMISSION_ERROR_FORMAT = + "Could not save data to file %s due to insufficient permissions to write to the file or the folder."; private static final String UNFORMATTED_FIELD_MISSING = "Contact's %s field is missing."; From 27dc1eb7cb9b49e87faa9ed09df94654e5c33d76 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:54:23 +0800 Subject: [PATCH 19/22] style(main): Fix checkstyle --- src/main/java/swe/context/logic/parser/ParserUtil.java | 4 ++-- src/main/java/swe/context/ui/CommandBoxHistory.java | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/swe/context/logic/parser/ParserUtil.java b/src/main/java/swe/context/logic/parser/ParserUtil.java index dd9145978eb..c3ff39e6fe3 100644 --- a/src/main/java/swe/context/logic/parser/ParserUtil.java +++ b/src/main/java/swe/context/logic/parser/ParserUtil.java @@ -21,8 +21,8 @@ * Contains utility methods used for parsing strings in the various *Parser classes. */ public class ParserUtil { - public static final String MESSAGE_INDEX_NOT_POSITIVE - = "Index is not a non-zero unsigned integer."; + public static final String MESSAGE_INDEX_NOT_POSITIVE = + "Index is not a non-zero unsigned integer."; /** * Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing whitespaces will be diff --git a/src/main/java/swe/context/ui/CommandBoxHistory.java b/src/main/java/swe/context/ui/CommandBoxHistory.java index dd2cf12bb98..b80283a9651 100644 --- a/src/main/java/swe/context/ui/CommandBoxHistory.java +++ b/src/main/java/swe/context/ui/CommandBoxHistory.java @@ -82,8 +82,7 @@ public String next() { commandIndex++; if (commandIndex == commandList.size()) { return ""; - } - else { + } else { return commandList.get(commandIndex); } } @@ -99,8 +98,7 @@ public String previous() { commandIndex--; if (commandIndex == commandList.size()) { return ""; - } - else { + } else { return commandList.get(commandIndex); } } @@ -115,8 +113,7 @@ public String current() { } if (commandIndex == commandList.size()) { return ""; - } - else { + } else { return commandList.get(commandIndex); } } From 52e92d4413627599e1a6f69d1cc42cd9da2b1d60 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:54:57 +0800 Subject: [PATCH 20/22] style(Messages): Fix checkstyle --- src/main/java/swe/context/logic/Messages.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/swe/context/logic/Messages.java b/src/main/java/swe/context/logic/Messages.java index c4c22bd4ef7..5a6c53a5a39 100644 --- a/src/main/java/swe/context/logic/Messages.java +++ b/src/main/java/swe/context/logic/Messages.java @@ -11,8 +11,8 @@ */ public final class Messages { // Generic commands - public static final String DUPLICATE_FIELDS - = "Multiple values specified for the following single-valued parameters(s): "; + public static final String DUPLICATE_FIELDS = + "Multiple values specified for the following single-valued parameters(s): "; public static final String COMMAND_DUPLICATE_CONTACT = "There is an existing contact with the same name."; private static final String UNFORMATTED_COMMAND_INVALID_FORMAT = "Invalid command format.%n%s"; @@ -30,8 +30,8 @@ public final class Messages { public static final String COMMAND_HELP_SUCCESS = "Opened help window."; public static final String COMMAND_EXIT_SUCCESS = "Exiting app..."; - public static final String INVALID_DELETE_INDEX - = "One or more of the contact indices provided are invalid."; + public static final String INVALID_DELETE_INDEX = + "One or more of the contact indices provided are invalid."; public static final String INVALID_EDIT_INDEX = "The contact index provided is invalid."; // Validation messages for command parameter constraints From cdfb456dd5330674ac5f618ecc78b247208f1d7d Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:55:32 +0800 Subject: [PATCH 21/22] style(test): Fix checkstyle --- src/test/java/swe/context/logic/commands/FindCommandTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/swe/context/logic/commands/FindCommandTest.java b/src/test/java/swe/context/logic/commands/FindCommandTest.java index 8b5fafaea50..f13b38ab681 100644 --- a/src/test/java/swe/context/logic/commands/FindCommandTest.java +++ b/src/test/java/swe/context/logic/commands/FindCommandTest.java @@ -53,7 +53,7 @@ public void equals() { @Test public void execute_zeroKeywords_noContactFound() { - String expectedMessage = Messages.contactsListedOverview( 0); + String expectedMessage = Messages.contactsListedOverview(0); NameContainsKeywordsPredicate predicate = preparePredicate(" "); FindCommand command = new FindCommand(predicate); expectedModel.setContactsFilter(predicate); From 3ec8d2adf42a86d43b8f09120780890e1da6f7c2 Mon Sep 17 00:00:00 2001 From: Cloud <44526554+Cloud7050@users.noreply.github.com> Date: Fri, 3 Nov 2023 01:03:58 +0800 Subject: [PATCH 22/22] feat(Messages): Make alternate match docs --- src/main/java/swe/context/logic/Messages.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/swe/context/logic/Messages.java b/src/main/java/swe/context/logic/Messages.java index 5a6c53a5a39..205ef32bfaf 100644 --- a/src/main/java/swe/context/logic/Messages.java +++ b/src/main/java/swe/context/logic/Messages.java @@ -43,7 +43,7 @@ public final class Messages { "\"%s\" is not a valid tag. Tags must be alphanumeric (spaces allowed)."; private static final String UNFORMATTED_ALTERNATECONTACT_INVALID = "\"%s\" is not a valid alternate contact. " - + "Alternate contacts must roughly be of the form \"socialMedia: name\""; + + "Alternate contacts must roughly be of the form \"SocialMedia: Username\""; // JSON public static final String CONVERT_CONTACTS_DUPLICATE =