diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
new file mode 100644
index 00000000000..1e1862b0e82
--- /dev/null
+++ b/.github/workflows/docs.yml
@@ -0,0 +1,25 @@
+name: MarkBind Action
+
+on:
+ push:
+ branches:
+ - master
+
+jobs:
+ build_and_deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install Graphviz
+ run: sudo apt-get install graphviz
+ - name: Install Java
+ uses: actions/setup-java@v3
+ with:
+ java-version: '11'
+ distribution: 'temurin'
+ - name: Build & Deploy MarkBind site
+ uses: MarkBind/markbind-action@v2
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ rootDirectory: './docs'
+ baseUrl: '/tp' # replace with your repo name
+ version: '^5.1.0'
diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
index 6ff220b5196..ca85dcec3c1 100644
--- a/.github/workflows/gradle.yml
+++ b/.github/workflows/gradle.yml
@@ -22,7 +22,7 @@ jobs:
run: git checkout --progress --force ${{ github.sha }}
- name: Run repository-wide tests
- if: runner.os == 'Linux'
+ if: runner.os == 'macOS'
working-directory: ${{ github.workspace }}/.github
run: ./run-checks.sh
@@ -39,7 +39,7 @@ jobs:
run: ./gradlew check coverage
- name: Upload coverage reports to Codecov
- if: runner.os == 'Linux'
+ if: runner.os == 'macOS'
uses: codecov/codecov-action@v3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 284c4ca7cd9..eab4c7db6a5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,4 @@ src/test/data/sandbox/
# MacOS custom attributes files created by Finder
.DS_Store
docs/_site/
+docs/_markbind/logs/
diff --git a/LICENSE b/LICENSE
index 39b3478982c..a5875d64fe8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -2,11 +2,11 @@ MIT License
Copyright (c) 2016 Software Engineering Education - FOSS Resources
-Permission is hereby granted, free of charge, to any person obtaining a copy
+Permission is hereby granted, free of charge, to any date obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
+copies of the Software, and to permit dates to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
diff --git a/README.md b/README.md
index 13f5c77403f..af7fc822c1c 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,5 @@
-[![CI Status](https://github.com/se-edu/addressbook-level3/workflows/Java%20CI/badge.svg)](https://github.com/se-edu/addressbook-level3/actions)
+[![CI Status](https://github.com/AY2324S1-CS2103T-F10-2/tp/workflows/Java%20CI/badge.svg)](https://github.com/AY2324S1-CS2103T-F10-2/tp/actions)
![Ui](docs/images/Ui.png)
-* This is **a sample project for Software Engineering (SE) students**.
- Example usages:
- * as a starting point of a course project (as opposed to writing everything from scratch)
- * as a case study
-* The project simulates an ongoing software project for a desktop application (called _AddressBook_) used for managing contact details.
- * It is **written in OOP fashion**. It provides a **reasonably well-written** code base **bigger** (around 6 KLoC) than what students usually write in beginner-level SE modules, without being overwhelmingly big.
- * It comes with a **reasonable level of user and developer documentation**.
-* It is named `AddressBook Level 3` (`AB3` for short) because it was initially created as a part of a series of `AddressBook` projects (`Level 1`, `Level 2`, `Level 3` ...).
-* For the detailed documentation of this project, see the **[Address Book Product Website](https://se-education.org/addressbook-level3)**.
-* This project is a **part of the se-education.org** initiative. If you would like to contribute code to this project, see [se-education.org](https://se-education.org#https://se-education.org/#contributing) for more info.
+This is a sample project for LoveBook. Yay!
diff --git a/bin/main/images/address_book_32.png b/bin/main/images/address_book_32.png
new file mode 100644
index 00000000000..29810cf1fd9
Binary files /dev/null and b/bin/main/images/address_book_32.png differ
diff --git a/bin/main/images/calendar.png b/bin/main/images/calendar.png
new file mode 100644
index 00000000000..8b2bdf4f1c1
Binary files /dev/null and b/bin/main/images/calendar.png differ
diff --git a/bin/main/images/clock.png b/bin/main/images/clock.png
new file mode 100644
index 00000000000..0807cbf6451
Binary files /dev/null and b/bin/main/images/clock.png differ
diff --git a/bin/main/images/fail.png b/bin/main/images/fail.png
new file mode 100644
index 00000000000..6daf01290dd
Binary files /dev/null and b/bin/main/images/fail.png differ
diff --git a/bin/main/images/help_icon.png b/bin/main/images/help_icon.png
new file mode 100644
index 00000000000..f8e80d6c1c5
Binary files /dev/null and b/bin/main/images/help_icon.png differ
diff --git a/bin/main/images/info_icon.png b/bin/main/images/info_icon.png
new file mode 100644
index 00000000000..f8cef714095
Binary files /dev/null and b/bin/main/images/info_icon.png differ
diff --git a/bin/main/seedu/lovebook/AppParameters.class b/bin/main/seedu/lovebook/AppParameters.class
new file mode 100644
index 00000000000..65311d3f3b4
Binary files /dev/null and b/bin/main/seedu/lovebook/AppParameters.class differ
diff --git a/bin/main/seedu/lovebook/Main.class b/bin/main/seedu/lovebook/Main.class
new file mode 100644
index 00000000000..5eb9a153ed7
Binary files /dev/null and b/bin/main/seedu/lovebook/Main.class differ
diff --git a/bin/main/seedu/lovebook/MainApp.class b/bin/main/seedu/lovebook/MainApp.class
new file mode 100644
index 00000000000..d899cc238ae
Binary files /dev/null and b/bin/main/seedu/lovebook/MainApp.class differ
diff --git a/bin/main/seedu/lovebook/commons/core/Config.class b/bin/main/seedu/lovebook/commons/core/Config.class
new file mode 100644
index 00000000000..21917e89cca
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/core/Config.class differ
diff --git a/bin/main/seedu/lovebook/commons/core/GuiSettings.class b/bin/main/seedu/lovebook/commons/core/GuiSettings.class
new file mode 100644
index 00000000000..572386b3038
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/core/GuiSettings.class differ
diff --git a/bin/main/seedu/lovebook/commons/core/LogsCenter.class b/bin/main/seedu/lovebook/commons/core/LogsCenter.class
new file mode 100644
index 00000000000..b135388ab48
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/core/LogsCenter.class differ
diff --git a/bin/main/seedu/lovebook/commons/core/Version.class b/bin/main/seedu/lovebook/commons/core/Version.class
new file mode 100644
index 00000000000..6eb8f4289dc
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/core/Version.class differ
diff --git a/bin/main/seedu/lovebook/commons/core/index/Index.class b/bin/main/seedu/lovebook/commons/core/index/Index.class
new file mode 100644
index 00000000000..f9c27896d39
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/core/index/Index.class differ
diff --git a/bin/main/seedu/lovebook/commons/exceptions/DataLoadingException.class b/bin/main/seedu/lovebook/commons/exceptions/DataLoadingException.class
new file mode 100644
index 00000000000..108063a5f06
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/exceptions/DataLoadingException.class differ
diff --git a/bin/main/seedu/lovebook/commons/exceptions/IllegalValueException.class b/bin/main/seedu/lovebook/commons/exceptions/IllegalValueException.class
new file mode 100644
index 00000000000..1be3a983167
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/exceptions/IllegalValueException.class differ
diff --git a/bin/main/seedu/lovebook/commons/util/AppUtil.class b/bin/main/seedu/lovebook/commons/util/AppUtil.class
new file mode 100644
index 00000000000..183991a0cda
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/util/AppUtil.class differ
diff --git a/bin/main/seedu/lovebook/commons/util/CollectionUtil.class b/bin/main/seedu/lovebook/commons/util/CollectionUtil.class
new file mode 100644
index 00000000000..529a189b130
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/util/CollectionUtil.class differ
diff --git a/bin/main/seedu/lovebook/commons/util/ConfigUtil.class b/bin/main/seedu/lovebook/commons/util/ConfigUtil.class
new file mode 100644
index 00000000000..a3a51d58ee7
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/util/ConfigUtil.class differ
diff --git a/bin/main/seedu/lovebook/commons/util/FileUtil.class b/bin/main/seedu/lovebook/commons/util/FileUtil.class
new file mode 100644
index 00000000000..8681098c69a
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/util/FileUtil.class differ
diff --git a/bin/main/seedu/lovebook/commons/util/JsonUtil$LevelDeserializer.class b/bin/main/seedu/lovebook/commons/util/JsonUtil$LevelDeserializer.class
new file mode 100644
index 00000000000..8182abe92ff
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/util/JsonUtil$LevelDeserializer.class differ
diff --git a/bin/main/seedu/lovebook/commons/util/JsonUtil.class b/bin/main/seedu/lovebook/commons/util/JsonUtil.class
new file mode 100644
index 00000000000..f109f3bf58a
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/util/JsonUtil.class differ
diff --git a/bin/main/seedu/lovebook/commons/util/PredicatesUtil.class b/bin/main/seedu/lovebook/commons/util/PredicatesUtil.class
new file mode 100644
index 00000000000..1c4b6ede746
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/util/PredicatesUtil.class differ
diff --git a/bin/main/seedu/lovebook/commons/util/StringUtil.class b/bin/main/seedu/lovebook/commons/util/StringUtil.class
new file mode 100644
index 00000000000..474f01c420d
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/util/StringUtil.class differ
diff --git a/bin/main/seedu/lovebook/commons/util/ToStringBuilder.class b/bin/main/seedu/lovebook/commons/util/ToStringBuilder.class
new file mode 100644
index 00000000000..5434311c6bc
Binary files /dev/null and b/bin/main/seedu/lovebook/commons/util/ToStringBuilder.class differ
diff --git a/bin/main/seedu/lovebook/logic/Logic.class b/bin/main/seedu/lovebook/logic/Logic.class
new file mode 100644
index 00000000000..9d9d6729715
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/Logic.class differ
diff --git a/bin/main/seedu/lovebook/logic/LogicManager.class b/bin/main/seedu/lovebook/logic/LogicManager.class
new file mode 100644
index 00000000000..e188233ee50
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/LogicManager.class differ
diff --git a/bin/main/seedu/lovebook/logic/Messages.class b/bin/main/seedu/lovebook/logic/Messages.class
new file mode 100644
index 00000000000..8969548ba8c
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/Messages.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/AddCommand.class b/bin/main/seedu/lovebook/logic/commands/AddCommand.class
new file mode 100644
index 00000000000..d0443d3b653
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/AddCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/BestMatchCommand.class b/bin/main/seedu/lovebook/logic/commands/BestMatchCommand.class
new file mode 100644
index 00000000000..42a9332e721
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/BestMatchCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/BlindDateCommand.class b/bin/main/seedu/lovebook/logic/commands/BlindDateCommand.class
new file mode 100644
index 00000000000..9e66d7ff48c
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/BlindDateCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/ClearCommand.class b/bin/main/seedu/lovebook/logic/commands/ClearCommand.class
new file mode 100644
index 00000000000..95a61a0dc21
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/ClearCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/Command.class b/bin/main/seedu/lovebook/logic/commands/Command.class
new file mode 100644
index 00000000000..ca9ce8bdff2
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/Command.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/CommandResult.class b/bin/main/seedu/lovebook/logic/commands/CommandResult.class
new file mode 100644
index 00000000000..f82dd2a0500
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/CommandResult.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/DeleteCommand.class b/bin/main/seedu/lovebook/logic/commands/DeleteCommand.class
new file mode 100644
index 00000000000..7a88a18ced7
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/DeleteCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/EditCommand$EditPersonDescriptor.class b/bin/main/seedu/lovebook/logic/commands/EditCommand$EditPersonDescriptor.class
new file mode 100644
index 00000000000..3d90d0140a7
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/EditCommand$EditPersonDescriptor.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/EditCommand.class b/bin/main/seedu/lovebook/logic/commands/EditCommand.class
new file mode 100644
index 00000000000..db9629d1293
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/EditCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/ExitCommand.class b/bin/main/seedu/lovebook/logic/commands/ExitCommand.class
new file mode 100644
index 00000000000..07f61c29cde
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/ExitCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/FilterCommand.class b/bin/main/seedu/lovebook/logic/commands/FilterCommand.class
new file mode 100644
index 00000000000..bdeac67d644
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/FilterCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/FindCommand.class b/bin/main/seedu/lovebook/logic/commands/FindCommand.class
new file mode 100644
index 00000000000..b59b5e967ca
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/FindCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/HelpCommand.class b/bin/main/seedu/lovebook/logic/commands/HelpCommand.class
new file mode 100644
index 00000000000..0694fdf158b
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/HelpCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/ListCommand.class b/bin/main/seedu/lovebook/logic/commands/ListCommand.class
new file mode 100644
index 00000000000..5b0b7a933f4
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/ListCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/SetPrefCommand$SetPreferenceDescriptor.class b/bin/main/seedu/lovebook/logic/commands/SetPrefCommand$SetPreferenceDescriptor.class
new file mode 100644
index 00000000000..d7d3a20c9ae
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/SetPrefCommand$SetPreferenceDescriptor.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/SetPrefCommand.class b/bin/main/seedu/lovebook/logic/commands/SetPrefCommand.class
new file mode 100644
index 00000000000..2a3dc1f4be8
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/SetPrefCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/ShowPrefCommand.class b/bin/main/seedu/lovebook/logic/commands/ShowPrefCommand.class
new file mode 100644
index 00000000000..9d92653b9ba
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/ShowPrefCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/SortCommand.class b/bin/main/seedu/lovebook/logic/commands/SortCommand.class
new file mode 100644
index 00000000000..d706a955476
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/SortCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/StarCommand.class b/bin/main/seedu/lovebook/logic/commands/StarCommand.class
new file mode 100644
index 00000000000..da0ae9c37c9
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/StarCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/UnstarCommand.class b/bin/main/seedu/lovebook/logic/commands/UnstarCommand.class
new file mode 100644
index 00000000000..e3945b81731
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/UnstarCommand.class differ
diff --git a/bin/main/seedu/lovebook/logic/commands/exceptions/CommandException.class b/bin/main/seedu/lovebook/logic/commands/exceptions/CommandException.class
new file mode 100644
index 00000000000..343674ffc9e
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/commands/exceptions/CommandException.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/AddCommandParser.class b/bin/main/seedu/lovebook/logic/parser/AddCommandParser.class
new file mode 100644
index 00000000000..408ccaf9b2b
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/AddCommandParser.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/ArgumentMultimap.class b/bin/main/seedu/lovebook/logic/parser/ArgumentMultimap.class
new file mode 100644
index 00000000000..21dfe0480ca
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/ArgumentMultimap.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/ArgumentTokenizer$PrefixPosition.class b/bin/main/seedu/lovebook/logic/parser/ArgumentTokenizer$PrefixPosition.class
new file mode 100644
index 00000000000..4a092d6eebe
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/ArgumentTokenizer$PrefixPosition.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/ArgumentTokenizer.class b/bin/main/seedu/lovebook/logic/parser/ArgumentTokenizer.class
new file mode 100644
index 00000000000..f4a31f7b4f9
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/ArgumentTokenizer.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/CliSyntax.class b/bin/main/seedu/lovebook/logic/parser/CliSyntax.class
new file mode 100644
index 00000000000..36dfbd9af02
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/CliSyntax.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/DeleteCommandParser.class b/bin/main/seedu/lovebook/logic/parser/DeleteCommandParser.class
new file mode 100644
index 00000000000..232d99f6c11
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/DeleteCommandParser.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/EditCommandParser.class b/bin/main/seedu/lovebook/logic/parser/EditCommandParser.class
new file mode 100644
index 00000000000..27908e85a8e
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/EditCommandParser.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/FilterCommandParser.class b/bin/main/seedu/lovebook/logic/parser/FilterCommandParser.class
new file mode 100644
index 00000000000..ef2c3e7d623
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/FilterCommandParser.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/FindCommandParser.class b/bin/main/seedu/lovebook/logic/parser/FindCommandParser.class
new file mode 100644
index 00000000000..1a6088f7d68
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/FindCommandParser.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/LoveBookParser.class b/bin/main/seedu/lovebook/logic/parser/LoveBookParser.class
new file mode 100644
index 00000000000..d890666c4fa
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/LoveBookParser.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/Parser.class b/bin/main/seedu/lovebook/logic/parser/Parser.class
new file mode 100644
index 00000000000..7e3dc2dd6f3
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/Parser.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/ParserUtil.class b/bin/main/seedu/lovebook/logic/parser/ParserUtil.class
new file mode 100644
index 00000000000..62d16a1255f
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/ParserUtil.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/Prefix.class b/bin/main/seedu/lovebook/logic/parser/Prefix.class
new file mode 100644
index 00000000000..2fe719c2ebd
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/Prefix.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/SetPrefCommandParser.class b/bin/main/seedu/lovebook/logic/parser/SetPrefCommandParser.class
new file mode 100644
index 00000000000..bd096a7b107
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/SetPrefCommandParser.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/SortCommandParser.class b/bin/main/seedu/lovebook/logic/parser/SortCommandParser.class
new file mode 100644
index 00000000000..c9f0f09fcc3
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/SortCommandParser.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/StarCommandParser.class b/bin/main/seedu/lovebook/logic/parser/StarCommandParser.class
new file mode 100644
index 00000000000..3acb987346b
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/StarCommandParser.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/UnstarCommandParser.class b/bin/main/seedu/lovebook/logic/parser/UnstarCommandParser.class
new file mode 100644
index 00000000000..9811bcdfe3e
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/UnstarCommandParser.class differ
diff --git a/bin/main/seedu/lovebook/logic/parser/exceptions/ParseException.class b/bin/main/seedu/lovebook/logic/parser/exceptions/ParseException.class
new file mode 100644
index 00000000000..609a26d7bdd
Binary files /dev/null and b/bin/main/seedu/lovebook/logic/parser/exceptions/ParseException.class differ
diff --git a/bin/main/seedu/lovebook/model/DatePrefs.class b/bin/main/seedu/lovebook/model/DatePrefs.class
new file mode 100644
index 00000000000..6a02fb767e1
Binary files /dev/null and b/bin/main/seedu/lovebook/model/DatePrefs.class differ
diff --git a/bin/main/seedu/lovebook/model/LoveBook.class b/bin/main/seedu/lovebook/model/LoveBook.class
new file mode 100644
index 00000000000..1b20133b158
Binary files /dev/null and b/bin/main/seedu/lovebook/model/LoveBook.class differ
diff --git a/bin/main/seedu/lovebook/model/Model.class b/bin/main/seedu/lovebook/model/Model.class
new file mode 100644
index 00000000000..69c63fc1302
Binary files /dev/null and b/bin/main/seedu/lovebook/model/Model.class differ
diff --git a/bin/main/seedu/lovebook/model/ModelManager.class b/bin/main/seedu/lovebook/model/ModelManager.class
new file mode 100644
index 00000000000..114a1a3d988
Binary files /dev/null and b/bin/main/seedu/lovebook/model/ModelManager.class differ
diff --git a/bin/main/seedu/lovebook/model/ReadOnlyDatePrefs.class b/bin/main/seedu/lovebook/model/ReadOnlyDatePrefs.class
new file mode 100644
index 00000000000..9336d63a913
Binary files /dev/null and b/bin/main/seedu/lovebook/model/ReadOnlyDatePrefs.class differ
diff --git a/bin/main/seedu/lovebook/model/ReadOnlyLoveBook.class b/bin/main/seedu/lovebook/model/ReadOnlyLoveBook.class
new file mode 100644
index 00000000000..26ac8bed2ed
Binary files /dev/null and b/bin/main/seedu/lovebook/model/ReadOnlyLoveBook.class differ
diff --git a/bin/main/seedu/lovebook/model/ReadOnlyUserPrefs.class b/bin/main/seedu/lovebook/model/ReadOnlyUserPrefs.class
new file mode 100644
index 00000000000..b091e827372
Binary files /dev/null and b/bin/main/seedu/lovebook/model/ReadOnlyUserPrefs.class differ
diff --git a/bin/main/seedu/lovebook/model/UserPrefs.class b/bin/main/seedu/lovebook/model/UserPrefs.class
new file mode 100644
index 00000000000..dde904da3e9
Binary files /dev/null and b/bin/main/seedu/lovebook/model/UserPrefs.class differ
diff --git a/bin/main/seedu/lovebook/model/date/Age.class b/bin/main/seedu/lovebook/model/date/Age.class
new file mode 100644
index 00000000000..8ade997c666
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/Age.class differ
diff --git a/bin/main/seedu/lovebook/model/date/Avatar.class b/bin/main/seedu/lovebook/model/date/Avatar.class
new file mode 100644
index 00000000000..2d27d0c35ae
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/Avatar.class differ
diff --git a/bin/main/seedu/lovebook/model/date/Date.class b/bin/main/seedu/lovebook/model/date/Date.class
new file mode 100644
index 00000000000..73754ba5fb3
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/Date.class differ
diff --git a/bin/main/seedu/lovebook/model/date/Gender.class b/bin/main/seedu/lovebook/model/date/Gender.class
new file mode 100644
index 00000000000..90d9bef2edc
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/Gender.class differ
diff --git a/bin/main/seedu/lovebook/model/date/Height.class b/bin/main/seedu/lovebook/model/date/Height.class
new file mode 100644
index 00000000000..7303c267b8d
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/Height.class differ
diff --git a/bin/main/seedu/lovebook/model/date/Income.class b/bin/main/seedu/lovebook/model/date/Income.class
new file mode 100644
index 00000000000..0b2d867bd0d
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/Income.class differ
diff --git a/bin/main/seedu/lovebook/model/date/MetricContainsKeywordPredicate.class b/bin/main/seedu/lovebook/model/date/MetricContainsKeywordPredicate.class
new file mode 100644
index 00000000000..039e29dcc9a
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/MetricContainsKeywordPredicate.class differ
diff --git a/bin/main/seedu/lovebook/model/date/Name.class b/bin/main/seedu/lovebook/model/date/Name.class
new file mode 100644
index 00000000000..4cae1564feb
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/Name.class differ
diff --git a/bin/main/seedu/lovebook/model/date/NameContainsKeywordsPredicate.class b/bin/main/seedu/lovebook/model/date/NameContainsKeywordsPredicate.class
new file mode 100644
index 00000000000..13a65078c24
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/NameContainsKeywordsPredicate.class differ
diff --git a/bin/main/seedu/lovebook/model/date/RandomPredicate.class b/bin/main/seedu/lovebook/model/date/RandomPredicate.class
new file mode 100644
index 00000000000..eecff95e584
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/RandomPredicate.class differ
diff --git a/bin/main/seedu/lovebook/model/date/Star.class b/bin/main/seedu/lovebook/model/date/Star.class
new file mode 100644
index 00000000000..d3d4881eaa3
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/Star.class differ
diff --git a/bin/main/seedu/lovebook/model/date/UniqueDateList.class b/bin/main/seedu/lovebook/model/date/UniqueDateList.class
new file mode 100644
index 00000000000..f2bdf0b57fd
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/UniqueDateList.class differ
diff --git a/bin/main/seedu/lovebook/model/date/exceptions/DuplicatePersonException.class b/bin/main/seedu/lovebook/model/date/exceptions/DuplicatePersonException.class
new file mode 100644
index 00000000000..e6760440500
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/exceptions/DuplicatePersonException.class differ
diff --git a/bin/main/seedu/lovebook/model/date/exceptions/PersonNotFoundException.class b/bin/main/seedu/lovebook/model/date/exceptions/PersonNotFoundException.class
new file mode 100644
index 00000000000..516a8e74a3b
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/exceptions/PersonNotFoundException.class differ
diff --git a/bin/main/seedu/lovebook/model/date/horoscope/Horoscope.class b/bin/main/seedu/lovebook/model/date/horoscope/Horoscope.class
new file mode 100644
index 00000000000..f9785ae73b2
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/horoscope/Horoscope.class differ
diff --git a/bin/main/seedu/lovebook/model/date/horoscope/HoroscopeEnum.class b/bin/main/seedu/lovebook/model/date/horoscope/HoroscopeEnum.class
new file mode 100644
index 00000000000..65c9f9850fc
Binary files /dev/null and b/bin/main/seedu/lovebook/model/date/horoscope/HoroscopeEnum.class differ
diff --git a/bin/main/seedu/lovebook/model/person/Age.class b/bin/main/seedu/lovebook/model/person/Age.class
new file mode 100644
index 00000000000..9b1cff0294d
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/Age.class differ
diff --git a/bin/main/seedu/lovebook/model/person/Date.class b/bin/main/seedu/lovebook/model/person/Date.class
new file mode 100644
index 00000000000..5e1afd84721
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/Date.class differ
diff --git a/bin/main/seedu/lovebook/model/person/Gender.class b/bin/main/seedu/lovebook/model/person/Gender.class
new file mode 100644
index 00000000000..556cb0716c8
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/Gender.class differ
diff --git a/bin/main/seedu/lovebook/model/person/Height.class b/bin/main/seedu/lovebook/model/person/Height.class
new file mode 100644
index 00000000000..82e91c90b15
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/Height.class differ
diff --git a/bin/main/seedu/lovebook/model/person/Horoscope.class b/bin/main/seedu/lovebook/model/person/Horoscope.class
new file mode 100644
index 00000000000..686e9eaad2d
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/Horoscope.class differ
diff --git a/bin/main/seedu/lovebook/model/person/Income.class b/bin/main/seedu/lovebook/model/person/Income.class
new file mode 100644
index 00000000000..c95ad9be7b7
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/Income.class differ
diff --git a/bin/main/seedu/lovebook/model/person/MetricContainsKeywordPredicate.class b/bin/main/seedu/lovebook/model/person/MetricContainsKeywordPredicate.class
new file mode 100644
index 00000000000..f86b8b770e3
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/MetricContainsKeywordPredicate.class differ
diff --git a/bin/main/seedu/lovebook/model/person/Name.class b/bin/main/seedu/lovebook/model/person/Name.class
new file mode 100644
index 00000000000..0e610ac1e3d
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/Name.class differ
diff --git a/bin/main/seedu/lovebook/model/person/NameContainsKeywordsPredicate.class b/bin/main/seedu/lovebook/model/person/NameContainsKeywordsPredicate.class
new file mode 100644
index 00000000000..d16578d0fa5
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/NameContainsKeywordsPredicate.class differ
diff --git a/bin/main/seedu/lovebook/model/person/UniquePersonList.class b/bin/main/seedu/lovebook/model/person/UniquePersonList.class
new file mode 100644
index 00000000000..8aba2e5e970
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/UniquePersonList.class differ
diff --git a/bin/main/seedu/lovebook/model/person/User.class b/bin/main/seedu/lovebook/model/person/User.class
new file mode 100644
index 00000000000..1bf21cb1d42
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/User.class differ
diff --git a/bin/main/seedu/lovebook/model/person/exceptions/DuplicatePersonException.class b/bin/main/seedu/lovebook/model/person/exceptions/DuplicatePersonException.class
new file mode 100644
index 00000000000..890076c19b9
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/exceptions/DuplicatePersonException.class differ
diff --git a/bin/main/seedu/lovebook/model/person/exceptions/PersonNotFoundException.class b/bin/main/seedu/lovebook/model/person/exceptions/PersonNotFoundException.class
new file mode 100644
index 00000000000..6b3ac0341e8
Binary files /dev/null and b/bin/main/seedu/lovebook/model/person/exceptions/PersonNotFoundException.class differ
diff --git a/bin/main/seedu/lovebook/model/tag/Tag.class b/bin/main/seedu/lovebook/model/tag/Tag.class
new file mode 100644
index 00000000000..d77c5425040
Binary files /dev/null and b/bin/main/seedu/lovebook/model/tag/Tag.class differ
diff --git a/bin/main/seedu/lovebook/model/util/SampleDataUtil.class b/bin/main/seedu/lovebook/model/util/SampleDataUtil.class
new file mode 100644
index 00000000000..0d46e09d780
Binary files /dev/null and b/bin/main/seedu/lovebook/model/util/SampleDataUtil.class differ
diff --git a/bin/main/seedu/lovebook/model/util/SampleDatePrefUtil.class b/bin/main/seedu/lovebook/model/util/SampleDatePrefUtil.class
new file mode 100644
index 00000000000..10b704c9da7
Binary files /dev/null and b/bin/main/seedu/lovebook/model/util/SampleDatePrefUtil.class differ
diff --git a/bin/main/seedu/lovebook/storage/DatePrefsStorage.class b/bin/main/seedu/lovebook/storage/DatePrefsStorage.class
new file mode 100644
index 00000000000..24cebde664f
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/DatePrefsStorage.class differ
diff --git a/bin/main/seedu/lovebook/storage/JsonAdaptedDate.class b/bin/main/seedu/lovebook/storage/JsonAdaptedDate.class
new file mode 100644
index 00000000000..8f06f285a2f
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/JsonAdaptedDate.class differ
diff --git a/bin/main/seedu/lovebook/storage/JsonAdaptedDatePrefs.class b/bin/main/seedu/lovebook/storage/JsonAdaptedDatePrefs.class
new file mode 100644
index 00000000000..f56759b6aa4
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/JsonAdaptedDatePrefs.class differ
diff --git a/bin/main/seedu/lovebook/storage/JsonAdaptedPerson.class b/bin/main/seedu/lovebook/storage/JsonAdaptedPerson.class
new file mode 100644
index 00000000000..5bec486dbcf
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/JsonAdaptedPerson.class differ
diff --git a/bin/main/seedu/lovebook/storage/JsonAdaptedTag.class b/bin/main/seedu/lovebook/storage/JsonAdaptedTag.class
new file mode 100644
index 00000000000..5dd64afe915
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/JsonAdaptedTag.class differ
diff --git a/bin/main/seedu/lovebook/storage/JsonDatePrefsStorage.class b/bin/main/seedu/lovebook/storage/JsonDatePrefsStorage.class
new file mode 100644
index 00000000000..41da74d82ea
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/JsonDatePrefsStorage.class differ
diff --git a/bin/main/seedu/lovebook/storage/JsonLoveBookStorage.class b/bin/main/seedu/lovebook/storage/JsonLoveBookStorage.class
new file mode 100644
index 00000000000..c26701605cb
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/JsonLoveBookStorage.class differ
diff --git a/bin/main/seedu/lovebook/storage/JsonSerializableDatePrefs.class b/bin/main/seedu/lovebook/storage/JsonSerializableDatePrefs.class
new file mode 100644
index 00000000000..47ec16f836f
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/JsonSerializableDatePrefs.class differ
diff --git a/bin/main/seedu/lovebook/storage/JsonSerializableLoveBook.class b/bin/main/seedu/lovebook/storage/JsonSerializableLoveBook.class
new file mode 100644
index 00000000000..cc32ec4083d
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/JsonSerializableLoveBook.class differ
diff --git a/bin/main/seedu/lovebook/storage/JsonUserPrefsStorage.class b/bin/main/seedu/lovebook/storage/JsonUserPrefsStorage.class
new file mode 100644
index 00000000000..ca4612b81df
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/JsonUserPrefsStorage.class differ
diff --git a/bin/main/seedu/lovebook/storage/LoveBookStorage.class b/bin/main/seedu/lovebook/storage/LoveBookStorage.class
new file mode 100644
index 00000000000..fcd9c49b25d
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/LoveBookStorage.class differ
diff --git a/bin/main/seedu/lovebook/storage/Storage.class b/bin/main/seedu/lovebook/storage/Storage.class
new file mode 100644
index 00000000000..32ca6d8db72
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/Storage.class differ
diff --git a/bin/main/seedu/lovebook/storage/StorageManager.class b/bin/main/seedu/lovebook/storage/StorageManager.class
new file mode 100644
index 00000000000..ce371664847
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/StorageManager.class differ
diff --git a/bin/main/seedu/lovebook/storage/UserPrefsStorage.class b/bin/main/seedu/lovebook/storage/UserPrefsStorage.class
new file mode 100644
index 00000000000..9471aa669d5
Binary files /dev/null and b/bin/main/seedu/lovebook/storage/UserPrefsStorage.class differ
diff --git a/bin/main/seedu/lovebook/ui/CommandBox$CommandExecutor.class b/bin/main/seedu/lovebook/ui/CommandBox$CommandExecutor.class
new file mode 100644
index 00000000000..45033e723b4
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/CommandBox$CommandExecutor.class differ
diff --git a/bin/main/seedu/lovebook/ui/CommandBox.class b/bin/main/seedu/lovebook/ui/CommandBox.class
new file mode 100644
index 00000000000..9dca8f42abb
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/CommandBox.class differ
diff --git a/bin/main/seedu/lovebook/ui/DateCard.class b/bin/main/seedu/lovebook/ui/DateCard.class
new file mode 100644
index 00000000000..68907bf9dbd
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/DateCard.class differ
diff --git a/bin/main/seedu/lovebook/ui/DateListPanel$PersonListViewCell.class b/bin/main/seedu/lovebook/ui/DateListPanel$PersonListViewCell.class
new file mode 100644
index 00000000000..b4568ae00bf
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/DateListPanel$PersonListViewCell.class differ
diff --git a/bin/main/seedu/lovebook/ui/DateListPanel.class b/bin/main/seedu/lovebook/ui/DateListPanel.class
new file mode 100644
index 00000000000..0a1d83758ad
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/DateListPanel.class differ
diff --git a/bin/main/seedu/lovebook/ui/HelpWindow.class b/bin/main/seedu/lovebook/ui/HelpWindow.class
new file mode 100644
index 00000000000..fb9b8cbba22
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/HelpWindow.class differ
diff --git a/bin/main/seedu/lovebook/ui/MainWindow.class b/bin/main/seedu/lovebook/ui/MainWindow.class
new file mode 100644
index 00000000000..9118e39e5c3
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/MainWindow.class differ
diff --git a/bin/main/seedu/lovebook/ui/NoSelectionModel.class b/bin/main/seedu/lovebook/ui/NoSelectionModel.class
new file mode 100644
index 00000000000..089399902de
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/NoSelectionModel.class differ
diff --git a/bin/main/seedu/lovebook/ui/PersonCard.class b/bin/main/seedu/lovebook/ui/PersonCard.class
new file mode 100644
index 00000000000..2f0226cfadc
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/PersonCard.class differ
diff --git a/bin/main/seedu/lovebook/ui/PersonListPanel$PersonListViewCell.class b/bin/main/seedu/lovebook/ui/PersonListPanel$PersonListViewCell.class
new file mode 100644
index 00000000000..55dbfb5b359
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/PersonListPanel$PersonListViewCell.class differ
diff --git a/bin/main/seedu/lovebook/ui/PersonListPanel.class b/bin/main/seedu/lovebook/ui/PersonListPanel.class
new file mode 100644
index 00000000000..2b674f4204f
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/PersonListPanel.class differ
diff --git a/bin/main/seedu/lovebook/ui/PresetsBar.class b/bin/main/seedu/lovebook/ui/PresetsBar.class
new file mode 100644
index 00000000000..7ef2fe10220
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/PresetsBar.class differ
diff --git a/bin/main/seedu/lovebook/ui/ResultDisplay.class b/bin/main/seedu/lovebook/ui/ResultDisplay.class
new file mode 100644
index 00000000000..1fbaaed8721
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/ResultDisplay.class differ
diff --git a/bin/main/seedu/lovebook/ui/StatusBarFooter.class b/bin/main/seedu/lovebook/ui/StatusBarFooter.class
new file mode 100644
index 00000000000..c1ba67228e8
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/StatusBarFooter.class differ
diff --git a/bin/main/seedu/lovebook/ui/Ui.class b/bin/main/seedu/lovebook/ui/Ui.class
new file mode 100644
index 00000000000..a700d84781c
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/Ui.class differ
diff --git a/bin/main/seedu/lovebook/ui/UiManager.class b/bin/main/seedu/lovebook/ui/UiManager.class
new file mode 100644
index 00000000000..c0a41221f21
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/UiManager.class differ
diff --git a/bin/main/seedu/lovebook/ui/UiPart.class b/bin/main/seedu/lovebook/ui/UiPart.class
new file mode 100644
index 00000000000..d4bd01e1ed3
Binary files /dev/null and b/bin/main/seedu/lovebook/ui/UiPart.class differ
diff --git a/bin/main/view/CommandBox.fxml b/bin/main/view/CommandBox.fxml
new file mode 100644
index 00000000000..124283a392e
--- /dev/null
+++ b/bin/main/view/CommandBox.fxml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/bin/main/view/DarkTheme.css b/bin/main/view/DarkTheme.css
new file mode 100644
index 00000000000..36e6b001cd8
--- /dev/null
+++ b/bin/main/view/DarkTheme.css
@@ -0,0 +1,352 @@
+.background {
+ -fx-background-color: derive(#1d1d1d, 20%);
+ background-color: #383838; /* Used in the default.html file */
+}
+
+.label {
+ -fx-font-size: 11pt;
+ -fx-font-family: "Segoe UI Semibold";
+ -fx-text-fill: #555555;
+ -fx-opacity: 0.9;
+}
+
+.label-bright {
+ -fx-font-size: 11pt;
+ -fx-font-family: "Segoe UI Semibold";
+ -fx-text-fill: white;
+ -fx-opacity: 1;
+}
+
+.label-header {
+ -fx-font-size: 32pt;
+ -fx-font-family: "Segoe UI Light";
+ -fx-text-fill: white;
+ -fx-opacity: 1;
+}
+
+.text-field {
+ -fx-font-size: 12pt;
+ -fx-font-family: "Segoe UI Semibold";
+}
+
+.tab-pane {
+ -fx-padding: 0 0 0 1;
+}
+
+.tab-pane .tab-header-area {
+ -fx-padding: 0 0 0 0;
+ -fx-min-height: 0;
+ -fx-max-height: 0;
+}
+
+.table-view {
+ -fx-base: #1d1d1d;
+ -fx-control-inner-background: #1d1d1d;
+ -fx-background-color: #1d1d1d;
+ -fx-table-cell-border-color: transparent;
+ -fx-table-header-border-color: transparent;
+ -fx-padding: 5;
+}
+
+.table-view .column-header-background {
+ -fx-background-color: transparent;
+}
+
+.table-view .column-header, .table-view .filler {
+ -fx-size: 35;
+ -fx-border-width: 0 0 1 0;
+ -fx-background-color: transparent;
+ -fx-border-color:
+ transparent
+ transparent
+ derive(-fx-base, 80%)
+ transparent;
+ -fx-border-insets: 0 10 1 0;
+}
+
+.table-view .column-header .label {
+ -fx-font-size: 20pt;
+ -fx-font-family: "Segoe UI Light";
+ -fx-text-fill: white;
+ -fx-alignment: center-left;
+ -fx-opacity: 1;
+}
+
+.table-view:focused .table-row-cell:filled:focused:selected {
+ -fx-background-color: -fx-focus-color;
+}
+
+.split-pane:horizontal .split-pane-divider {
+ -fx-background-color: derive(#1d1d1d, 20%);
+ -fx-border-color: transparent transparent transparent #4d4d4d;
+}
+
+.split-pane {
+ -fx-border-radius: 1;
+ -fx-border-width: 1;
+ -fx-background-color: derive(#1d1d1d, 20%);
+}
+
+.list-view {
+ -fx-background-insets: 0;
+ -fx-padding: 0;
+ -fx-background-color: derive(#1d1d1d, 20%);
+}
+
+.list-cell {
+ -fx-label-padding: 0 0 0 0;
+ -fx-graphic-text-gap : 0;
+ -fx-padding: 0 0 0 0;
+}
+
+.list-cell:filled:even {
+ -fx-background-color: #3c3e3f;
+}
+
+.list-cell:filled:odd {
+ -fx-background-color: #515658;
+}
+
+.list-cell:filled:selected {
+ -fx-background-color: #424d5f;
+}
+
+.list-cell:filled:selected #cardPane {
+ -fx-border-color: #3e7b91;
+ -fx-border-width: 1;
+}
+
+.list-cell .label {
+ -fx-text-fill: white;
+}
+
+.cell_big_label {
+ -fx-font-family: "Segoe UI Semibold";
+ -fx-font-size: 16px;
+ -fx-text-fill: #010504;
+}
+
+.cell_small_label {
+ -fx-font-family: "Segoe UI";
+ -fx-font-size: 13px;
+ -fx-text-fill: #010504;
+}
+
+.stack-pane {
+ -fx-background-color: derive(#1d1d1d, 20%);
+}
+
+.pane-with-border {
+ -fx-background-color: derive(#1d1d1d, 20%);
+ -fx-border-color: derive(#1d1d1d, 10%);
+ -fx-border-top-width: 1px;
+}
+
+.status-bar {
+ -fx-background-color: derive(#1d1d1d, 30%);
+}
+
+.result-display {
+ -fx-background-color: transparent;
+ -fx-font-family: "Segoe UI Light";
+ -fx-font-size: 13pt;
+ -fx-text-fill: white;
+}
+
+.result-display .label {
+ -fx-text-fill: black !important;
+}
+
+.status-bar .label {
+ -fx-font-family: "Segoe UI Light";
+ -fx-text-fill: white;
+ -fx-padding: 4px;
+ -fx-pref-height: 30px;
+}
+
+.status-bar-with-border {
+ -fx-background-color: derive(#1d1d1d, 30%);
+ -fx-border-color: derive(#1d1d1d, 25%);
+ -fx-border-width: 1px;
+}
+
+.status-bar-with-border .label {
+ -fx-text-fill: white;
+}
+
+.grid-pane {
+ -fx-background-color: derive(#1d1d1d, 30%);
+ -fx-border-color: derive(#1d1d1d, 30%);
+ -fx-border-width: 1px;
+}
+
+.grid-pane .stack-pane {
+ -fx-background-color: derive(#1d1d1d, 30%);
+}
+
+.context-menu {
+ -fx-background-color: derive(#1d1d1d, 50%);
+}
+
+.context-menu .label {
+ -fx-text-fill: white;
+}
+
+.menu-bar {
+ -fx-background-color: derive(#1d1d1d, 20%);
+}
+
+.menu-bar .label {
+ -fx-font-size: 14pt;
+ -fx-font-family: "Segoe UI Light";
+ -fx-text-fill: white;
+ -fx-opacity: 0.9;
+}
+
+.menu .left-container {
+ -fx-background-color: black;
+}
+
+/*
+ * Metro style Push Button
+ * Author: Pedro Duque Vieira
+ * http://pixelduke.wordpress.com/2012/10/23/jmetro-windows-8-controls-on-java/
+ */
+.button {
+ -fx-padding: 5 22 5 22;
+ -fx-border-color: #e2e2e2;
+ -fx-border-width: 2;
+ -fx-background-radius: 0;
+ -fx-background-color: #1d1d1d;
+ -fx-font-family: "Segoe UI", Helvetica, Arial, sans-serif;
+ -fx-font-size: 11pt;
+ -fx-text-fill: #d8d8d8;
+ -fx-background-insets: 0 0 0 0, 0, 1, 2;
+}
+
+.button:hover {
+ -fx-background-color: #3a3a3a;
+}
+
+.button:pressed, .button:default:hover:pressed {
+ -fx-background-color: white;
+ -fx-text-fill: #1d1d1d;
+}
+
+.button:focused {
+ -fx-border-color: white, white;
+ -fx-border-width: 1, 1;
+ -fx-border-style: solid, segments(1, 1);
+ -fx-border-radius: 0, 0;
+ -fx-border-insets: 1 1 1 1, 0;
+}
+
+.button:disabled, .button:default:disabled {
+ -fx-opacity: 0.4;
+ -fx-background-color: #1d1d1d;
+ -fx-text-fill: white;
+}
+
+.button:default {
+ -fx-background-color: -fx-focus-color;
+ -fx-text-fill: #ffffff;
+}
+
+.button:default:hover {
+ -fx-background-color: derive(-fx-focus-color, 30%);
+}
+
+.dialog-pane {
+ -fx-background-color: #1d1d1d;
+}
+
+.dialog-pane > *.button-bar > *.container {
+ -fx-background-color: #1d1d1d;
+}
+
+.dialog-pane > *.label.content {
+ -fx-font-size: 14px;
+ -fx-font-weight: bold;
+ -fx-text-fill: white;
+}
+
+.dialog-pane:header *.header-panel {
+ -fx-background-color: derive(#1d1d1d, 25%);
+}
+
+.dialog-pane:header *.header-panel *.label {
+ -fx-font-size: 18px;
+ -fx-font-style: italic;
+ -fx-fill: white;
+ -fx-text-fill: white;
+}
+
+.scroll-bar {
+ -fx-background-color: derive(#1d1d1d, 20%);
+}
+
+.scroll-bar .thumb {
+ -fx-background-color: derive(#1d1d1d, 50%);
+ -fx-background-insets: 3;
+}
+
+.scroll-bar .increment-button, .scroll-bar .decrement-button {
+ -fx-background-color: transparent;
+ -fx-padding: 0 0 0 0;
+}
+
+.scroll-bar .increment-arrow, .scroll-bar .decrement-arrow {
+ -fx-shape: " ";
+}
+
+.scroll-bar:vertical .increment-arrow, .scroll-bar:vertical .decrement-arrow {
+ -fx-padding: 1 8 1 8;
+}
+
+.scroll-bar:horizontal .increment-arrow, .scroll-bar:horizontal .decrement-arrow {
+ -fx-padding: 8 1 8 1;
+}
+
+#cardPane {
+ -fx-background-color: transparent;
+ -fx-border-width: 0;
+}
+
+#commandTypeLabel {
+ -fx-font-size: 11px;
+ -fx-text-fill: #F70D1A;
+}
+
+#commandTextField {
+ -fx-background-color: transparent #383838 transparent #383838;
+ -fx-background-insets: 0;
+ -fx-border-color: #383838 #383838 #ffffff #383838;
+ -fx-border-insets: 0;
+ -fx-border-width: 1;
+ -fx-font-family: "Segoe UI Light";
+ -fx-font-size: 13pt;
+ -fx-text-fill: white;
+}
+
+#filterField, #personListPanel, #personWebpage {
+ -fx-effect: innershadow(gaussian, black, 10, 0, 0, 0);
+}
+
+#resultDisplay .content {
+ -fx-background-color: transparent, #383838, transparent, #383838;
+ -fx-background-radius: 0;
+}
+
+#tags {
+ -fx-hgap: 7;
+ -fx-vgap: 3;
+}
+
+#tags .label {
+ -fx-text-fill: white;
+ -fx-background-color: #3e7b91;
+ -fx-padding: 1 3 1 3;
+ -fx-border-radius: 2;
+ -fx-background-radius: 2;
+ -fx-font-size: 11;
+}
diff --git a/bin/main/view/Extensions.css b/bin/main/view/Extensions.css
new file mode 100644
index 00000000000..bfe82a85964
--- /dev/null
+++ b/bin/main/view/Extensions.css
@@ -0,0 +1,20 @@
+
+.error {
+ -fx-text-fill: #d06651 !important; /* The error class should always override the default text-fill style */
+}
+
+.list-cell:empty {
+ /* Empty cells will not have alternating colours */
+ -fx-background: #383838;
+}
+
+.tag-selector {
+ -fx-border-width: 1;
+ -fx-border-color: white;
+ -fx-border-radius: 3;
+ -fx-background-radius: 3;
+}
+
+.tooltip-text {
+ -fx-text-fill: white;
+}
diff --git a/bin/main/view/HelpWindow.css b/bin/main/view/HelpWindow.css
new file mode 100644
index 00000000000..17e8a8722cd
--- /dev/null
+++ b/bin/main/view/HelpWindow.css
@@ -0,0 +1,19 @@
+#copyButton, #helpMessage {
+ -fx-text-fill: white;
+}
+
+#copyButton {
+ -fx-background-color: dimgray;
+}
+
+#copyButton:hover {
+ -fx-background-color: gray;
+}
+
+#copyButton:armed {
+ -fx-background-color: darkgray;
+}
+
+#helpMessageContainer {
+ -fx-background-color: derive(#1d1d1d, 20%);
+}
diff --git a/bin/main/view/HelpWindow.fxml b/bin/main/view/HelpWindow.fxml
new file mode 100644
index 00000000000..e01f330de33
--- /dev/null
+++ b/bin/main/view/HelpWindow.fxml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bin/main/view/MainWindow.fxml b/bin/main/view/MainWindow.fxml
new file mode 100644
index 00000000000..1600b91bbcd
--- /dev/null
+++ b/bin/main/view/MainWindow.fxml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/PersonListCard.fxml b/bin/main/view/PersonListCard.fxml
similarity index 84%
rename from src/main/resources/view/PersonListCard.fxml
rename to bin/main/view/PersonListCard.fxml
index f5e812e25e6..5034c5a6a4f 100644
--- a/src/main/resources/view/PersonListCard.fxml
+++ b/bin/main/view/PersonListCard.fxml
@@ -28,9 +28,9 @@
-
-
-
+
+
+
diff --git a/src/main/resources/view/PersonListPanel.fxml b/bin/main/view/PersonListPanel.fxml
similarity index 100%
rename from src/main/resources/view/PersonListPanel.fxml
rename to bin/main/view/PersonListPanel.fxml
diff --git a/bin/main/view/ResultDisplay.fxml b/bin/main/view/ResultDisplay.fxml
new file mode 100644
index 00000000000..01b691792a9
--- /dev/null
+++ b/bin/main/view/ResultDisplay.fxml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
diff --git a/bin/main/view/StatusBarFooter.fxml b/bin/main/view/StatusBarFooter.fxml
new file mode 100644
index 00000000000..7b430f9c6a2
--- /dev/null
+++ b/bin/main/view/StatusBarFooter.fxml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bin/test/seedu/lovebook/AppParametersTest$ParametersStub.class b/bin/test/seedu/lovebook/AppParametersTest$ParametersStub.class
new file mode 100644
index 00000000000..7bdd1902b39
Binary files /dev/null and b/bin/test/seedu/lovebook/AppParametersTest$ParametersStub.class differ
diff --git a/bin/test/seedu/lovebook/AppParametersTest.class b/bin/test/seedu/lovebook/AppParametersTest.class
new file mode 100644
index 00000000000..142ed81b289
Binary files /dev/null and b/bin/test/seedu/lovebook/AppParametersTest.class differ
diff --git a/bin/test/seedu/lovebook/commons/core/ConfigTest.class b/bin/test/seedu/lovebook/commons/core/ConfigTest.class
new file mode 100644
index 00000000000..54cdcc4f942
Binary files /dev/null and b/bin/test/seedu/lovebook/commons/core/ConfigTest.class differ
diff --git a/bin/test/seedu/lovebook/commons/core/GuiSettingsTest.class b/bin/test/seedu/lovebook/commons/core/GuiSettingsTest.class
new file mode 100644
index 00000000000..fbbfc6dea65
Binary files /dev/null and b/bin/test/seedu/lovebook/commons/core/GuiSettingsTest.class differ
diff --git a/bin/test/seedu/lovebook/commons/core/VersionTest.class b/bin/test/seedu/lovebook/commons/core/VersionTest.class
new file mode 100644
index 00000000000..019955477e0
Binary files /dev/null and b/bin/test/seedu/lovebook/commons/core/VersionTest.class differ
diff --git a/bin/test/seedu/lovebook/commons/core/index/IndexTest.class b/bin/test/seedu/lovebook/commons/core/index/IndexTest.class
new file mode 100644
index 00000000000..a3cf51601c0
Binary files /dev/null and b/bin/test/seedu/lovebook/commons/core/index/IndexTest.class differ
diff --git a/bin/test/seedu/lovebook/commons/util/AppUtilTest.class b/bin/test/seedu/lovebook/commons/util/AppUtilTest.class
new file mode 100644
index 00000000000..bfe11042274
Binary files /dev/null and b/bin/test/seedu/lovebook/commons/util/AppUtilTest.class differ
diff --git a/bin/test/seedu/lovebook/commons/util/CollectionUtilTest.class b/bin/test/seedu/lovebook/commons/util/CollectionUtilTest.class
new file mode 100644
index 00000000000..95acf18edca
Binary files /dev/null and b/bin/test/seedu/lovebook/commons/util/CollectionUtilTest.class differ
diff --git a/bin/test/seedu/lovebook/commons/util/ConfigUtilTest.class b/bin/test/seedu/lovebook/commons/util/ConfigUtilTest.class
new file mode 100644
index 00000000000..ffb2d2d971f
Binary files /dev/null and b/bin/test/seedu/lovebook/commons/util/ConfigUtilTest.class differ
diff --git a/bin/test/seedu/lovebook/commons/util/FileUtilTest.class b/bin/test/seedu/lovebook/commons/util/FileUtilTest.class
new file mode 100644
index 00000000000..0ae1c5bd252
Binary files /dev/null and b/bin/test/seedu/lovebook/commons/util/FileUtilTest.class differ
diff --git a/bin/test/seedu/lovebook/commons/util/JsonUtilTest.class b/bin/test/seedu/lovebook/commons/util/JsonUtilTest.class
new file mode 100644
index 00000000000..0f98852b79f
Binary files /dev/null and b/bin/test/seedu/lovebook/commons/util/JsonUtilTest.class differ
diff --git a/bin/test/seedu/lovebook/commons/util/StringUtilTest.class b/bin/test/seedu/lovebook/commons/util/StringUtilTest.class
new file mode 100644
index 00000000000..70c8c8c899a
Binary files /dev/null and b/bin/test/seedu/lovebook/commons/util/StringUtilTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/LogicManagerTest$1.class b/bin/test/seedu/lovebook/logic/LogicManagerTest$1.class
new file mode 100644
index 00000000000..644402b539d
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/LogicManagerTest$1.class differ
diff --git a/bin/test/seedu/lovebook/logic/LogicManagerTest.class b/bin/test/seedu/lovebook/logic/LogicManagerTest.class
new file mode 100644
index 00000000000..e6c4db2f50b
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/LogicManagerTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/AddCommandIntegrationTest.class b/bin/test/seedu/lovebook/logic/commands/AddCommandIntegrationTest.class
new file mode 100644
index 00000000000..d2d56381179
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/AddCommandIntegrationTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/AddCommandTest$ModelStub.class b/bin/test/seedu/lovebook/logic/commands/AddCommandTest$ModelStub.class
new file mode 100644
index 00000000000..544de5a16d3
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/AddCommandTest$ModelStub.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/AddCommandTest$ModelStubAcceptingPersonAdded.class b/bin/test/seedu/lovebook/logic/commands/AddCommandTest$ModelStubAcceptingPersonAdded.class
new file mode 100644
index 00000000000..ba581afb3b0
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/AddCommandTest$ModelStubAcceptingPersonAdded.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/AddCommandTest$ModelStubWithPerson.class b/bin/test/seedu/lovebook/logic/commands/AddCommandTest$ModelStubWithPerson.class
new file mode 100644
index 00000000000..ce84322ee18
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/AddCommandTest$ModelStubWithPerson.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/AddCommandTest.class b/bin/test/seedu/lovebook/logic/commands/AddCommandTest.class
new file mode 100644
index 00000000000..adcbe1697c4
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/AddCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/BlindDateCommandTest.class b/bin/test/seedu/lovebook/logic/commands/BlindDateCommandTest.class
new file mode 100644
index 00000000000..6a38bfff3cc
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/BlindDateCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/ClearCommandTest.class b/bin/test/seedu/lovebook/logic/commands/ClearCommandTest.class
new file mode 100644
index 00000000000..749ad6dba0e
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/ClearCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/CommandResultTest.class b/bin/test/seedu/lovebook/logic/commands/CommandResultTest.class
new file mode 100644
index 00000000000..20ca39a9b52
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/CommandResultTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/CommandTestUtil.class b/bin/test/seedu/lovebook/logic/commands/CommandTestUtil.class
new file mode 100644
index 00000000000..4794f1adf22
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/CommandTestUtil.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/DeleteCommandTest.class b/bin/test/seedu/lovebook/logic/commands/DeleteCommandTest.class
new file mode 100644
index 00000000000..0b7cf9a490d
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/DeleteCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/EditCommandTest.class b/bin/test/seedu/lovebook/logic/commands/EditCommandTest.class
new file mode 100644
index 00000000000..51999f11602
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/EditCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/EditDateDescriptorTest.class b/bin/test/seedu/lovebook/logic/commands/EditDateDescriptorTest.class
new file mode 100644
index 00000000000..1f5f1744bb7
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/EditDateDescriptorTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/ExitCommandTest.class b/bin/test/seedu/lovebook/logic/commands/ExitCommandTest.class
new file mode 100644
index 00000000000..74889781179
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/ExitCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/FilterCommandTest.class b/bin/test/seedu/lovebook/logic/commands/FilterCommandTest.class
new file mode 100644
index 00000000000..5a934533df2
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/FilterCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/FindCommandTest.class b/bin/test/seedu/lovebook/logic/commands/FindCommandTest.class
new file mode 100644
index 00000000000..ed1edaef2d7
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/FindCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/HelpCommandTest.class b/bin/test/seedu/lovebook/logic/commands/HelpCommandTest.class
new file mode 100644
index 00000000000..c2b7287f018
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/HelpCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/ListCommandTest.class b/bin/test/seedu/lovebook/logic/commands/ListCommandTest.class
new file mode 100644
index 00000000000..9ac0b09bc3e
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/ListCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/SetPrefCommandTest$ModelStub.class b/bin/test/seedu/lovebook/logic/commands/SetPrefCommandTest$ModelStub.class
new file mode 100644
index 00000000000..c47c9259338
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/SetPrefCommandTest$ModelStub.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/SetPrefCommandTest$ModelStubAcceptingPreferenceAdded.class b/bin/test/seedu/lovebook/logic/commands/SetPrefCommandTest$ModelStubAcceptingPreferenceAdded.class
new file mode 100644
index 00000000000..c4315ca3798
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/SetPrefCommandTest$ModelStubAcceptingPreferenceAdded.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/SetPrefCommandTest.class b/bin/test/seedu/lovebook/logic/commands/SetPrefCommandTest.class
new file mode 100644
index 00000000000..cd9381eb841
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/SetPrefCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/ShowPrefCommandTest.class b/bin/test/seedu/lovebook/logic/commands/ShowPrefCommandTest.class
new file mode 100644
index 00000000000..43669ecc8f7
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/ShowPrefCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/SortCommandTest.class b/bin/test/seedu/lovebook/logic/commands/SortCommandTest.class
new file mode 100644
index 00000000000..11663814743
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/SortCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/StarCommandTest.class b/bin/test/seedu/lovebook/logic/commands/StarCommandTest.class
new file mode 100644
index 00000000000..b65180db483
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/StarCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/commands/UnstarCommandTest.class b/bin/test/seedu/lovebook/logic/commands/UnstarCommandTest.class
new file mode 100644
index 00000000000..50391601f21
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/commands/UnstarCommandTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/parser/AddCommandParserTest.class b/bin/test/seedu/lovebook/logic/parser/AddCommandParserTest.class
new file mode 100644
index 00000000000..21ae12f70c8
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/parser/AddCommandParserTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/parser/ArgumentTokenizerTest.class b/bin/test/seedu/lovebook/logic/parser/ArgumentTokenizerTest.class
new file mode 100644
index 00000000000..081b899f148
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/parser/ArgumentTokenizerTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/parser/CommandParserTestUtil.class b/bin/test/seedu/lovebook/logic/parser/CommandParserTestUtil.class
new file mode 100644
index 00000000000..095fd444c15
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/parser/CommandParserTestUtil.class differ
diff --git a/bin/test/seedu/lovebook/logic/parser/DeleteCommandParserTest.class b/bin/test/seedu/lovebook/logic/parser/DeleteCommandParserTest.class
new file mode 100644
index 00000000000..8fcb417872e
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/parser/DeleteCommandParserTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/parser/EditCommandParserTest.class b/bin/test/seedu/lovebook/logic/parser/EditCommandParserTest.class
new file mode 100644
index 00000000000..f092f8c2f47
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/parser/EditCommandParserTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/parser/FilterCommandParserTest.class b/bin/test/seedu/lovebook/logic/parser/FilterCommandParserTest.class
new file mode 100644
index 00000000000..e1333c74b52
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/parser/FilterCommandParserTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/parser/FindCommandParserTest.class b/bin/test/seedu/lovebook/logic/parser/FindCommandParserTest.class
new file mode 100644
index 00000000000..804b42e175a
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/parser/FindCommandParserTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/parser/LoveBookParserTest.class b/bin/test/seedu/lovebook/logic/parser/LoveBookParserTest.class
new file mode 100644
index 00000000000..665727aac14
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/parser/LoveBookParserTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/parser/ParserUtilTest.class b/bin/test/seedu/lovebook/logic/parser/ParserUtilTest.class
new file mode 100644
index 00000000000..49c1f1d7e7a
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/parser/ParserUtilTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/parser/SortCommandParserTest.class b/bin/test/seedu/lovebook/logic/parser/SortCommandParserTest.class
new file mode 100644
index 00000000000..feac0f05db9
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/parser/SortCommandParserTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/parser/StarCommandParserTest.class b/bin/test/seedu/lovebook/logic/parser/StarCommandParserTest.class
new file mode 100644
index 00000000000..330a2696066
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/parser/StarCommandParserTest.class differ
diff --git a/bin/test/seedu/lovebook/logic/parser/UnstarCommandParserTest.class b/bin/test/seedu/lovebook/logic/parser/UnstarCommandParserTest.class
new file mode 100644
index 00000000000..fe9617a3d85
Binary files /dev/null and b/bin/test/seedu/lovebook/logic/parser/UnstarCommandParserTest.class differ
diff --git a/bin/test/seedu/lovebook/model/LoveBookTest$LoveBookStub.class b/bin/test/seedu/lovebook/model/LoveBookTest$LoveBookStub.class
new file mode 100644
index 00000000000..0380ab333b9
Binary files /dev/null and b/bin/test/seedu/lovebook/model/LoveBookTest$LoveBookStub.class differ
diff --git a/bin/test/seedu/lovebook/model/LoveBookTest.class b/bin/test/seedu/lovebook/model/LoveBookTest.class
new file mode 100644
index 00000000000..e3d0f8386ce
Binary files /dev/null and b/bin/test/seedu/lovebook/model/LoveBookTest.class differ
diff --git a/bin/test/seedu/lovebook/model/ModelManagerTest.class b/bin/test/seedu/lovebook/model/ModelManagerTest.class
new file mode 100644
index 00000000000..aea3fe41d8a
Binary files /dev/null and b/bin/test/seedu/lovebook/model/ModelManagerTest.class differ
diff --git a/bin/test/seedu/lovebook/model/UserPrefsTest.class b/bin/test/seedu/lovebook/model/UserPrefsTest.class
new file mode 100644
index 00000000000..1e4689e5f81
Binary files /dev/null and b/bin/test/seedu/lovebook/model/UserPrefsTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/AgeTest.class b/bin/test/seedu/lovebook/model/date/AgeTest.class
new file mode 100644
index 00000000000..bc633a6b6a3
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/AgeTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/AvatarTest.class b/bin/test/seedu/lovebook/model/date/AvatarTest.class
new file mode 100644
index 00000000000..c6e461a8477
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/AvatarTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/DateTest.class b/bin/test/seedu/lovebook/model/date/DateTest.class
new file mode 100644
index 00000000000..17f49bb7b3d
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/DateTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/GenderTest.class b/bin/test/seedu/lovebook/model/date/GenderTest.class
new file mode 100644
index 00000000000..3dc1ffdadc0
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/GenderTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/HeightTest.class b/bin/test/seedu/lovebook/model/date/HeightTest.class
new file mode 100644
index 00000000000..4b617516e15
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/HeightTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/IncomeTest.class b/bin/test/seedu/lovebook/model/date/IncomeTest.class
new file mode 100644
index 00000000000..821625e9e36
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/IncomeTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/MetricContainsKeywordPredicateTest.class b/bin/test/seedu/lovebook/model/date/MetricContainsKeywordPredicateTest.class
new file mode 100644
index 00000000000..939f028b35b
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/MetricContainsKeywordPredicateTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/NameContainsKeywordsPredicateTest.class b/bin/test/seedu/lovebook/model/date/NameContainsKeywordsPredicateTest.class
new file mode 100644
index 00000000000..c675ce740a1
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/NameContainsKeywordsPredicateTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/NameTest.class b/bin/test/seedu/lovebook/model/date/NameTest.class
new file mode 100644
index 00000000000..b492fb9fc9c
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/NameTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/RandomPredicateTest.class b/bin/test/seedu/lovebook/model/date/RandomPredicateTest.class
new file mode 100644
index 00000000000..06268b6c2d3
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/RandomPredicateTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/ScoreTest.class b/bin/test/seedu/lovebook/model/date/ScoreTest.class
new file mode 100644
index 00000000000..68a5d94a94e
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/ScoreTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/StarTest.class b/bin/test/seedu/lovebook/model/date/StarTest.class
new file mode 100644
index 00000000000..d7167fb0440
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/StarTest.class differ
diff --git a/bin/test/seedu/lovebook/model/date/UniqueDateListTest.class b/bin/test/seedu/lovebook/model/date/UniqueDateListTest.class
new file mode 100644
index 00000000000..294b957d2a1
Binary files /dev/null and b/bin/test/seedu/lovebook/model/date/UniqueDateListTest.class differ
diff --git a/bin/test/seedu/lovebook/model/person/AgeTest.class b/bin/test/seedu/lovebook/model/person/AgeTest.class
new file mode 100644
index 00000000000..00d62911eb9
Binary files /dev/null and b/bin/test/seedu/lovebook/model/person/AgeTest.class differ
diff --git a/bin/test/seedu/lovebook/model/person/DateTest.class b/bin/test/seedu/lovebook/model/person/DateTest.class
new file mode 100644
index 00000000000..7454d246ff0
Binary files /dev/null and b/bin/test/seedu/lovebook/model/person/DateTest.class differ
diff --git a/bin/test/seedu/lovebook/model/person/GenderTest.class b/bin/test/seedu/lovebook/model/person/GenderTest.class
new file mode 100644
index 00000000000..449d793bf0d
Binary files /dev/null and b/bin/test/seedu/lovebook/model/person/GenderTest.class differ
diff --git a/bin/test/seedu/lovebook/model/person/HeightTest.class b/bin/test/seedu/lovebook/model/person/HeightTest.class
new file mode 100644
index 00000000000..f6e2a6b36e0
Binary files /dev/null and b/bin/test/seedu/lovebook/model/person/HeightTest.class differ
diff --git a/bin/test/seedu/lovebook/model/person/MetricContainsKeyWordPredicateTest.class b/bin/test/seedu/lovebook/model/person/MetricContainsKeyWordPredicateTest.class
new file mode 100644
index 00000000000..ef859c6d630
Binary files /dev/null and b/bin/test/seedu/lovebook/model/person/MetricContainsKeyWordPredicateTest.class differ
diff --git a/bin/test/seedu/lovebook/model/person/NameContainsKeywordsPredicateTest.class b/bin/test/seedu/lovebook/model/person/NameContainsKeywordsPredicateTest.class
new file mode 100644
index 00000000000..f28b53a6a74
Binary files /dev/null and b/bin/test/seedu/lovebook/model/person/NameContainsKeywordsPredicateTest.class differ
diff --git a/bin/test/seedu/lovebook/model/person/NameTest.class b/bin/test/seedu/lovebook/model/person/NameTest.class
new file mode 100644
index 00000000000..306c8078b37
Binary files /dev/null and b/bin/test/seedu/lovebook/model/person/NameTest.class differ
diff --git a/bin/test/seedu/lovebook/model/person/UniqueDateListTest.class b/bin/test/seedu/lovebook/model/person/UniqueDateListTest.class
new file mode 100644
index 00000000000..cef821e3a52
Binary files /dev/null and b/bin/test/seedu/lovebook/model/person/UniqueDateListTest.class differ
diff --git a/bin/test/seedu/lovebook/model/tag/TagTest.class b/bin/test/seedu/lovebook/model/tag/TagTest.class
new file mode 100644
index 00000000000..cdb71a53179
Binary files /dev/null and b/bin/test/seedu/lovebook/model/tag/TagTest.class differ
diff --git a/bin/test/seedu/lovebook/model/util/SampleDataUtilTest.class b/bin/test/seedu/lovebook/model/util/SampleDataUtilTest.class
new file mode 100644
index 00000000000..acae74ebd3e
Binary files /dev/null and b/bin/test/seedu/lovebook/model/util/SampleDataUtilTest.class differ
diff --git a/bin/test/seedu/lovebook/model/util/SampleDatePrefUtilTest.class b/bin/test/seedu/lovebook/model/util/SampleDatePrefUtilTest.class
new file mode 100644
index 00000000000..a382810d9dc
Binary files /dev/null and b/bin/test/seedu/lovebook/model/util/SampleDatePrefUtilTest.class differ
diff --git a/bin/test/seedu/lovebook/storage/JsonAdaptedDatePrefsTest.class b/bin/test/seedu/lovebook/storage/JsonAdaptedDatePrefsTest.class
new file mode 100644
index 00000000000..e1d5ed71000
Binary files /dev/null and b/bin/test/seedu/lovebook/storage/JsonAdaptedDatePrefsTest.class differ
diff --git a/bin/test/seedu/lovebook/storage/JsonAdaptedDateTest.class b/bin/test/seedu/lovebook/storage/JsonAdaptedDateTest.class
new file mode 100644
index 00000000000..251e32b072e
Binary files /dev/null and b/bin/test/seedu/lovebook/storage/JsonAdaptedDateTest.class differ
diff --git a/bin/test/seedu/lovebook/storage/JsonDatePrefsStorageTest.class b/bin/test/seedu/lovebook/storage/JsonDatePrefsStorageTest.class
new file mode 100644
index 00000000000..ff8364658c6
Binary files /dev/null and b/bin/test/seedu/lovebook/storage/JsonDatePrefsStorageTest.class differ
diff --git a/bin/test/seedu/lovebook/storage/JsonLoveBookStorageTest.class b/bin/test/seedu/lovebook/storage/JsonLoveBookStorageTest.class
new file mode 100644
index 00000000000..e5c6586ca61
Binary files /dev/null and b/bin/test/seedu/lovebook/storage/JsonLoveBookStorageTest.class differ
diff --git a/bin/test/seedu/lovebook/storage/JsonSerializableDatePrefsTest.class b/bin/test/seedu/lovebook/storage/JsonSerializableDatePrefsTest.class
new file mode 100644
index 00000000000..bf52425c10c
Binary files /dev/null and b/bin/test/seedu/lovebook/storage/JsonSerializableDatePrefsTest.class differ
diff --git a/bin/test/seedu/lovebook/storage/JsonSerializableLoveBookTest.class b/bin/test/seedu/lovebook/storage/JsonSerializableLoveBookTest.class
new file mode 100644
index 00000000000..b1d73c002f3
Binary files /dev/null and b/bin/test/seedu/lovebook/storage/JsonSerializableLoveBookTest.class differ
diff --git a/bin/test/seedu/lovebook/storage/JsonUserPrefsStorageTest.class b/bin/test/seedu/lovebook/storage/JsonUserPrefsStorageTest.class
new file mode 100644
index 00000000000..d7cade3471f
Binary files /dev/null and b/bin/test/seedu/lovebook/storage/JsonUserPrefsStorageTest.class differ
diff --git a/bin/test/seedu/lovebook/storage/StorageManagerTest.class b/bin/test/seedu/lovebook/storage/StorageManagerTest.class
new file mode 100644
index 00000000000..c27cc13c263
Binary files /dev/null and b/bin/test/seedu/lovebook/storage/StorageManagerTest.class differ
diff --git a/bin/test/seedu/lovebook/testutil/Assert.class b/bin/test/seedu/lovebook/testutil/Assert.class
new file mode 100644
index 00000000000..d20ca4049bc
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/Assert.class differ
diff --git a/bin/test/seedu/lovebook/testutil/EditPersonDescriptorBuilder.class b/bin/test/seedu/lovebook/testutil/EditPersonDescriptorBuilder.class
new file mode 100644
index 00000000000..450a895ac99
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/EditPersonDescriptorBuilder.class differ
diff --git a/bin/test/seedu/lovebook/testutil/LoveBookBuilder.class b/bin/test/seedu/lovebook/testutil/LoveBookBuilder.class
new file mode 100644
index 00000000000..3a1a1e47009
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/LoveBookBuilder.class differ
diff --git a/bin/test/seedu/lovebook/testutil/PersonBuilder.class b/bin/test/seedu/lovebook/testutil/PersonBuilder.class
new file mode 100644
index 00000000000..2c60921cf64
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/PersonBuilder.class differ
diff --git a/bin/test/seedu/lovebook/testutil/PersonUtil.class b/bin/test/seedu/lovebook/testutil/PersonUtil.class
new file mode 100644
index 00000000000..5a458b27ca2
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/PersonUtil.class differ
diff --git a/bin/test/seedu/lovebook/testutil/PreferenceBuilder.class b/bin/test/seedu/lovebook/testutil/PreferenceBuilder.class
new file mode 100644
index 00000000000..7aff8deea91
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/PreferenceBuilder.class differ
diff --git a/bin/test/seedu/lovebook/testutil/SerializableTestClass.class b/bin/test/seedu/lovebook/testutil/SerializableTestClass.class
new file mode 100644
index 00000000000..1a56ba24654
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/SerializableTestClass.class differ
diff --git a/bin/test/seedu/lovebook/testutil/SetPreferenceDescriptorBuilder.class b/bin/test/seedu/lovebook/testutil/SetPreferenceDescriptorBuilder.class
new file mode 100644
index 00000000000..8808dd25a24
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/SetPreferenceDescriptorBuilder.class differ
diff --git a/bin/test/seedu/lovebook/testutil/TestUtil.class b/bin/test/seedu/lovebook/testutil/TestUtil.class
new file mode 100644
index 00000000000..a405e449dda
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/TestUtil.class differ
diff --git a/bin/test/seedu/lovebook/testutil/TypicalDatePrefs.class b/bin/test/seedu/lovebook/testutil/TypicalDatePrefs.class
new file mode 100644
index 00000000000..07819fb9f4a
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/TypicalDatePrefs.class differ
diff --git a/bin/test/seedu/lovebook/testutil/TypicalDates.class b/bin/test/seedu/lovebook/testutil/TypicalDates.class
new file mode 100644
index 00000000000..2452d5fc3bb
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/TypicalDates.class differ
diff --git a/bin/test/seedu/lovebook/testutil/TypicalIndexes.class b/bin/test/seedu/lovebook/testutil/TypicalIndexes.class
new file mode 100644
index 00000000000..5061c4271ce
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/TypicalIndexes.class differ
diff --git a/bin/test/seedu/lovebook/testutil/TypicalPersons.class b/bin/test/seedu/lovebook/testutil/TypicalPersons.class
new file mode 100644
index 00000000000..fdd0543fb91
Binary files /dev/null and b/bin/test/seedu/lovebook/testutil/TypicalPersons.class differ
diff --git a/bin/test/seedu/lovebook/ui/DateCardTest.class b/bin/test/seedu/lovebook/ui/DateCardTest.class
new file mode 100644
index 00000000000..690f103b55a
Binary files /dev/null and b/bin/test/seedu/lovebook/ui/DateCardTest.class differ
diff --git a/bin/test/seedu/lovebook/ui/PresetsBarTest.class b/bin/test/seedu/lovebook/ui/PresetsBarTest.class
new file mode 100644
index 00000000000..0295aae7029
Binary files /dev/null and b/bin/test/seedu/lovebook/ui/PresetsBarTest.class differ
diff --git a/bin/test/seedu/lovebook/ui/StubCommandExecutor.class b/bin/test/seedu/lovebook/ui/StubCommandExecutor.class
new file mode 100644
index 00000000000..bc08ae22b1e
Binary files /dev/null and b/bin/test/seedu/lovebook/ui/StubCommandExecutor.class differ
diff --git a/bin/test/seedu/lovebook/ui/TestFxmlObject.class b/bin/test/seedu/lovebook/ui/TestFxmlObject.class
new file mode 100644
index 00000000000..4c693ad4dd0
Binary files /dev/null and b/bin/test/seedu/lovebook/ui/TestFxmlObject.class differ
diff --git a/bin/test/seedu/lovebook/ui/UiPartTest$TestUiPart.class b/bin/test/seedu/lovebook/ui/UiPartTest$TestUiPart.class
new file mode 100644
index 00000000000..5acce70cedc
Binary files /dev/null and b/bin/test/seedu/lovebook/ui/UiPartTest$TestUiPart.class differ
diff --git a/bin/test/seedu/lovebook/ui/UiPartTest.class b/bin/test/seedu/lovebook/ui/UiPartTest.class
new file mode 100644
index 00000000000..93fe47cf65d
Binary files /dev/null and b/bin/test/seedu/lovebook/ui/UiPartTest.class differ
diff --git a/bin/test/view/UiPartTest/invalidFile.fxml b/bin/test/view/UiPartTest/invalidFile.fxml
new file mode 100644
index 00000000000..67680946732
--- /dev/null
+++ b/bin/test/view/UiPartTest/invalidFile.fxml
@@ -0,0 +1 @@
+Not a valid FXML file
diff --git a/bin/test/view/UiPartTest/validFile.fxml b/bin/test/view/UiPartTest/validFile.fxml
new file mode 100644
index 00000000000..f61b877600c
--- /dev/null
+++ b/bin/test/view/UiPartTest/validFile.fxml
@@ -0,0 +1,4 @@
+
+
+
+Hello World!
diff --git a/bin/test/view/UiPartTest/validFileWithFxRoot.fxml b/bin/test/view/UiPartTest/validFileWithFxRoot.fxml
new file mode 100644
index 00000000000..7b72ea2e208
--- /dev/null
+++ b/bin/test/view/UiPartTest/validFileWithFxRoot.fxml
@@ -0,0 +1,6 @@
+
+
+
+ Hello World!
+
diff --git a/build.gradle b/build.gradle
index a2951cc709e..3701ee6774f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ plugins {
id 'jacoco'
}
-mainClassName = 'seedu.address.Main'
+mainClassName = 'seedu.lovebook.Main'
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
@@ -21,10 +21,19 @@ checkstyle {
}
test {
+ doFirst {
+ if (System.getProperty("os.name").equals("Linux")) {
+ exclude '**/ui/**'
+ }
+ }
useJUnitPlatform()
finalizedBy jacocoTestReport
}
+run {
+ enableAssertions = true
+}
+
task coverage(type: JacocoReport) {
sourceDirectories.from files(sourceSets.main.allSource.srcDirs)
classDirectories.from files(sourceSets.main.output)
@@ -63,10 +72,13 @@ dependencies {
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: jUnitVersion
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: jUnitVersion
+
+ testImplementation 'org.testfx:testfx-core:4.0.16-alpha'
+ testImplementation 'org.testfx:testfx-junit5:4.0.16-alpha'
}
shadowJar {
- archiveFileName = 'addressbook.jar'
+ archiveFileName = 'LoveBook.jar'
}
defaultTasks 'clean', 'test'
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 00000000000..1748e487fbd
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,23 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+_markbind/logs/
+
+# Dependency directories
+node_modules/
+
+# Production build files (change if you output the build to a different directory)
+_site/
+
+# Env
+.env
+.env.local
+
+# IDE configs
+.vscode/
+.idea/*
+*.iml
diff --git a/docs/AboutUs.md b/docs/AboutUs.md
index 1c9514e966a..6c0e754d52b 100644
--- a/docs/AboutUs.md
+++ b/docs/AboutUs.md
@@ -1,59 +1,55 @@
---
-layout: page
-title: About Us
+ layout: default.md
+ title: "About Us"
---
-We are a team based in the [School of Computing, National University of Singapore](http://www.comp.nus.edu.sg).
+# About Us
-You can reach us at the email `seer[at]comp.nus.edu.sg`
+We are a team based in the [School of Computing, National University of Singapore](http://www.comp.nus.edu.sg).
## Project team
-### John Doe
+### Goh En Rui Ryann
-
+
-[[homepage](http://www.comp.nus.edu.sg/~damithch)]
-[[github](https://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](http://github.com/ryamgoh)]
+[[portfolio](team/ryamgoh.md)]
-* Role: Project Advisor
+* Role: Developer
-### Jane Doe
+### Lynn Low
-
+
-[[github](http://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](http://github.com/lynnlow175)]
+[[portfolio](team/lynnlow175.md)]
-* Role: Team Lead
-* Responsibilities: UI
+* Role: Developer
-### Johnny Doe
+### Shishir Bychapur
-
+
-[[github](http://github.com/johndoe)] [[portfolio](team/johndoe.md)]
+[[github](http://github.com/shishirbychapur)]
+[[portfolio](team/shishirbychapur.md)]
* Role: Developer
-* Responsibilities: Data
-### Jean Doe
+* ### Lee Seng Kitt
-
+
-[[github](http://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](http://github.com/bobscodedump)]
+[[portfolio](team/bobscodedump.md)]
* Role: Developer
-* Responsibilities: Dev Ops + Threading
-### James Doe
+* ### Cleon Tan De Xuan
-
+
-[[github](http://github.com/johndoe)]
-[[portfolio](team/johndoe.md)]
+[[github](http://github.com/Cleon2)]
+[[portfolio](team/cleon2.md)]
* Role: Developer
-* Responsibilities: UI
diff --git a/docs/Configuration.md b/docs/Configuration.md
index 13cf0faea16..32f6255f3b9 100644
--- a/docs/Configuration.md
+++ b/docs/Configuration.md
@@ -1,6 +1,8 @@
---
-layout: page
-title: Configuration guide
+ layout: default.md
+ title: "Configuration guide"
---
+# Configuration guide
+
Certain properties of the application can be controlled (e.g user preferences file location, logging level) through the configuration file (default: `config.json`).
diff --git a/docs/DevOps.md b/docs/DevOps.md
index d2fd91a6001..ec3f2b01faa 100644
--- a/docs/DevOps.md
+++ b/docs/DevOps.md
@@ -1,12 +1,15 @@
---
-layout: page
-title: DevOps guide
+ layout: default.md
+ title: "DevOps guide"
+ pageNav: 3
---
-* Table of Contents
-{:toc}
+# DevOps guide
---------------------------------------------------------------------------------------------------------------------
+
+
+
+
## Build automation
@@ -73,7 +76,7 @@ Any warnings or errors will be printed out to the console.
Here are the steps to create a new release.
-1. Update the version number in [`MainApp.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/MainApp.java).
-1. Generate a fat JAR file using Gradle (i.e., `gradlew shadowJar`).
-1. Tag the repo with the version number. e.g. `v0.1`
-1. [Create a new release using GitHub](https://help.github.com/articles/creating-releases/). Upload the JAR file you created.
+1. Update the version number in [`MainApp.java`](https://github.com/se-edu/LoveBook-level3/tree/master/src/main/java/seedu/address/MainApp.java).
+2. Generate a fat JAR file using Gradle (i.e., `gradlew shadowJar`).
+3. Tag the repo with the version number. e.g. `v0.1`
+4. [Create a new release using GitHub](https://help.github.com/articles/creating-releases/). Upload the JAR file you created.
diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md
index 8a861859bfd..6b2af4a6092 100644
--- a/docs/DeveloperGuide.md
+++ b/docs/DeveloperGuide.md
@@ -1,255 +1,656 @@
---
-layout: page
-title: Developer Guide
+layout: default.md
+title: "Developer Guide"
+pageNav: 3
---
-* Table of Contents
-{:toc}
---------------------------------------------------------------------------------------------------------------------
+# LoveBook Developer Guide
+
+## **Overview**
+
+LoveBook, is a **dating-focused** application, revolving around providing **online daters** with a **convenient**
+and **enjoyable** tool to enhance their dating experiences. Featuring **user preferences management**, **date
+organization**, **customizable filtering options** and **best match algorithms**, LoveBook enhances the **efficiency**
+of your online dating journey.
+
+[//]: # ""
+[//]: # ""
## **Acknowledgements**
-* {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well}
+- Code reused from here to disable click feature of `ListView`:
+ https://stackoverflow.com/questions/20621752/javafx-make-listview-not-selectable-via-mouse
+- Result Display FXML code inspired from here:
+ https://github.com/AY1920S2-CS2103T-F09-3/main
+
+## **Table of Contents**
+
+- [**Overview**](#overview)
+- [**Acknowledgements**](#acknowledgements)
+- [**Table of Contents**](#table-of-contents)
+- [**Setting up, getting started**](#setting-up-getting-started)
+- [**Design**](#design)
+ - [Architecture](#architecture)
+ - [UI component](#ui-component)
+ - [Logic component](#logic-component)
+ - [Model component](#model-component)
+ - [Storage component](#storage-component)
+ - [Common classes](#common-classes)
+- [**Implementation**](#implementation)
+ - [Add Dates](#add-dates)
+ - [List Dates](#list-dates)
+ - [Filter dates](#filter-dates)
+ - [Sort dates](#sort-dates)
+ - [Get Blind Date](#get-blind-date)
+ - [Get best match](#get-best-match)
+ - [Set preferences](#set-preferences)
+ - [Star dates](#star-dates)
+ - [Unstar dates](#unstar-dates)
+- [**Documentation, logging, testing, configuration, dev-ops**](#documentation-logging-testing-configuration-dev-ops)
+- [**Appendix: Requirements**](#appendix-requirements)
+ - [Product scope](#product-scope)
+ - [User stories](#user-stories)
+ - [Use cases](#use-cases)
+ - [Non-Functional Requirements](#non-functional-requirements)
+ - [Glossary](#glossary)
+- [**Appendix: Instructions for Manual Testing**](#appendix-instructions-for-manual-testing)
+ - [Launch](#launch)
+ - [Viewing Help](#viewing-help)
+ - [Adding Dates](#adding-dates)
+ - [Editing Dates](#editing-dates)
+ - [Finding Dates](#finding-dates)
+ - [Filtering Dates](#filtering-dates)
+ - [Finding a Blind Date](#finding-a-blind-date)
+ - [Exiting the Application](#exiting-the-application)
+ - [Saving Data](#saving-data)
+- [**Appendix: Effort**](#appendix-effort)
+ - [Evolving of AB3 into LoveBook](#evolving-of-ab3-into-lovebook)
+ - [Revamping of UI](#revamping-of-ui)
+- [**Appendix: Planned Enhancements**](#appendix-planned-enhancements)
---------------------------------------------------------------------------------------------------------------------
+---
## **Setting up, getting started**
Refer to the guide [_Setting up and getting started_](SettingUp.md).
---------------------------------------------------------------------------------------------------------------------
-
-## **Design**
+---
-
+
-:bulb: **Tip:** The `.puml` files used to create diagrams in this document `docs/diagrams` folder. Refer to the [_PlantUML Tutorial_ at se-edu/guides](https://se-education.org/guides/tutorials/plantUml.html) to learn how to create and edit diagrams.
-
+## **Design**
### Architecture
-
+
-The ***Architecture Diagram*** given above explains the high-level design of the App.
+The **_Architecture Diagram_** given above explains the high-level design of the App.
Given below is a quick overview of main components and how they interact with each other.
**Main components of the architecture**
-**`Main`** (consisting of classes [`Main`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/Main.java) and [`MainApp`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/MainApp.java)) is in charge of the app launch and shut down.
-* At app launch, it initializes the other components in the correct sequence, and connects them up with each other.
-* At shut down, it shuts down the other components and invokes cleanup methods where necessary.
+**`Main`** (consisting of
+classes [`Main`](https://github.com/AY2324S1-CS2103T-F10-2/tp/blob/master/src/main/java/seedu/lovebook/Main.java)
+and [`MainApp`](https://github.com/AY2324S1-CS2103T-F10-2/tp/blob/master/src/main/java/seedu/lovebook/MainApp.java)) is
+in charge of the app launch and shut down.
+
+- At app launch, it initializes the other components in the correct sequence, and connects them up with each other.
+- At shut down, it shuts down the other components and invokes cleanup methods where necessary.
The bulk of the app's work is done by the following four components:
-* [**`UI`**](#ui-component): The UI of the App.
-* [**`Logic`**](#logic-component): The command executor.
-* [**`Model`**](#model-component): Holds the data of the App in memory.
-* [**`Storage`**](#storage-component): Reads data from, and writes data to, the hard disk.
+- [**`UI`**](#ui-component): The UI of the App.
+- [**`Logic`**](#logic-component): The command executor.
+- [**`Model`**](#model-component): Holds the data of the App in memory.
+- [**`Storage`**](#storage-component): Reads data from, and writes data to, the hard disk.
[**`Commons`**](#common-classes) represents a collection of classes used by multiple other components.
**How the architecture components interact with each other**
-The *Sequence Diagram* below shows how the components interact with each other for the scenario where the user issues the command `delete 1`.
+This application attempts to separate the `UI`, `Logic`, `Model` and `Storage` components to reduce coupling between the
+components.
+This is done by using interfaces to define the API of each component and using classes to implement the functionality of
+each component.
+This allows the components to be easily added and replaced with other implementations without affecting the other
+components.
+For example, new features can be added to the `Storage` component without affecting the other components.
+
+The _Sequence Diagram_ below shows how the components interact with each other for the scenario where the user issues
+the command `delete 1`.
-
+
Each of the four main components (also shown in the diagram above),
-* defines its *API* in an `interface` with the same name as the Component.
-* implements its functionality using a concrete `{Component Name}Manager` class (which follows the corresponding API `interface` mentioned in the previous point.
+- defines its _API_ in an `interface` with the same name as the Component.
+- implements its functionality using a concrete `{Component Name}Manager` class (which follows the corresponding
+ API `interface` mentioned in the previous point.
-For example, the `Logic` component defines its API in the `Logic.java` interface and implements its functionality using the `LogicManager.java` class which follows the `Logic` interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside component's being coupled to the implementation of a component), as illustrated in the (partial) class diagram below.
+For example, the `Logic` component defines its API in the `Logic.java` interface and implements its functionality using
+the `LogicManager.java` class which follows the `Logic` interface. Other components interact with a given component
+through its interface rather than the concrete class (reason: to prevent outside component's being coupled to the
+implementation of a component), as illustrated in the (partial) class diagram below.
-
+
The sections below give more details of each component.
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
+
### UI component
-The **API** of this component is specified in [`Ui.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/Ui.java)
+The **API** of this component is specified
+in [`Ui.java`](https://github.com/AY2324S1-CS2103T-F10-2/tp/blob/master/src/main/java/seedu/lovebook/ui/Ui.java)
-![Structure of the UI Component](images/UiClassDiagram.png)
+
-The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class which captures the commonalities between classes that represent parts of the visible GUI.
+The UI consists of a `MainWindow` that is made up of parts
+e.g.`CommandBox`, `ResultDisplay`, `DateListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`,
+inherit from the abstract `UiPart` class which captures the commonalities between classes that represent parts of the
+visible GUI.
-The `UI` component uses the JavaFx UI framework. The layout of these UI parts are defined in matching `.fxml` files that are in the `src/main/resources/view` folder. For example, the layout of the [`MainWindow`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/MainWindow.java) is specified in [`MainWindow.fxml`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/resources/view/MainWindow.fxml)
+The `UI` component uses the JavaFx UI framework. The layout of these UI parts are defined in matching `.fxml` files that
+are in the `src/main/resources/view` folder. For example, the layout of
+the [`MainWindow`](https://github.com/AY2324S1-CS2103T-F10-2/tp/blob/master/src/main/java/seedu/lovebook/ui/MainWindow.java)
+is specified
+in [`MainWindow.fxml`](https://github.com/se-edu/LoveBook-level3/tree/master/src/main/resources/view/MainWindow.fxml)
The `UI` component,
-* executes user commands using the `Logic` component.
-* listens for changes to `Model` data so that the UI can be updated with the modified data.
-* keeps a reference to the `Logic` component, because the `UI` relies on the `Logic` to execute commands.
-* depends on some classes in the `Model` component, as it displays `Person` object residing in the `Model`.
+- executes user commands using the `Logic` component.
+- listens for changes to `Model` data so that the UI can be updated with the modified data.
+- keeps a reference to the `Logic` component, because the `UI` relies on the `Logic` to execute commands.
+- depends on some classes in the `Model` component, as it displays `Date` object residing in the `Model`.
+
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
### Logic component
-**API** : [`Logic.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/logic/Logic.java)
+**API
+** : [`Logic.java`](https://github.com/AY2324S1-CS2103T-F10-2/tp/blob/master/src/main/java/seedu/lovebook/logic/Logic.java)
Here's a (partial) class diagram of the `Logic` component:
-
+
+
+The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete 1")` API
+call as an example.
+
+
-The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete 1")` API call as an example.
+
-![Interactions Inside the Logic Component for the `delete 1` Command](images/DeleteSequenceDiagram.png)
+**Note:** The lifeline for `DeleteCommandParser` should end at the destroy marker (X) but due to a limitation of
+PlantUML, the lifeline reaches the end of diagram.
-
:information_source: **Note:** The lifeline for `DeleteCommandParser` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
-
+
How the `Logic` component works:
-1. When `Logic` is called upon to execute a command, it is passed to an `AddressBookParser` object which in turn creates a parser that matches the command (e.g., `DeleteCommandParser`) and uses it to parse the command.
-1. This results in a `Command` object (more precisely, an object of one of its subclasses e.g., `DeleteCommand`) which is executed by the `LogicManager`.
-1. The command can communicate with the `Model` when it is executed (e.g. to delete a person).
+1. When `Logic` is called upon to execute a command, it is passed to an `LoveBookParser` object which in turn creates a
+ parser that matches the command (e.g., `DeleteCommandParser`) and uses it to parse the command.
+1. This results in a `Command` object (more precisely, an object of one of its subclasses e.g., `DeleteCommand`) which
+ is executed by the `LogicManager`.
+1. The command can communicate with the `Model` when it is executed (e.g. to delete a date).
1. The result of the command execution is encapsulated as a `CommandResult` object which is returned back from `Logic`.
Here are the other classes in `Logic` (omitted from the class diagram above) that are used for parsing a user command:
-
+
How the parsing works:
-* When called upon to parse a user command, the `AddressBookParser` class creates an `XYZCommandParser` (`XYZ` is a placeholder for the specific command name e.g., `AddCommandParser`) which uses the other classes shown above to parse the user command and create a `XYZCommand` object (e.g., `AddCommand`) which the `AddressBookParser` returns back as a `Command` object.
-* All `XYZCommandParser` classes (e.g., `AddCommandParser`, `DeleteCommandParser`, ...) inherit from the `Parser` interface so that they can be treated similarly where possible e.g, during testing.
-### Model component
-**API** : [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/model/Model.java)
+- When called upon to parse a user command, the `LoveBookParser` class creates an `XYZCommandParser` (`XYZ` is a
+ placeholder for the specific command name e.g., `AddCommandParser`) which uses the other classes shown above to parse
+ the user command and create a `XYZCommand` object (e.g., `AddCommand`) which the `LoveBookParser` returns back as
+ a `Command` object.
+- All `XYZCommandParser` classes (e.g., `AddCommandParser`, `DeleteCommandParser`, ...) inherit from the `Parser`
+ interface so that they can be treated similarly where possible e.g, during testing.
-
+[Scroll back to _Table of Contents_](#table-of-contents)
+
-The `Model` component,
+### Model component
+
+**API
+** : [`Model.java`](https://github.com/AY2324S1-CS2103T-F10-2/tp/blob/master/src/main/java/seedu/lovebook/model/Model.java)
-* stores the address book data i.e., all `Person` objects (which are contained in a `UniquePersonList` object).
-* stores the currently 'selected' `Person` objects (e.g., results of a search query) as a separate _filtered_ list which is exposed to outsiders as an unmodifiable `ObservableList` that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change.
-* stores a `UserPref` object that represents the user’s preferences. This is exposed to the outside as a `ReadOnlyUserPref` objects.
-* does not depend on any of the other three components (as the `Model` represents data entities of the domain, they should make sense on their own without depending on other components)
+
-
:information_source: **Note:** An alternative (arguably, a more OOP) model is given below. It has a `Tag` list in the `AddressBook`, which `Person` references. This allows `AddressBook` to only require one `Tag` object per unique tag, instead of each `Person` needing their own `Tag` objects.
+The `Model` component,
-
+- stores the LoveBook data i.e., all `Date` objects (which are contained in a `UniqueDateList` object).
+- stores the currently 'selected' `Date` objects (e.g., results of a search query) as a separate _filtered_ list which
+ is exposed to outsiders as an unmodifiable `ObservableList` that can be 'observed' e.g. the UI can be bound to
+ this list so that the UI automatically updates when the data in the list change.
+- stores a `UserPrefs` object that represents the user’s preferences. This is exposed to the outside as
+ a `ReadOnlyUserPrefs` objects.
+- stores a `DatePrefs` object that represents the user’s preferences for dates. This is exposed to the outside as
+ a `ReadOnlyDatePrefs` objects.
+- does not depend on any of the other three components (as the `Model` represents data entities of the domain, they
+ should make sense on their own without depending on other components)
-
+[Scroll back to _Table of Contents_](#table-of-contents)
+
### Storage component
-**API** : [`Storage.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/storage/Storage.java)
+**API
+** : [`Storage.java`](https://github.com/AY2324S1-CS2103T-F10-2/tp/blob/master/src/main/java/seedu/lovebook/storage/Storage.java)
-
+
The `Storage` component,
-* can save both address book data and user preference data in JSON format, and read them back into corresponding objects.
-* inherits from both `AddressBookStorage` and `UserPrefStorage`, which means it can be treated as either one (if only the functionality of only one is needed).
-* depends on some classes in the `Model` component (because the `Storage` component's job is to save/retrieve objects that belong to the `Model`)
+
+- saves LoveBook data, date preferences data and user preference data in JSON format, and reads them back into
+ corresponding objects.
+- inherits from `LoveBookStorage`, `UserPrefsStorage` and `DatePrefsStorage`, which means it can be treated as
+ either one of three (if the functionality of only one is needed).
+- depends on some classes in the `Model` component (because the `Storage` component's job is to save/retrieve objects
+ that belong to the `Model`)
+
+[Scroll back to _Table of Contents_](#table-of-contents)
### Common classes
-Classes used by multiple components are in the `seedu.addressbook.commons` package.
+Classes used by multiple components are in the `seedu.LoveBook.commons` package.
+
+
---------------------------------------------------------------------------------------------------------------------
+---
## **Implementation**
-This section describes some noteworthy details on how certain features are implemented.
+Before diving into the implementation details, here's an overview of what changed from the AB-3 codebase.
+
+- Address, Phone Number, Email, Tags fields have been replaced with Gender, Age, Horoscope, Height and Income fields.
+- The `Person` class has been renamed to `Date` class, and most of the classes named `Personxxx` have been renamed
+ accordingly.
+- The GUI has been updated to make the application more visually appealing and user-friendly.
+- Several other commands like `filter`, `star`, `bestMatch` (not exhaustive) have been added to the application.
+
+The following class diagram shows the new `Date` class after the changes mentioned above.
+
+
+
+Moving on to the implementation details, the following sections describe how and why the main features of the app work.
+
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
+
+### Add Dates
+
+#### Implementation
+
+1. The add dates feature begins by passing the user input obtained from the `CommandBox` class in the `Ui` component to
+ the `LogicManager` class in the `Logic` component by invoking the `execute` function.
+2. The `LogicManager` class then passes the user input to the `LoveBookParser` class for parsing and validation.
+3. The `LoveBookParser` class then performs polymorphism and creates an `AddCommandParser` object for add command
+ specific parsing.
+4. The `LoveBookParser` class also separates the command word from the user input and passes the arguments from the user
+ input to the `AddCommandParser` object created above for parsing.
+5. The `AddCommandParser` carries out it's validation checks and creates new `Date`, `AddCommand` objects if the
+ validation checks pass.
+6. The `AddCommand` object is then passed back to the `LogicManager` class for invocation of the `execute` function
+ which adds the new `Date` object created into the existing `Model` component.
+
+
+ The delete, edit and find features are also implemented in a similar manner.
+
+
+The sequence diagram notation of the above steps is shown below.
+
+
+
+The activity diagram notation of the above steps is shown below.
+
+
+
+
+ The UI and Storage components are not shown in the sequence and activity diagrams above for simplicity.
+
+
+#### Design Considerations
+
+**Aspect: Adding dates with same name**
+
+- **Alternative 1 (current choice):** Don't allow dates with the same name to be added.
+
+ - Pros: Easy to implement (since all you have to do is find the name in the existing list of dates)
+ - Cons: Not very user-friendly (since the user may be dating multiple people with the same name)
+
+- **Alternative 2:** Allow dates with the same name to be added.
+ - Pros: More user-friendly (since user has more flexibility in adding dates)
+ - Cons: Slightly harder to implement (equality check will now take into account other details like age, gender,
+ etc.)
+
+**Aspect: Allowing users to add dates without specifying all fields**
+
+- **Alternative 1 (current choice):** Require users to specify all fields.
+
+ - Pros: Easy to implement (since all you have to do is check if all fields are present)
+ - Cons: Not very user-friendly (since the user may not know all the details of the date)
+
+- **Alternative 2:** Allow users to specify only some fields, and adding placeholder inputs to the remaining fields.
+ - Pros: More user-friendly (since user has more flexibility in adding dates)
+ - Cons: Slightly harder to implement (since you have to check which fields are present). Will also affect the
+ matching algorithm since these placeholder inputs have to be omitted.
+
+**Aspect: Adding dates to existing date list**
+
+- **Alternative 1 (current choice):** Sorts the list on every addition, maintaining a lexically sorted list.
+
+ - Pros: Easier to implement (since all you have to do is sort the list by name on every addition) and more visually
+ appealing (since the user can easily see the list sorted by name)
+ - Cons: Not very user-friendly (since the user may want to see the date being added to the end of the list)
+
+- **Alternative 2:** Adds the date to the end of the list.
+ - Pros: More user-friendly (since user can easily see the date being added to the end of the list)
+ - Cons: Not very visually appealing (since the list appears to be unsorted and non uniform)
+
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
+
+### List Dates
+
+1. The list dates feature begins by passing the user input obtained from the `CommandBox` class in the `Ui` component to
+ the `LogicManager` class in the `Logic` component by invoking the `execute` function.
+2. The `LogicManager` class then passes the user input to the `LoveBookParser` class for parsing and validation.
+3. The `LoveBookParser` class then performs polymorphism and creates a `ListCommand` object for list specific commands.
+ One thing to note here is that inputs like `list 12` and `list x` are accepted since they still contain `list`.
+4. The `ListCommand` object is then passed back to the `LogicManager` class for invocation of the `execute` function
+ which sorts the list of dates in the `Model` component and returns the sorted list to the `Ui` component.
+
+The sequence diagram notation of the above steps is shown below.
+
+
+
+#### Design Considerations
+
+**Aspect: Ordering of dates**
+
+- **Alternative 1 (current choice):** Sorts the list of dates by name.
+
+ - Pros: Easier to implement (since all you have to do is sort the list by name on every addition) and more visually
+ appealing (since the user can easily see the list sorted by name)
+ - Cons: Not very user-friendly (since the user may want to see the date being added to the end of the list) and less
+ efficient (since you have to sort the list on every command).
+
+- **Alternative 2:** List the dates in the order they were added.
+ - Pros: More user-friendly (since user can easily see the date being added to the end of the list). More efficient (
+ since you don't have to sort the list on every list command)
+ - Cons: Not very visually appealing (since the list appears to be unsorted and non uniform)
-### \[Proposed\] Undo/redo feature
+[Scroll back to _Table of Contents_](#table-of-contents)
-#### Proposed Implementation
+
-The proposed undo/redo mechanism is facilitated by `VersionedAddressBook`. It extends `AddressBook` with an undo/redo history, stored internally as an `addressBookStateList` and `currentStatePointer`. Additionally, it implements the following operations:
+### Filter dates
-* `VersionedAddressBook#commit()` — Saves the current address book state in its history.
-* `VersionedAddressBook#undo()` — Restores the previous address book state from its history.
-* `VersionedAddressBook#redo()` — Restores a previously undone address book state from its history.
+1. The filter dates feature begins by passing the user input obtained from the `CommandBox` class in the `Ui` component to
+ the `LogicManager` class in the `Logic` component by invoking the `execute` function.
+2. The `LogicManager` class then passes the user input to the `LoveBookParser` class for parsing and validation.
+3. The `LoveBookParser` class then performs polymorphism and creates a `FilterCommandParser` object for filter command parsing.
+4. The `FilterCommandParser` carries out it's validation checks and creates a `FilterCommand` object containing a
+ list of `MetricContainsKeywordPredicate` objects if the checks pass.
+5. The `FilterCommand` object is then passed back to the `LogicManager` class for invocation of the `execute` function which
+ filters the list of dates in the `Model` component and returns the filtered list to the `Ui` component.
-These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()` and `Model#redoAddressBook()` respectively.
+The _Activity_ diagram summarises what happens after the user enters a filter command.
-Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
+
-Step 1. The user launches the application for the first time. The `VersionedAddressBook` will be initialized with the initial address book state, and the `currentStatePointer` pointing to that single address book state.
+The _Sequence_ Diagram below shows how the components interact with each other for the scenario where the user issues
+the command `filter name/John`.
-![UndoRedoState0](images/UndoRedoState0.png)
+
-Step 2. The user executes `delete 5` command to delete the 5th person in the address book. The `delete` command calls `Model#commitAddressBook()`, causing the modified state of the address book after the `delete 5` command executes to be saved in the `addressBookStateList`, and the `currentStatePointer` is shifted to the newly inserted address book state.
+[Scroll back to _Table of Contents_](#table-of-contents)
-![UndoRedoState1](images/UndoRedoState1.png)
+
-Step 3. The user executes `add n/David …` to add a new person. The `add` command also calls `Model#commitAddressBook()`, causing another modified address book state to be saved into the `addressBookStateList`.
+### Sort dates
-![UndoRedoState2](images/UndoRedoState2.png)
+1. The sort dates feature begins by passing the user input obtained from the `CommandBox` class in the `Ui` component to
+ the `LogicManager` class in the `Logic` component by invoking the `execute` function.
+2. The `LogicManager` class then passes the user input to the `LoveBookParser` class for parsing and validation.
+3. The `LoveBookParser` class then performs polymorphism and creates a `SortCommandParser` object for sort command parsing.
+4. The `SortCommandParser` object carries out its validation checks and creates a `SortCommand` object containing a
+ String prefix (eg. name/) and String sequence (increasing/decreasing) if all checks pass. One thing to note here is
+ that the sequence and prefix are case-sensitive.
+5. The `SortCommand` object is then passed back to the `LogicManager` class for invocation of the `execute` function which
+ sorts the list of dates based on a specified metric in the specified order in the `Model` component and returns the sorted
+ list to the `Ui` component.
-
:information_source: **Note:** If a command fails its execution, it will not call `Model#commitAddressBook()`, so the address book state will not be saved into the `addressBookStateList`.
+The _Activity_ diagram summarises what happens after the user enters a sort command.
-
+
-Step 4. The user now decides that adding the person was a mistake, and decides to undo that action by executing the `undo` command. The `undo` command will call `Model#undoAddressBook()`, which will shift the `currentStatePointer` once to the left, pointing it to the previous address book state, and restores the address book to that state.
+The _Sequence_ Diagram below shows how the components interact with each other for the scenario where the user issues
+the command `sort name/increasing`.
-![UndoRedoState3](images/UndoRedoState3.png)
+
-
:information_source: **Note:** If the `currentStatePointer` is at index 0, pointing to the initial AddressBook state, then there are no previous AddressBook states to restore. The `undo` command uses `Model#canUndoAddressBook()` to check if this is the case. If so, it will return an error to the user rather
-than attempting to perform the undo.
+[Scroll back to _Table of Contents_](#table-of-contents)
-
+
-The following sequence diagram shows how the undo operation works:
+### Get Blind Date
-![UndoSequenceDiagram](images/UndoSequenceDiagram.png)
+1. The blind date feature begins by passing the user input obtained from the `CommandBox` class in the `Ui` component to
+ the `LogicManager` class in the `Logic` component by invoking the `execute` function.
+2. The `LogicManager` class then passes the user input to the `LoveBookParser` class for parsing and validation.
+3. The `LoveBookParser` class then performs polymorphism and creates a `BlindDateCommand` object.
+ One thing to note here is that inputs like `blindDate 12` and `blindDate x` are accepted since they still contain `list`.
+4. The `BlindDateCommand` object is then passed back to the `LogicManager` class for invocation of the `execute` function
+ which sorts the list of dates in the `Model` component and returns the sorted list to the `Ui` component.
-
:information_source: **Note:** The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
+The _Activity_ diagram summarises what happens after the user enters a blindDate command.
-
+
-The `redo` command does the opposite — it calls `Model#redoAddressBook()`, which shifts the `currentStatePointer` once to the right, pointing to the previously undone state, and restores the address book to that state.
+The _Sequence_ Diagram below shows how the components interact with each other for the scenario where the user issues
+the command `blindDate`.
-
:information_source: **Note:** If the `currentStatePointer` is at index `addressBookStateList.size() - 1`, pointing to the latest address book state, then there are no undone AddressBook states to restore. The `redo` command uses `Model#canRedoAddressBook()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
+
-
+[Scroll back to _Table of Contents_](#table-of-contents)
-Step 5. The user then decides to execute the command `list`. Commands that do not modify the address book, such as `list`, will usually not call `Model#commitAddressBook()`, `Model#undoAddressBook()` or `Model#redoAddressBook()`. Thus, the `addressBookStateList` remains unchanged.
+
-![UndoRedoState4](images/UndoRedoState4.png)
+### Get best match
-Step 6. The user executes `clear`, which calls `Model#commitAddressBook()`. Since the `currentStatePointer` is not pointing at the end of the `addressBookStateList`, all address book states after the `currentStatePointer` will be purged. Reason: It no longer makes sense to redo the `add n/David …` command. This is the behavior that most modern desktop applications follow.
+The best match feature is implemented using the `BestMatchCommand` class. The `BestMatchCommand` class iterates
+through the list of Dates, and calls `GetScore` to get the score of the date based on height, age, horoscope and
+income.
-![UndoRedoState5](images/UndoRedoState5.png)
+1. The best match feature begins by passing the user input obtained from the `CommandBox` class in the `Ui`
+ component to the `LogicManager` class in the `Logic` component by invoking the `execute` function.
+2. The `LogicManager` class then passes the user input to the `LoveBookParser` class for parsing and validation.
+3. The `LoveBookParser` class then performs polymorphism and creates a `BestMatchCommand` object.
+4. The `BestMatchCommand` object is then passed back to the `LogicManager` class for invocation of the `execute` function
+ which then picks the `Date` with the highest score in the `Model` component by calling the `getScore` function for all `Date` objects in the `dateList`.
-The following activity diagram summarizes what happens when a user executes a new command:
+**Scoring Dates**
-
+- Dates are scored upon 40, where each factor (age, height, income, horoscope) contributing 10 points each.
+- The date's attributes are compared to the user's set preferences.
+- Score for age = 10 - 2 \* (age difference)
+- Score for height = 10 - (height difference)
+- Score for income = 10 - (income difference) / 250
+- Score for horoscope = 10 if horoscope is the same, 0 if horoscope is different
-#### Design considerations:
+**Ranking of Scores**
-**Aspect: How undo & redo executes:**
+- When the user requests for a Best Match, the Date with the highest score is taken.
+- A Date with 0 points can be chosen.
+- In cases where Dates are tied in score, the Date that was first input into LoveBook is chosen.
-* **Alternative 1 (current choice):** Saves the entire address book.
- * Pros: Easy to implement.
- * Cons: May have performance issues in terms of memory usage.
+The _Sequence_ Diagram below shows how the components interact with each other for the scenario where the user issues
+the command `bestMatch`
-* **Alternative 2:** Individual command knows how to undo/redo by
- itself.
- * Pros: Will use less memory (e.g. for `delete`, just save the person being deleted).
- * Cons: We must ensure that the implementation of each individual command are correct.
+
-_{more aspects and alternatives to be added}_
+[Scroll back to _Table of Contents_](#table-of-contents)
-### \[Proposed\] Data archiving
+
-_{Explain here how the data archiving feature will be implemented}_
+### Set preferences
+#### Implementation
---------------------------------------------------------------------------------------------------------------------
+1. The set preferences feature begins by passing the user input obtained from the `CommandBox` class in the `Ui`
+ component to the `LogicManager` class in the `Logic` component by invoking the `execute` function.
+2. The `LogicManager` class then passes the user input to the `LoveBookParser` class for parsing and validation.
+3. The `LoveBookParser` class then performs polymorphism and creates a `SetPrefCommandParser` object for SetPrefCommand
+ specific parsing.
+4. The `LoveBookParser` class also separates the command word from the user input and passes the arguments from the user
+ input to the `SetPrefCommandParser` object created above for parsing.
+5. The `SetPrefCommandParser` carries out it's validation checks and creates a new `SetPrefCommand` object if the
+ validation checks pass.
+6. The `SetPrefCommand` object is then passed back to the `LogicManager` class for invocation of the `execute` function
+ which then updates the date preferences in the `Model` component.
+
+The `edit` feature is also implemented in a similar manner.
+
+The _Activity_ Diagram notation of the above steps is shown below.
+
+
+
+The _Sequence_ Diagram notation of the above steps is shown below.
+
+
+
+
+
+#### Design Considerations
+
+**Aspect: Allowing users to set their date preferences on launch**
+
+- **Alternative 1 (current choice):** Have default date preference (
+ see [this](UserGuide.md#managing-preferences-and-getting-matches))
+ - Pros: Easy to implement (since all you have to do is set the default date preference). `bestMatch` works
+ immediately from the start.
+ - Cons: Not very user-friendly (since the user may not know all the details of the date)
+- **Alternative 2:** Allow users to set their date preferences on launch
+ - Pros: More user-friendly (since user has more flexibility in setting their date preferences)
+ - Cons: Slightly harder to implement (since you have to check which fields are present). Will also affect the
+ bestMatch
+ algorithm since users may not know how to set their date preferences first.
+
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
+
+### Show preferences
+
+#### Implementation
+
+1. The show preferences feature begins by passing the user input obtained from the `CommandBox` class in the `Ui`
+ component to the `LogicManager` class in the `Logic` component by invoking the `execute` function.
+2. The `LogicManager` class then passes the user input to the `LoveBookParser` class for parsing and validation.
+3. The `LoveBookParser` class then performs polymorphism and creates a `ShowPrefCommand` object.
+4. The `ShowPrefCommand` object is then passed back to the `LogicManager` class for invocation of the `execute` function
+ which then returns the preferences to the `Ui` component.
+
+The _Sequence_ Diagram notation of the above steps is shown below.
+
+
+
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
+
+### Star dates
+
+#### Implementation
+
+1. The star dates feature begins by passing the user input obtained from the `CommandBox` class in the `Ui` component to
+ the `LogicManager` class in the `Logic` component by invoking the `execute` function.
+2. The `LogicManager` class then passes the user input to the `LoveBookParser` class for parsing and validation.
+3. The `LoveBookParser` class then performs polymorphism and creates a `StarCommandParser` object for StarCommand specific parsing.
+4. The `LoveBookParser` class also separates the command word from the user input and passes the arguments from the user input to the `StarCommandParser` object created above for parsing.
+5. The `StarCommandParser` carries out it's validation checks and creates a new `StarCommand` object if the validation checks pass.
+6. The `StarCommand` object is then passed back to the `LogicManager` class for invocation of the `execute` function which then updates the isStarred field for the date object with the respective index.
+
+The _Activity_ diagram summarises what happens after the user enters a star command.
+
+
+
+The _Sequence_ Diagram below shows how the components interact with each other for the scenario where the user issues
+the command `star 1`
+
+
+
+#### Design Considerations
+
+**Aspect: Choosing star to be an additional field for the add dates command**
+
+- **Alternative 1 (current choice):** Dates are starred only through the star command
+ - Pros: Users can easily modify the starred status for any one of the dates by calling `star INDEX`
+ - Cons: Users cannot create a date and star it in one go using a single add dates command
+- **Alternative 2:** Let star be a field for the add dates command
+ - Pros: You can create a date and star the date in one go
+ - Cons: Makes the add command extra lengthy. Furthermore, the premise of the star command is that it's to be used on
+ an exceptional few dates. Hence, the time taken to fill in the extra star field, each time the user uses the
+ add dates command, will exceed any potential time savings.
+
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
+
+### Unstar dates
+
+#### Implementation
+
+1. The star dates feature begins by passing the user input obtained from the `CommandBox` class in the `Ui` component to
+ the `LogicManager` class in the `Logic` component by invoking the `execute` function.
+2. The `LogicManager` class then passes the user input to the `LoveBookParser` class for parsing and validation.
+3. The `LoveBookParser` class then performs polymorphism and creates a `UnstarCommandParser` object for UnstarCommand
+ specific parsing.
+4. The `LoveBookParser` class also separates the command word from the user input and passes the arguments from the user
+ input to the `UnstarCommandParser` object created above for parsing.
+5. The `UnstarCommandParser` carries out it's validation checks and creates a new `UnstarCommand` object if the
+ validation checks pass.
+6. The `UnstarCommand` object is then passed back to the `LogicManager` class for invocation of the `execute` function
+ which then updates the isStarred field for the date object with the respective index.
+
+The _Activity_ diagram summarises what happens after the user enters a star command.
+
+
+
+The _Sequence_ Diagram below shows how the components interact with each other for the scenario where the user issues
+the command `unstar 1`
+
+
+
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
+
+---
## **Documentation, logging, testing, configuration, dev-ops**
-* [Documentation guide](Documentation.md)
-* [Testing guide](Testing.md)
-* [Logging guide](Logging.md)
-* [Configuration guide](Configuration.md)
-* [DevOps guide](DevOps.md)
+- [Documentation guide](Documentation.md)
+- [Testing guide](Testing.md)
+- [Logging guide](Logging.md)
+- [Configuration guide](Configuration.md)
+- [DevOps guide](DevOps.md)
+
+[Scroll back to _Table of Contents_](#table-of-contents)
---------------------------------------------------------------------------------------------------------------------
+
## **Appendix: Requirements**
@@ -257,121 +658,560 @@ _{Explain here how the data archiving feature will be implemented}_
**Target user profile**:
-* has a need to manage a significant number of contacts
-* prefer desktop apps over other types
-* can type fast
-* prefers typing to mouse interactions
-* is reasonably comfortable using CLI apps
+- active online dater
+- has a need to manage a number of dates
+- prefer desktop apps over other types
+- can find, filter and organize their dates for better compatibility
+- prefers typing to mouse interactions
+- is reasonably comfortable using CLI apps
-**Value proposition**: manage contacts faster than a typical mouse/GUI driven app
+**Value proposition**:
+LoveBook simplifies the process of storing information of dates and assessing compatibility between user and his/her
+dates by taking into account the user’s preferences, thereby enhancing the efficiency and effectiveness of finding the
+perfect match.
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
### User stories
Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*`
-| Priority | As a … | I want to … | So that I can… |
-| -------- | ------------------------------------------ | ------------------------------ | ---------------------------------------------------------------------- |
-| `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App |
-| `* * *` | user | add a new person | |
-| `* * *` | user | delete a person | remove entries that I no longer need |
-| `* * *` | user | find a person by name | locate details of persons without having to go through the entire list |
-| `* *` | user | hide private contact details | minimize chance of someone else seeing them by accident |
-| `*` | user with many persons in the address book | sort persons by name | locate a person easily |
-
-*{More to be added}*
+| Priority | As a … | I want to … | So that I can… |
+| -------- | --------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
+| `* *` | new user | be greeted with a welcome message when i launch the app | feel welcome |
+| `* *` | new user | be able to get help when i'm stuck | better navigate through the application |
+| `* * *` | dater | be able to key my preferred height in my preferences | get recommended a suitable date based on our height compatibility |
+| `* * *` | dater | be able to key in my preferred horoscope in my preferences | get recommended a suitable date based on our horoscope compatibility |
+| `* * *` | dater | be able to key in my preferred income in my preferences | get recommended a suitable date based on our income compatibility |
+| `* * *` | dater | be able to key in my preferred age in my preferences | get recommended a suitable date based on our age compatibility |
+| `* * *` | dater | be able to edit my entered preferences | change my preferences in the event I change my mind |
+| `* * *` | dater | be able to view my preferences | know what my preferences are in the event I forget |
+| `* * *` | dater | be able to pull up a list of my previous dates | keep track of who I have dated in the past |
+| `* * *` | dater | be able to delete dates from my list | limit my dating list to those who I am still interested in |
+| `* * *` | dater | to be able create a new date entry with his/her gender, name, income, height, horoscope and age | keep my list growing |
+| `* * *` | dater | to be able to edit the details of my date | keep my dates details up to date |
+| `* * *` | dater | to be able to be recommended a complete random date | have an exciting surprise date that day |
+| `* * *` | dater | to be able to filter my dates based on a particular metric | find dates that I am interested in amidst my long and ever growing list |
+| `* * *` | dater | to be able to be recommended the most compatible date for me | optimize my chance of finding my one true love |
+| `* * *` | dater | to be able to star dates | keep track of outstanding dates |
+| `* * *` | dater | to be able to unstar dates | keep focused on people who are still outstanding to me |
+| `* * *` | dater | to be able to sort my dates based on a particular metric | find dates that I am interested in amidst my long and ever growing list |
+| `* * *` | dater | to be able to find dates based on their name | locate a date easily |
+| `* *` | lazy user | to be able to clear all the dates in my list | start afresh with a new date list |
+
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
### Use cases
-(For all use cases below, the **System** is the `AddressBook` and the **Actor** is the `user`, unless specified otherwise)
+(For all use cases below, the **System** is the `LoveBook` and the **Actor** is the `user`, unless specified otherwise)
+
+#### Use Case: List All Dates
+
+**Main Success Scenario (MSS):**
+
+1. User requests to list all dates.
+2. LoveBook shows a list of dates.
+
+ Use case ends.
+
+**Extensions:**
+
+2a. The list is empty.
+
+ 2a1. Use case ends.
+
+#### Use Case: Add a Date
+
+**Main Success Scenario (MSS):**
+
+1. User inputs command for adding date to LoveBook.
+2. LoveBook validates the command.
+3. LoveBook adds the new date to the LoveBook.
+4. LoveBook displays a confirmation message.
+
+ Use case ends.
+
+**Extensions:**
+
+2a. The command is invalid (Fields do not exist, invalid format).
+
+ 2a1. LoveBook displays an error message.
+ 2a2. Use case ends.
+
+#### Use Case: Finding a Date
+
+**Main Success Scenario (MSS):**
+
+1. User inputs command to search for a date in LoveBook.
+2. LoveBook displays all Dates with names that match the keyword.
+
+Use case ends.
+
+**Extensions:**
-**Use case: Delete a person**
+2a. No dates match the search query.
-**MSS**
+ 2a1. LoveBook displays an error message.
+ 2a2. Use case ends.
-1. User requests to list persons
-2. AddressBook shows a list of persons
-3. User requests to delete a specific person in the list
-4. AddressBook deletes the person
+#### Use Case: Edit a Date's Details
- Use case ends.
+**Main Success Scenario (MSS):**
-**Extensions**
+1. User inputs command to edit a Date's details.
+2. LoveBook validates the command.
+3. LoveBook updates the Date's details with the new information.
+4. LoveBook displays a confirmation message.
-* 2a. The list is empty.
+Use case ends.
- Use case ends.
+**Extensions:**
-* 3a. The given index is invalid.
+2a. The command is invalid (Fields do not exist, invalid format).
- * 3a1. AddressBook shows an error message.
+ 2a1. LoveBook shows an error message.
+ 2a2. Use case ends.
- Use case resumes at step 2.
+2b. No fields to edit are given.
-*{More to be added}*
+ 2b1. LoveBook displays an error message.
+ 2b2. Use case ends.
+
+2c. Edited field(s) are invalid.
+
+ 2c1. LoveBook displays an error message.
+ 2c2 Use case ends.
+
+2d. Index provided is invalid.
+
+ 2d1. LoveBook displays an error message.
+ 2d2. Use case ends.
+
+#### Use Case: Delete a Date
+
+**Main Success Scenario (MSS):**
+
+1. User inputs command to delete Date.
+2. Date is deleted from LoveBook.
+3. LoveBook displays a confirmation message.
+
+Use case ends.
+
+**Extensions:**
+
+2a. Index provided is invalid.
+
+ 2a1. LoveBook displays an error message.
+ 2a2. Use case ends.
+
+#### Use Case: Set Preferences
+
+**Main Success Scenario (MSS):**
+
+1. User inputs command to set Preferences.
+2. LoveBook validates the command.
+3. LoveBook updates the preferences with the new information.
+4. LoveBook displays a confirmation message.
+
+Use case ends.
+
+**Extensions:**
+
+2a. The command is invalid (Preference does not exist, invalid format).
+
+ 2a1. LoveBook displays an error message.
+ 2a2. Use case ends.
+
+2b. No Preferences to set are given.
+
+ 2b1. LoveBook displays an error message.
+ 2b2. Use case ends.
+
+2c. Field(s) are invalid.
+
+ 2c1. LoveBook displays an error message.
+ 2c2. Use case ends.
+
+2d. There are multiple values for a single field
+
+- LoveBook displays a message indicating that there are multiple values for a single field.
+- Use case ends.
+
+#### Use Case: Show Preferences
+
+**Main Success Scenario (MSS):**
+
+1. User inputs command to show preferences.
+2. LoveBook displays the preferences.
+
+Use case ends.
+
+**Extensions:**
+
+1a. No Preferences were previously set.
+
+ 1a1. LoveBook displays the default preferences.
+ 1a2. Use case ends.
+
+#### Use Case: Get Blind Date
+
+**Main Success Scenario (MSS):**
+
+1. User inputs command to get a blind Date.
+2. LoveBook displays a random Date.
+3. LoveBook displays a confirmation message.
+
+Use case ends.
+
+**Extensions:**
+
+1a. The list is empty.
+
+ 1a1. LoveBook displays an error message.
+ 1a2. Use case ends.
+
+#### Use Case: Filter Dates
+
+**Main Success Scenario (MSS):**
+
+1. User inputs command to filter dates.
+2. LoveBook validates the command.
+3. LoveBook shows a list of dates which are filtered based on the metric(s) given.
+
+Use case ends.
+
+**Extensions:**
+
+2a. The list is empty.
+
+ 2a1. Use case ends.
+
+2b. The command is invalid (Metrics do not exist, invalid format).
+
+ 2b1.LoveBook displays an error message.
+ 2b2. Use case ends.
+
+2c. No metric to filter by are given.
+
+ 2c1. LoveBook displays an error message.
+ 2c2. Use case ends.
+
+2d. Field(s) are invalid.
+
+ 2d1. LoveBook displays an error message.
+ 2d2. Use case ends.
+
+#### Use Case: Sort Dates
+
+**Main Success Scenario (MSS):**
+
+1. User inputs command to sort Dates
+2. LoveBook validated the command.
+3. LoveBook shows a list of dates which are sorted based on the comparator given.
+
+Use case ends.
+
+**Extensions:**
+
+2a. The list is empty.
+
+ 2a1. Use case ends.
+
+2b. The command is invalid (Comparator does not exist, invalid format).
+
+ 2b1. LoveBook displays an error message.
+ 2b2. Use case ends.
+
+2c. No comparator to sort is given.
+
+ 2c1. LoveBook displays an error message.
+ 2c2. Use case ends.
+
+2d. Comparator is invalid.
+
+ 2d1. LoveBook displays an error message.
+ 2d2. Use case ends.
+
+#### Use Case: Get Best Match
+
+**Main Success Scenario (MSS):**
+
+1. User requests for their best match.
+2. LoveBook displays the best match.
+
+Use case ends.
+
+**Extensions:**
+
+1a. The list is empty.
+
+ 1a1. LoveBook displays an error message.
+ 1a2. Use case ends.
+
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
### Non-Functional Requirements
-1. Should work on any _mainstream OS_ as long as it has Java `11` or above installed.
-2. Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.
-3. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
+1. Usability and Accessibility: The application should provide clear and user-friendly CLI prompts and menus.
+ It should support keyboard shortcuts for navigation to enhance accessibility.
+2. Scalability: The LoveBook should be capable of storing at least 10,000 contacts without a significant decrease in
+ performance.
+3. Reliability and Availability: The application should have a 99.9% uptime, ensuring that users can access their
+ contacts reliably.
+ It should automatically back up LoveBook data daily to prevent data loss.
+4. Portability: The CLI application should be compatible with multiple operating systems, including Windows, macOS, and
+ Linux.
-*{More to be added}*
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
### Glossary
-* **Mainstream OS**: Windows, Linux, Unix, OS-X
-* **Private contact detail**: A contact detail that is not meant to be shared with others
+| Term | Definition |
+| ------------- | ----------------------------------------------------------------------------------------------------------------- |
+| Date | A person that the user is interested in and is currently seeing. |
+| Metric | A certain characteristic of a date. (e.g. Gender, Height) |
+| Command | Text that the user types into the application to perform an action. |
+| Parameter | A value that the user provides to the application when executing a command. (e.g. in `gender/M` M is a parameter) |
+| GUI | Graphical User Interface |
+| CLI | Command Line Interface |
+| Mainstream OS | Windows, Linux, Unix, OS-X |
+
+[Scroll back to _Table of Contents_](#table-of-contents)
---------------------------------------------------------------------------------------------------------------------
+
-## **Appendix: Instructions for manual testing**
+---
+
+## **Appendix: Instructions for Manual Testing**
Given below are instructions to test the app manually.
+You are recommended to start with an empty LoveBook and follow the instructions sequentially
+in order for the example commands provided to be relevant.
+You can refer to the user guide for more details on the features.
+
+**Note:** These instructions only provide a starting point for testers to work on;
+testers are expected to do more _exploratory_ testing.
+
+### Launch
+
+1. Initial Launch.
+2. Download the jar file and copy it into an empty folder.
+3. Double-click the jar file.
+4. Expected output: The program runs and shows the GUI. Note that the window size may not be optimum.
+
+### Viewing Help
+
+1. Opening the Help window.
+2. Type the following help command into the text field.
+ `help`
+3. Press enter.
+4. Expected Output: The GUI shows a popup with a message and a link to the User Guide.
+
+### Adding Dates
+
+1. Adding a Date.
+2. Type the following add command into the text field.
+ `add name/Cleon age/22 gender/F height/176 horoscope/Taurus income/3000`
+3. Press enter.
+4. Expected Output: The GUI shows the added date in the LoveBook.
+
+### Editing Dates
+
+
+
+_Prerequisites:_ Have at least 1 date in the LoveBook.
+
+
+
+1. Editing a Date by index.
+2. Type the following edit date command into the text field.
+ `edit 1 horoscope/Cancer name/John`
+3. Press enter.
+4. Expected Output: The GUI shows the newly-edited fields for the Date at the specified index. (Sequence doesn't matter)
+
+### Finding Dates
+
+#### Finding Dates by single name
+
+
+
+_Prerequisites:_ Have at least 1 date with name containing "John" in the LoveBook.
+
+
+
+1. Type the following find command into the text field.
+ `find John`
+2. Press enter.
+3. Expected Output: The date with specified name shown.
-
:information_source: **Note:** These instructions only provide a starting point for testers to work on;
-testers are expected to do more *exploratory* testing.
+#### Finding Dates by multiple names
-
+
-### Launch and shutdown
+_Prerequisites:_ Have at least 2 dates (named "John" and "Cleon") in the LoveBook.
-1. Initial launch
+
- 1. Download the jar file and copy into an empty folder
+1. Type the following find command into the text field.
+ `find John Cleon`
+2. Press enter.
+3. Expected Output: The dates with the specified names shown.
- 1. Double-click the jar file Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
+#### Listing all Dates
+
+1. Type the following list command into the text field.
+ `list`
+2. Press enter.
+3. Expected Output: The GUI shows all dates in LoveBook.
+
+### Filtering Dates
+
+1. Filtering Dates by metric (e.g. name, age, height).
+2. Type the following filter command into the text field.
+ `filter age/22`
+3. Press enter.
+4. Expected Output: The GUI shows all dates with age 22 in LoveBook.
+
+### Finding a Blind Date
+
+
+
+_Prerequisites:_ Have at least 1 date in the LoveBook. Best to have more than 5 dates.
+
+
+
+1. Finding a Blind Date
+2. Type the following command into the text field.
+ `blindDate`
+3. Press enter.
+4. Expected Output: The GUI shows a blind date in LoveBook.
+
+### Exiting the Application
+
+1. Exiting the app
+2. Use the `exit` command or click the 'X' button in the top right corner.
+3. Expected: The app closes.
+
+### Saving Data
1. Saving window preferences
- 1. Resize the window to an optimum size. Move the window to a different location. Close the window.
+ 1. Resize the window to an optimum size, preferably full screen. Close the window.
+ 2. Re-launch the app by double-clicking the jar file.
+ 3. Expected Output: The most recent window size and location is retained.
+ 4. Note: The window looks best under 1920 x 1080 resolution, 125% scale.
+
+2. Saving data
+ 1. Launch the app by double-clicking the jar file.
+ 2. Execute an add command to add a `Date` in the database.
+ 3. Close the app.
+ 4. Expected: A `data` folder is created under the current repository where the jar file is located.
+
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
+
+---
+
+## **Appendix: Effort**
+
+Implementing LoveBook was not straightforward and often required us to brainstorm as a team to solve the challenges faced.
+Given below is a summary of the effort our team has put into developing LoveBook as well as challenges faced.
+
+### Evolving of AB3 into LoveBook
+
+As we wanted to morph AB3 to fit into our idea of LoveBook, we had to refactor a large portion of the initial codebase
+and implement several new classes to get the basic minimum viable product of LoveBook.
+This included creating the Date class and its associated inner field classes. We also had to update how the application
+will store Dates and DatePrefs separately. In addition, many previous commands of AB3 had to be refactored or changed,
+and we added several new commands to LoveBook as well. Eventually, we were able to successfully implement both the Date
+and DatePref classes and all their associated commands.
+
+One challenge we faced was implementing the bestMatch feature. Given the tight timeline of the team project, we decided
+to do a simple implementation of this feature that does not provide user with much flexibility. If given more time, we would like
+to develop this further by incorporating the use of artificial intelligence, as it is a relevant feature that will be used in the real
+world and brings value to our target users.
+
+### Revamping of UI
+
+Our dedication to enhancing the aesthetics of LoveBook is highlighted by our attention to visual representation.
+We went beyond mere textual displays, incorporating visually engaging elements such as gender icons, horoscope symbols,
+and star command visual cues, all implemented using JavaFX. These features not only contribute to the overall visual
+appeal of the application but also serve a functional purpose in providing users with quick and intuitive insights into
+important date attributes. As our team was unfamiliar with JavaFX initially, it took us a great amount of time and
+effort to produce an eventual satisfactory and working UI that we were proud to adopt and incorporate into our application.
+
+[Scroll back to _Table of Contents_](#table-of-contents)
+
+
+
+## **Appendix: Planned Enhancements**
+
+1. Improve the command parser to be more robust. Some examples include:
+
+ - Gender entered while adding a new date is case-sensitive. We are planning to make it case-insensitive.
+ - Adding dates with the same name is currently not allowed. We are planning to allow this.
+ - Allowing some fields to be optional if user doesn't have access to the information. For example, if the user does
+ not know the income of the date, he/she can leave it blank. Currently, this is not allowed. We are planning to
+ allow this.
+
+2. Improve the income field to be more robust
+
+ - Currently, the income field is unable to accept a range of values, which might not be inclusive of people who
+ have careers with variable income.
+ - Additionally, right now the income field does not accept a value of 0. This is not inclusive towards students
+ who may not have any income. Hence, we plan to modify the field to accept a value of 0, on top of supporting a
+ range of values
+
+3. Improve issues regarding sorting stability
- 1. Re-launch the app by double-clicking the jar file.
- Expected: The most recent window size and location is retained.
+ - Currently, you are able to sort the dates by a specific field. However, if we sort by income for instance, and two
+ dates have the same value, then when one of those two dates are modified by operations such as star or edit, the
+ order of the two of them can change. The dates are still sorted in order, just that the stability is disrupted. We
+ intend to improve upon our star and edit commands such that they do not disrupt the stability in the future.
-1. _{ more test cases … }_
+4. Improve the filter feature to be more robust. Some examples include:
-### Deleting a person
+ - Currently, the filter feature only allows the user to filter by metrics limited to name, age, gender and height.
+ We are planning to allow the user to filter by other metrics such as horoscope and income.
+ - Currently, the filter feature only allows the user to filter by a single keyword for a single metric. We are
+ planning to allow the user to filter by multiple keywords.
-1. Deleting a person while all persons are being shown
+5. Improve the error message to be more comprehensive
- 1. Prerequisites: List all persons using the `list` command. Multiple persons in the list.
+ - Currently, the error message for user that key in multiple invalid keywords only spots the first invalid keyword.
+ We are planning to allow the user to know all the invalid keywords that he/she has keyed in.
+ - Currently, the error message for filter command with duplicate fields only display the invalid field value error. We are
+ planning to allow the user to know that he/she has keyed in duplicate fields.
- 1. Test case: `delete 1`
- Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated.
+6. Improve the message displayed when the user tries to perform an operation on an empty list
- 1. Test case: `delete 0`
- Expected: No person is deleted. Error details shown in the status message. Status bar remains the same.
+ - Currently, for some commands like edit and sort, the message displayed is simply based on the validity check of the parameters and it does not tell the user that the
+ list is empty. For instance, when the user sorts an empty list, the message displayed is "Sorted!" which is not very helpful. Hence, we are planning to tell the user that the list is empty and that the operation cannot be performed.
- 1. Other incorrect delete commands to try: `delete`, `delete x`, `...` (where x is larger than the list size)
- Expected: Similar to previous.
+7. Improve the presets bar feature to be more comprehensive and clear
-1. _{ more test cases … }_
+ - Currently, the presets bar feature only accommodates for the commands: `add`, `edit`, `delete`, `setP` and `showP`.
+ - In the future, we plan to add more presets buttons for all 16 commands in the application.
+ - Furthermore, even though there's `clear` command, the button "clear" removes all text in the command box, making
+ it ambiguous. We plan to change this in a future iteration like a trash can icon.
-### Saving data
+8. Improve the filter and sort command formats
-1. Dealing with missing/corrupted data files
+ - Currently, the filter and sort commands do not have a strict format. For example, if the user enters a filter command
+ with at least one valid metric and valid metric value, the filter command will still be executed successfully. We plan
+ to come up with a stricter filter and sort format in the future to make it more user-friendly.
- 1. _{explain how to simulate a missing/corrupted file, and the expected behavior}_
+9. Improve the best match feature to be more flexible
+ - Currently, the best match feature gives equal weightage to all characteristics: `Income`, `Age`, `Height` and `Horoscope`
+ - To better suit the user preferences, we plan to make the weightage customizable, so users can change the weightage for each characteristic
-1. _{ more test cases … }_
+[Scroll back to _Table of Contents_](#table-of-contents)
diff --git a/docs/Documentation.md b/docs/Documentation.md
index 3e68ea364e7..57cc4db890b 100644
--- a/docs/Documentation.md
+++ b/docs/Documentation.md
@@ -1,29 +1,21 @@
---
-layout: page
-title: Documentation guide
+ layout: default.md
+ title: "Documentation guide"
+ pageNav: 3
---
-**Setting up and maintaining the project website:**
-
-* We use [**Jekyll**](https://jekyllrb.com/) to manage documentation.
-* The `docs/` folder is used for documentation.
-* To learn how set it up and maintain the project website, follow the guide [_[se-edu/guides] **Using Jekyll for project documentation**_](https://se-education.org/guides/tutorials/jekyll.html).
-* Note these points when adapting the documentation to a different project/product:
- * The 'Site-wide settings' section of the page linked above has information on how to update site-wide elements such as the top navigation bar.
- * :bulb: In addition to updating content files, you might have to update the config files `docs\_config.yml` and `docs\_sass\minima\_base.scss` (which contains a reference to `AB-3` that comes into play when converting documentation pages to PDF format).
-* If you are using Intellij for editing documentation files, you can consider enabling 'soft wrapping' for `*.md` files, as explained in [_[se-edu/guides] **Intellij IDEA: Useful settings**_](https://se-education.org/guides/tutorials/intellijUsefulSettings.html#enabling-soft-wrapping)
+# Documentation Guide
+* We use [**MarkBind**](https://markbind.org/) to manage documentation.
+* The `docs/` folder contains the source files for the documentation website.
+* To learn how set it up and maintain the project website, follow the guide [[se-edu/guides] Working with Forked MarkBind sites](https://se-education.org/guides/tutorials/markbind-forked-sites.html) for project documentation.
**Style guidance:**
* Follow the [**_Google developer documentation style guide_**](https://developers.google.com/style).
+* Also, relevant is the [_se-edu/guides **Markdown coding standard**_](https://se-education.org/guides/conventions/markdown.html).
-* Also relevant is the [_[se-edu/guides] **Markdown coding standard**_](https://se-education.org/guides/conventions/markdown.html)
-
-**Diagrams:**
-
-* See the [_[se-edu/guides] **Using PlantUML**_](https://se-education.org/guides/tutorials/plantUml.html)
-**Converting a document to the PDF format:**
+**Converting to PDF**
-* See the guide [_[se-edu/guides] **Saving web documents as PDF files**_](https://se-education.org/guides/tutorials/savingPdf.html)
+* See the guide [_se-edu/guides **Saving web documents as PDF files**_](https://se-education.org/guides/tutorials/savingPdf.html).
diff --git a/docs/Gemfile b/docs/Gemfile
deleted file mode 100644
index c8385d85874..00000000000
--- a/docs/Gemfile
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-source "https://rubygems.org"
-
-git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
-
-gem 'jekyll'
-gem 'github-pages', group: :jekyll_plugins
-gem 'wdm', '~> 0.1.0' if Gem.win_platform?
-gem 'webrick'
diff --git a/docs/Logging.md b/docs/Logging.md
index 5e4fb9bc217..589644ad5c6 100644
--- a/docs/Logging.md
+++ b/docs/Logging.md
@@ -1,8 +1,10 @@
---
-layout: page
-title: Logging guide
+ layout: default.md
+ title: "Logging guide"
---
+# Logging guide
+
* We are using `java.util.logging` package for logging.
* The `LogsCenter` class is used to manage the logging levels and logging destinations.
* The `Logger` for a class can be obtained using `LogsCenter.getLogger(Class)` which will log messages according to the specified logging level.
diff --git a/docs/SettingUp.md b/docs/SettingUp.md
index 275445bd551..77083468697 100644
--- a/docs/SettingUp.md
+++ b/docs/SettingUp.md
@@ -1,30 +1,39 @@
---
-layout: page
-title: Setting up and getting started
+ layout: default.md
+ title: "Setting up and getting started"
+ pageNav: 3
---
-* Table of Contents
-{:toc}
+# Setting up and getting started
+
+
--------------------------------------------------------------------------------------------------------------------
## Setting up the project in your computer
-
:exclamation: **Caution:**
+
+**Caution:**
Follow the steps in the following guide precisely. Things will not work out if you deviate in some steps.
-
+
+
First, **fork** this repo, and **clone** the fork into your computer.
If you plan to use Intellij IDEA (highly recommended):
1. **Configure the JDK**: Follow the guide [_[se-edu/guides] IDEA: Configuring the JDK_](https://se-education.org/guides/tutorials/intellijJdk.html) to to ensure Intellij is configured to use **JDK 11**.
-1. **Import the project as a Gradle project**: Follow the guide [_[se-edu/guides] IDEA: Importing a Gradle project_](https://se-education.org/guides/tutorials/intellijImportGradleProject.html) to import the project into IDEA.
- :exclamation: Note: Importing a Gradle project is slightly different from importing a normal Java project.
-1. **Verify the setup**:
- 1. Run the `seedu.address.Main` and try a few commands.
- 1. [Run the tests](Testing.md) to ensure they all pass.
+2. **Import the project as a Gradle project**: Follow the guide [_[se-edu/guides] IDEA: Importing a Gradle project_](https://se-education.org/guides/tutorials/intellijImportGradleProject.html) to import the project into IDEA.
+
+
+
+ Note: Importing a Gradle project is slightly different from importing a normal Java project.
+
+
+3. **Verify the setup**:
+ 1. Run the `seedu.lovebook.Main` and try a few commands.
+ 2. [Run the tests](Testing.md) to ensure they all pass.
--------------------------------------------------------------------------------------------------------------------
@@ -34,20 +43,22 @@ If you plan to use Intellij IDEA (highly recommended):
If using IDEA, follow the guide [_[se-edu/guides] IDEA: Configuring the code style_](https://se-education.org/guides/tutorials/intellijCodeStyle.html) to set up IDEA's coding style to match ours.
-
:bulb: **Tip:**
+
+ **Tip:**
Optionally, you can follow the guide [_[se-edu/guides] Using Checkstyle_](https://se-education.org/guides/tutorials/checkstyle.html) to find how to use the CheckStyle within IDEA e.g., to report problems _as_ you write code.
-
+
+
-1. **Set up CI**
+2. **Set up CI**
This project comes with a GitHub Actions config files (in `.github/workflows` folder). When GitHub detects those files, it will run the CI for your project automatically at each push to the `master` branch or to any PR. No set up required.
-1. **Learn the design**
+3. **Learn the design**
- When you are ready to start coding, we recommend that you get some sense of the overall design by reading about [AddressBook’s architecture](DeveloperGuide.md#architecture).
+ When you are ready to start coding, we recommend that you get some sense of the overall design by reading about [LoveBook’s architecture](DeveloperGuide.md#architecture).
-1. **Do the tutorials**
+4. **Do the tutorials**
These tutorials will help you get acquainted with the codebase.
* [Tracing code](tutorials/TracingCode.md)
diff --git a/docs/Style.puml b/docs/Style.puml
new file mode 100644
index 00000000000..f7d7347ae84
--- /dev/null
+++ b/docs/Style.puml
@@ -0,0 +1,79 @@
+/'
+ 'Commonly used styles and colors across diagrams.
+ 'Refer to https://plantuml-documentation.readthedocs.io/en/latest for a more
+ 'comprehensive list of skinparams.
+ '/
+
+
+'T1 through T4 are shades of the original color from lightest to darkest
+
+!define UI_COLOR #1D8900
+!define UI_COLOR_T1 #83E769
+!define UI_COLOR_T2 #3FC71B
+!define UI_COLOR_T3 #166800
+!define UI_COLOR_T4 #0E4100
+
+!define LOGIC_COLOR #3333C4
+!define LOGIC_COLOR_T1 #C8C8FA
+!define LOGIC_COLOR_T2 #6A6ADC
+!define LOGIC_COLOR_T3 #1616B0
+!define LOGIC_COLOR_T4 #101086
+
+!define MODEL_COLOR #9D0012
+!define MODEL_COLOR_T1 #F97181
+!define MODEL_COLOR_T2 #E41F36
+!define MODEL_COLOR_T3 #7B000E
+!define MODEL_COLOR_T4 #51000A
+
+!define STORAGE_COLOR #A38300
+!define STORAGE_COLOR_T1 #FFE374
+!define STORAGE_COLOR_T2 #EDC520
+!define STORAGE_COLOR_T3 #806600
+!define STORAGE_COLOR_T2 #544400
+
+!define USER_COLOR #000000
+
+skinparam Package {
+ BackgroundColor #FFFFFF
+ BorderThickness 1
+ FontSize 16
+}
+
+skinparam Class {
+ FontColor #FFFFFF
+ FontSize 15
+ BorderThickness 1
+ BorderColor #FFFFFF
+ StereotypeFontColor #FFFFFF
+ FontName Arial
+}
+
+skinparam Actor {
+ BorderColor USER_COLOR
+ Color USER_COLOR
+ FontName Arial
+}
+
+skinparam Sequence {
+ MessageAlign center
+ BoxFontSize 15
+ BoxPadding 0
+ BoxFontColor #FFFFFF
+ FontName Arial
+}
+
+skinparam Participant {
+ FontColor #FFFFFFF
+ Padding 20
+}
+
+skinparam ArrowFontStyle bold
+skinparam MinClassWidth 50
+skinparam ParticipantPadding 10
+skinparam Shadowing false
+skinparam DefaultTextAlignment center
+skinparam packageStyle Rectangle
+
+hide footbox
+hide members
+hide circle
diff --git a/docs/Testing.md b/docs/Testing.md
index 8a99e82438a..6fa611f8da4 100644
--- a/docs/Testing.md
+++ b/docs/Testing.md
@@ -1,12 +1,15 @@
---
-layout: page
-title: Testing guide
+ layout: default.md
+ title: "Testing guide"
+ pageNav: 3
---
-* Table of Contents
-{:toc}
+# Testing guide
---------------------------------------------------------------------------------------------------------------------
+
+
+
+
## Running tests
@@ -19,8 +22,11 @@ There are two ways to run tests.
* **Method 2: Using Gradle**
* Open a console and run the command `gradlew clean test` (Mac/Linux: `./gradlew clean test`)
-
:link: **Link**: Read [this Gradle Tutorial from the se-edu/guides](https://se-education.org/guides/tutorials/gradle.html) to learn more about using Gradle.
-
+
+
+**Link**: Read [this Gradle Tutorial from the se-edu/guides](https://se-education.org/guides/tutorials/gradle.html) to learn more about using Gradle.
+
+
--------------------------------------------------------------------------------------------------------------------
@@ -29,8 +35,8 @@ There are two ways to run tests.
This project has three types of tests:
1. *Unit tests* targeting the lowest level methods/classes.
- e.g. `seedu.address.commons.StringUtilTest`
-1. *Integration tests* that are checking the integration of multiple code units (those code units are assumed to be working).
- e.g. `seedu.address.storage.StorageManagerTest`
-1. Hybrids of unit and integration tests. These test are checking multiple code units as well as how the are connected together.
- e.g. `seedu.address.logic.LogicManagerTest`
+ e.g. `seedu.lovebook.commons.StringUtilTest`
+2. *Integration tests* that are checking the integration of multiple code units (those code units are assumed to be working).
+ e.g. `seedu.lovebook.storage.StorageManagerTest`
+3. Hybrids of unit and integration tests. These test are checking multiple code units as well as how they are connected together.
+ e.g. `seedu.lovebook.logic.LogicManagerTest`
diff --git a/docs/UserGuide.md b/docs/UserGuide.md
index 57437026c7b..edefbd18895 100644
--- a/docs/UserGuide.md
+++ b/docs/UserGuide.md
@@ -1,197 +1,682 @@
---
-layout: page
-title: User Guide
+layout: default.md
+title: "User Guide"
+pageNav: 4
---
-AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized for use via a Command Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB3 can get your contact management tasks done faster than traditional GUI apps.
+# LoveBook User Guide
+
+## **Overview**
+LoveBook, is a **dating-focused** application, revolving around providing **serial daters** with a **convenient**
+and **enjoyable** tool to enhance their dating experiences. Featuring **user preferences management**, **date
+organization**,
+**customizable filtering options** and **best match algorithms**, LoveBook enhances the **efficiency** and
+**effectiveness** of your online dating journey.
+
+## **Table of Contents**
+
+* [Glossary](#glossary)
+ * [Common Symbols](#common-symbols)
+* [Quick Start](#quick-start)
+ * [Download and Installation](#download-and-installation)
+ * [Navigating the GUI](#navigating-the-gui)
+ * [LoveBook Tutorial: Getting started](#lovebook-tutorial-getting-started)
+* [Features](#features)
+ * [Managing Dates](#managing-dates)
+ * [Adding a new date: `add`](#adding-a-new-date-add)
+ * [Editing a date: `edit`](#editing-a-date-edit)
+ * [Deleting a date: `delete`](#deleting-a-date-delete)
+ * [Listing all dates: `list`](#listing-all-dates-list)
+ * [Clearing all dates: `clear`](#clearing-all-dates-clear)
+ * [Starring a date: `star`](#starring-a-date-star)
+ * [Unstarring a date: `unstar`](#unstarring-a-date-unstar)
+ * [Sorting, Finding dates](#sorting-finding-dates)
+ * [Finding a date: `find`](#finding-a-date-find)
+ * [Filtering dates by a certain metric: `filter`](#filtering-dates-by-a-certain-metric-filter)
+ * [Sorting dates by a certain metric: `sort`](#sorting-dates-by-a-certain-metric-sort)
+ * [Managing Preferences and Getting Matches](#managing-preferences-and-getting-matches)
+ * [Showing your date preferences: `showP`](#showing-your-date-preferences-showp)
+ * [Setting your date preferences: `setP`](#setting-your-date-preferences-setp)
+ * [Getting a recommended date: `bestMatch`](#getting-a-recommended-date-bestmatch)
+ * [Getting a blind date: `blindDate`](#getting-a-blind-date-blinddate)
+ * [Other Commands](#other-commands)
+ * [Exiting the application: `exit`](#exiting-the-application-exit)
+ * [Getting help: `help`](#getting-help-help)
+* [FAQ](#faq)
+* [Command Summary](#command-summary)
+
+
+
+## **Glossary**
+
+| Term | Definition |
+|------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
+| Date | A person that the user is interested in and is currently seeing. |
+| Metric | A certain characteristic of a date. (e.g. Gender, Height) |
+| Command | Text that the user types into the application to perform an action. |
+| Parameter | A value that the user provides to the application when executing a command. (e.g. in`gender/M` M is a parameter) |
+| GUI | Graphical User Interface |
+| CLI | Command Line Interface |
+| Mainstream OS | Windows, Linux, Unix, OS-X |
+| | To provide you with relevant suggestions on how to use the commands as well as address potential confusions when using these commands. |
+| | To inform you of some unintended or unexpected consequences that may occur when you use the commands. |
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+
+### **Common Symbols**
+
+As you navigate through the application, you may come across certain symbols depicting your date's gender and horoscope.
+Here's a quick guide to help you understand what they mean.
+
+#### Gender Symbols
+
+| Gender | Symbol |
+|--------|----------------------------------------------------------------------------------------------------------------------------------------|
+| Male | |
+| Female | |
+
+#### Horoscope Symbols
+
+| Horoscope | Symbol | Birthday Range |
+|-------------|------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------|
+| Aries | | March 21 - April 19 |
+| Taurus | | April 20 - May 20 |
+| Gemini | | May 21 - June 20 |
+| Cancer | | June 21 - July 22 |
+| Leo | | July 23 - August 22 |
+| Virgo | | August 23 - September 22 |
+| Libra | | September 23 - October 22 |
+| Scorpio | | October 23 - November 21 |
+| Sagittarius | | November 22 - December 21 |
+| Capricorn | | December 22 - January 19 |
+| Aquarius | | January 20 - February 18 |
+| Pisces | | February 19 - March 20 |
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
-* Table of Contents
-{:toc}
+---
---------------------------------------------------------------------------------------------------------------------
+## **Quick Start**
-## Quick start
+### **Download and Installation**
-1. Ensure you have Java `11` or above installed in your Computer.
+1. Ensure that you have Java `11` or above installed in your Computer.
+2. Download the latest `LoveBook.jar` from [here](https://github.com/AY2324S1-CS2103T-F10-2/tp).
+3. Double-click the file to start the app. The window that appears will be similar to the one below.
+
+ ![startScreen](images/emptyLoveBook.png)
+
+4. Follow the tutorial below to get started.
-1. Download the latest `addressbook.jar` from [here](https://github.com/se-edu/addressbook-level3/releases).
+### **Navigating the GUI**
-1. Copy the file to the folder you want to use as the _home folder_ for your AddressBook.
+If you're new to this program, the initial screen might appear a bit daunting. Don't fret; let's explore the various
+elements of the LoveBook interface together.
+We suggest enlarging the program window for a clearer perspective, allowing you to view more content.
-1. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar addressbook.jar` command to run the application.
- A GUI similar to the below should appear in a few seconds. Note how the app contains some sample data.
- ![Ui](images/Ui.png)
+Here's the detailed breakdown of the LoveBook screen:
+![GUI](images/navigation.png)
-1. Type the command in the command box and press Enter to execute it. e.g. typing **`help`** and pressing Enter will open the help window.
- Some example commands you can try:
+- **Menu Bar** - This is where you can find the `File` and `Help` options. Click on `File` to access the `Exit` option.
+ Click on `Help` to access the `Help` option.
+- **Command Box** - This is where you type in your commands. Press `Enter` to execute the command.
+- **Presets Bar** - This is where you can find the preset commands. Click on a preset command to populate your command
+ box.
+- **Result Display** - This is where the results of your commands are displayed.
+- **Date List Panel** - This is where the list of dates are displayed. The list is scrollable, and you can scroll up and
+ down to view the entire list.
- * `list` : Lists all contacts.
+
- * `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` : Adds a contact named `John Doe` to the Address Book.
+### **LoveBook Tutorial: Getting started**
- * `delete 3` : Deletes the 3rd contact shown in the current list.
+Now that you are familiar with the layout of LoveBook, we recommend you try the following steps to develop a feel for
+the core features of LoveBook.
- * `clear` : Deletes all contacts.
+#### 1. Adding a date
- * `exit` : Exits the app.
+So you've just started dating. How do you begin using this app?
-1. Refer to the [Features](#features) below for details of each command.
+Let's say you went out on a date with John. Throughout your date you find out key things about him, he's 123cm tall,
+earns 3k a month, his horoscope is Libra.
+Here you can add John to LoveBook using the add command:
---------------------------------------------------------------------------------------------------------------------
+In the command box, enter `add name/John Doe age/21 gender/M height/123 income/3000 horoscope/Libra` and press
+the `enter` key.
+This will add John to LoveBook.
-## Features
+
-
+Let's imagine you've added a couple of dates to the LoveBook already. It should look something like this now:
-**:information_source: Notes about the command format:**
+
-* Words in `UPPER_CASE` are the parameters to be supplied by the user.
- e.g. in `add n/NAME`, `NAME` is a parameter which can be used as `add n/John Doe`.
+
-* Items in square brackets are optional.
- e.g `n/NAME [t/TAG]` can be used as `n/John Doe t/friend` or as `n/John Doe`.
+#### 2. Starring a date
+
+With so many dates you might want to start keeping tabs on dates that are perhaps more exceptional. Fret not, star dates
+as you go along
+in your journey. Here you can star John for instance, using the star command:
+Enter `star 2`.
+This will star John.
+
+![starCommandExample](images/user-commands/starCommandExample.png)
+
+
+
+#### 3. Filtering dates
+
+With so many dates, you might want to start filtering down to the metrics that matter. Perhaps you seek someone younger,
+simply filter for
+a specific age. Here you can filter for an age of 21 for instance, using the filter command:
+Enter `filter age/21`.
+This will filter for John.
+
+![filterCommandExample](images/user-commands/filterCommandExample.png)
+
+
+
+#### 4. Set Preferences
+
+Well, maybe you are indecisive as a serial dater, and you want a third party opinion. Fret not, simply begin by keying
+in your preferences using the
+setPreferences command:
+Enter `setP age/22 height/130 income/3200 horoscope/Libra`
+This will set your preferences like so:
+
+![setPreferencesCommandExample](images/user-commands/setPreferencesCommandExample.png)
+
+
+
+#### 5. Best Match
+
+And here it is, to get the match of your dreams, simply use the bestMatch command:
+Enter `bestMatch`
+
+![bestMatchCommandExample](images/user-commands/bestMatchCommandExample.png)
+
+
+
+### Congrats! You have completed the tutorial!
+
+The tutorial shows you what a typical workflow might look like on LoveBook. Do continue to peruse the commands section
+which contains
+other commands that, while not worth covering in a quick start tutorial, are certainly important to using LoveBook as a
+whole.
+Here's to you embarking on your LoveBook journey!
-* Items with `…` after them can be used multiple times including zero times.
- e.g. `[t/TAG]…` can be used as ` ` (i.e. 0 times), `t/friend`, `t/friend t/family` etc.
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+---
+
+## **Features**
+
+
+
+* Words in `UPPER_CASE` are the parameters to be supplied by the user.
+ e.g. in `edit INDEX METRIC/NEW_ARG`, `INDEX`, `NEW_ARG` and `METRIC` are parameters which can be used as
+ `edit 2 income/3000`.
+* Items in square brackets are optional.
+ e.g `age/AGE [horoscope/HOROSCOPE]` can be used as `age/22 horoscope/ARIES` or as `age/22`.
* Parameters can be in any order.
- e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable.
+ e.g. if the command specifies `name/NAME age/AGE`, `age/AGE name/NAME` is also acceptable.
+* For commands that accept a positive integer, the integer cannot be preceded with a leading zero.
+ For instance, `star 9` is valid, but `star 09` is invalid
+* Extraneous parameters for commands that do not take in parameters (such as `help`, `list`, `exit` and `clear`)
+ will be ignored. e.g. if the command specifies `help 123`, it will be interpreted as `help`.
+* If you are using a PDF version of this document, be careful when copying and pasting commands that span multiple lines
+ as space characters surrounding line-breaks may be omitted when copied over to the application.
+
+
+
+
+
+The following table shows the list of metrics and their respective constraints.
+
+| Metric | Prefix | Constraints |
+|-----------|--------------|-----------------------------------------------------------------------------------------|
+| Name | `name/` | Name can only contain letters, numbers and spaces. It must not be left blank. |
+| Age | `age/` | Age should be a positive integer between 18 and 150 (inclusive). |
+| Gender | `gender/` | Gender should be either M or F. It is case sensitive. |
+| Height | `height/` | Height should be a positive integer in cm between 100cm and 250cm (inclusive). |
+| Income | `income/` | Income (per month) should be a positive integer in SGD less than or equal to a million. |
+| Horoscope | `horoscope/` | Horoscope should be a valid zodiac sign. It is case insensitive. |
+
+
-* Extraneous parameters for commands that do not take in parameters (such as `help`, `list`, `exit` and `clear`) will be ignored.
- e.g. if the command specifies `help 123`, it will be interpreted as `help`.
+---
-* If you are using a PDF version of this document, be careful when copying and pasting commands that span multiple lines as space characters surrounding line-breaks may be omitted when copied over to the application.
-
+### **Managing Dates**
-### Viewing help : `help`
+#### **Adding a new date: `add`**
-Shows a message explaning how to access the help page.
+Adds a date to the LoveBook.
-![help message](images/helpMessage.png)
+
-Format: `help`
+All parameters are compulsory.
+
-### Adding a person: `add`
+
-Adds a person to the address book.
+The date added must have a unique name that is not already in the LoveBook.
-Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…`
+
-
:bulb: **Tip:**
-A person can have any number of tags (including 0)
-
+Format: `add name/NAME age/AGE gender/GENDER height/HEIGHT horoscope/HOROSCOPE income/INCOME`
-Examples:
-* `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01`
-* `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal`
+Example: `add name/John Doe age/21 gender/M height/123 income/3000 horoscope/Libra`
+
+![addCommandExample](images/user-commands/addCommandExample.png)
-### Listing all persons : `list`
+Expected output: `New date added: John Doe; Age: 21; Gender: M; Height: 123; Income: 3000; Horoscope: LIBRA`
-Shows a list of all persons in the address book.
+[Scroll back to *Table of Contents*](#table-of-contents)
+
-Format: `list`
+#### **Editing a date: `edit`**
-### Editing a person : `edit`
+Edits a date in the specified index in the LoveBook.
-Edits an existing person in the address book.
+Format: `edit INDEX [name/NAME] [age/AGE] [gender/GENDER] [height/HEIGHT] [income/INCOME] [horoscope/HOROSCOPE]`
-Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]…`
+
-* Edits the person at the specified `INDEX`. The index refers to the index number shown in the displayed person list. The index **must be a positive integer** 1, 2, 3, …
-* At least one of the optional fields must be provided.
-* Existing values will be updated to the input values.
-* When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative.
-* You can remove all the person’s tags by typing `t/` without
- specifying any tags after it.
+* Metric is limited to `gender, age, horoscope, name, height, income` only.
+* New value replaces the existing value.
+* User can edit up to n number of metrics in one command line, where n refers to the number of metrics available.
+* The index must be a positive integer, and be within the range of the recorded dates. For example, if there are 3 Dates in LoveBook, the indices are 1, 2 and 3.
+
+
Examples:
-* `edit 1 p/91234567 e/johndoe@example.com` Edits the phone number and email address of the 1st person to be `91234567` and `johndoe@example.com` respectively.
-* `edit 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags.
-### Locating persons by name: `find`
+- `edit 1 name/John` (editing 1 metric)
+- `edit 1 name/John horoscope/Cancer` (editing 2 metrics)
+- `edit 1 horoscope/Cancer name/John` (sequence doesn't matter)
-Finds persons whose names contain any of the given keywords.
+
-Format: `find KEYWORD [MORE_KEYWORDS]`
+![editCommandExample](images/user-commands/editCommandExample.png)
-* The search is case-insensitive. e.g `hans` will match `Hans`
-* The order of the keywords does not matter. e.g. `Hans Bo` will match `Bo Hans`
-* Only the name is searched.
-* Only full words will be matched e.g. `Han` will not match `Hans`
-* Persons matching at least one keyword will be returned (i.e. `OR` search).
- e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang`
+Expected Output: `Edited Date: John; Age: 21; Gender: M; Height: 123; Income: 3000; Horoscope: LIBRA`
-Examples:
-* `find John` returns `john` and `John Doe`
-* `find alex david` returns `Alex Yeoh`, `David Li`
- ![result for 'find alex david'](images/findAlexDavidResult.png)
+[Scroll back to *Table of Contents*](#table-of-contents)
+
-### Deleting a person : `delete`
+#### **Deleting a date: `delete`**
-Deletes the specified person from the address book.
+Deletes the specified date from the LoveBook.
Format: `delete INDEX`
-* Deletes the person at the specified `INDEX`.
-* The index refers to the index number shown in the displayed person list.
-* The index **must be a positive integer** 1, 2, 3, …
+
-Examples:
-* `list` followed by `delete 2` deletes the 2nd person in the address book.
-* `find Betsy` followed by `delete 1` deletes the 1st person in the results of the `find` command.
+The index must be a positive integer, and be within the range of the recorded dates. For example, if there are 3 Dates in LoveBook, the indices are 1, 2 and 3.
+
+
+
+Example: `delete 1`
+
+![deleteCommandExample](images/user-commands/deleteCommandExample.png)
+
+Expected output: `Deleted Date: Ben Brown; Age: 21; Gender: F; Height: 194; Income: 6000; Horoscope: GEMINI`
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+
+#### **Listing all dates: `list`**
-### Clearing all entries : `clear`
+Shows a list of all dates in the LoveBook.
-Clears all entries from the address book.
+Format: `list`
+
+![listCommandExample](images/user-commands/listCommandExample.png)
+
+Expected output: `Listed all Dates`
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+
+#### **Clearing all dates: `clear`**
+
+Clears all dates in the LoveBook.
+
+
+
+This command is irreversible. All data will be lost. Please use this command with caution.
+
+
Format: `clear`
-### Exiting the program : `exit`
+![clearCommandExample-1](images/user-commands/clearCommandExample1.png)
+
+![clearCommandExample-2](images/user-commands/clearCommandExample2.png)
+
+Expected output: `LoveBook has been cleared!`
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+#### **Starring a date: `star`**
+
+Stars a date in the LoveBook.
+
+Format: `star INDEX`
+
+
+
+* The index must be a positive integer, and be within the range of the recorded dates.
+* For example, if there are 3 Dates in LoveBook, the indices are 1, 2 and 3.
+
+
+
+Example: `star 1`
+
+![starCommandExample-1](images/user-commands/starCommandExample1.png)
+
+Expected output: `Starred Date: John Doe; Age: 21; Gender: F; Height: 245; Income: 3000; Horoscope: LIBRA`
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+#### **Unstarring a date: `unstar`**
+
+Unstars a date in the LoveBook.
+
+Format: `unstar INDEX`
+
+
+
+The index must be a positive integer, and be within the range of the recorded dates. For example, if there are 3 Dates in LoveBook, the indices are 1, 2 and 3.
+
+
+
+Example: `unstar 1`
+
+![unstarCommandExample](images/user-commands/unstarCommandExample.png)
+
+Expected output: `Unstarred Date: John Doe; Age: 21; Gender: M; Height: 123; Income: 3000; Horoscope: LIBRA`
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+### **Sorting, Finding dates**
+
+#### **Finding a date: `find`**
+
+Finds a date in the LoveBook by a specific name(s)
+
+Format: `find NAME [MORE_NAMES]`
+
+
+
+More names can be added to the command line, and the search will be conducted for all names provided.
+
+
+
+Example:
+
+- `find Cleon`
+- `find Cleon John`
+
+Expected Output: `Lists the dates with the name(s) specified`
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+#### **Filtering dates by a certain metric: `filter`**
+
+Filters the dates in the LoveBook by a specific metric.
+
+Format: `filter METRIC/ARG`
+
+
+
+* Metric is limited to `gender, age, name, height` only
+* Arguments should be non-empty and adhere to the constraints of the metric
+* Multiple valid METRIC/ARG pairs can be added to the command line, and the search will be conducted for all pairs
+ provided. e.g. `filter gender/M age/21`
+* Filter format is valid as long as there is one valid METRIC/ARG pair. e.g. `filter xx gender/M` works as well, where xx is not a metric
+
+
+
+
+
+When filtering dates by a valid metric and an invalid metric, the valid METRIC/ARG pair will be used to filter the dates.
+Note that the invalid metric will be ignored and there will be no checking of the validity of the invalid metric value.
+
+
+
+Example:
+
+- `filter name/Cleon`
+- `filter gender/M`
+- `filter gender/M name/Cleon`
+- `filter hi gender/M` (provides flexibility to the user in the case they mistype a metric)
+- `filter income/20 name/Cleon` (this only returns dates with name Cleon since income is an invalid metric)
+
+Expected Output: `Lists the dates with the valid metric values specified`
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+
+#### **Sorting dates by a certain metric: `sort`**
+
+Sorts the dates in the LoveBook by a specific metric.
+
+Format: `sort METRIC/ORDER`
+
+
+
+* Metrics are limited to `name/`, `age/`, `height/`, `income/` and `horoscope/` only.
+* Order is limited to `increasing` or `decreasing` only and is case-sensitive.
+* Sort command is valid as long as there is only one valid METRIC/ORDER pair and no other metrics are provided.
+
+
+
+
+
+When sorting dates by a field where both have an equal value, say Kevin and Wayne are sorted by income and both have
+an income of 2000, applying commands such as edit or star, can affect the stability of the sort. However, the overall
+sorting order by value is preserved.
+
+
+
+Example:
+
+- `sort name/increasing`
+- `sort horoscope/decreasing`
+- `sort xx income/decreasing`, where xx is not a metric (provides flexibility to the user in the case they mistype a metric)
+
+Expected Output: `Lists the dates in the order specified`
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+
+### **Managing Preferences and Getting Matches**
+
+
+
+* By default, Date Preference is set to:
+ * AGE: 21
+ * HEIGHT: 170
+ * INCOME: 10000
+ * HOROSCOPE: ARIES
+* If you wish to change your Date Preference, please use the [`setP`](#setting-your-date-preferences-setp) command.
+* The [`bestMatch`](#getting-a-recommended-date-bestmatch) command will use the Date Preference set by the user.
+
+
+
+#### **Showing your date preferences: `showP`**
+
+Shows the User's Date Preference. This can be edited using the [`setP`](#setting-your-date-preferences-setp) command.
+
+Format: `showP`
+
+Expected output: `Here are your preferences: Age: 22; Height: 180; Income: 2000; Horoscope: TAURUS`
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+
+#### **Setting your date preferences: `setP`**
+
+Sets the user's preferences for the matching algorithm.
+
+
+
+* At least one field to edit must be provided.
+* The user's preferences will be used in the [`bestMatch`](#getting-a-recommended-date-bestmatch) command.
+* Gender is not taken into account here
+* The relevant fields are
+ * `age/AGE`
+ * `height/HEIGHT`
+ * `income/INCOME`
+ * `horoscope/HOROSCOPE`
+
+
+
+Format: `setP [age/AGE] [height/HEIGHT] [income/INCOME] [horoscope/HOROSCOPE]`
+
+Example: `setP age/22 height/180 income/2000 horoscope/TAURUS`
+
+![setPCommandExample](images/user-commands/setPCommandExample.png)
+
+Expected output: `Updated Preferences: Age: 22; Height: 180; Income: 2000; Horoscope: TAURUS`
+
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+
+#### **Getting a recommended date: `bestMatch`**
+
+Filters out the most compatible date based on the set preferences.
+
+Format: `bestMatch`
+
+![bestMatchCommandExample-1](images/user-commands/bestMatchCommandExample1.png)
+
+![bestMatchCommandExample-2](images/user-commands/bestMatchCommandExample2.png)
+
+Expected Output: `Here's your best match!`
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+#### **Getting a blind date: `blindDate`**
+
+Outputs a random date from the LoveBook.
+
+Format: `blindDate`
+
+
+
+
+
+
+Expected Output: `Here's a blind date for you!`
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+
+### **Other Commands**
+
+#### **Exiting the application: `exit`**
Exits the program.
Format: `exit`
-### Saving the data
+Expected output: `Exiting LoveBook...`
-AddressBook data are saved in the hard disk automatically after any command that changes the data. There is no need to save manually.
+#### **Getting help: `help`**
-### Editing the data file
+Shows a window to bring user to the LoveBook User Guide.
-AddressBook data are saved automatically as a JSON file `[JAR file location]/data/addressbook.json`. Advanced users are welcome to update data directly by editing that data file.
+Format: `help`
-
:exclamation: **Caution:**
-If your changes to the data file makes its format invalid, AddressBook will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it.
-
+![helpCommandExample](images/user-commands/helpCommandExample.png)
-### Archiving data files `[coming in v2.0]`
+Expected output: `Opened help window.`
-_Details coming soon ..._
+[Scroll back to *Table of Contents*](#table-of-contents)
---------------------------------------------------------------------------------------------------------------------
+
+
+---
-## FAQ
+## **FAQ**
**Q**: How do I transfer my data to another Computer?
-**A**: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous AddressBook home folder.
+**A**: Install the app in the other computer and overwrite the empty data file with the file that
+contains the data of your previous LoveBook home folder.
---------------------------------------------------------------------------------------------------------------------
+**Q**: Is my data stored in the cloud? Will I be open to data breaches?
+**A**: No, all your data is stored locally, no need to fear a potential data hack.
-## Known issues
+**Q**: Do I have to save before exiting the application for my data to safely backed up on my computer?
+**A**: All your data is saved on your computer as soon as you enter the command in. There is no need to manually save
+your data. In the event of a power outage, all your data will be safe.
-1. **When using multiple screens**, if you move the application to a secondary screen, and later switch to using only the primary screen, the GUI will open off-screen. The remedy is to delete the `preferences.json` file created by the application before running the application again.
+**Q**: Where do I go if I have issues with LoveBook?
+**A**: You may leave your issues [here](https://github.com/AY2324S1-CS2103T-F10-2/tp/issues).
---------------------------------------------------------------------------------------------------------------------
+**Q**: What happens if I enter invalid data into the stored data file?
+**A**: LoveBook will clear all the existing data and reset to as it was when you installed it. It is highly discouraged
+to manually edit the data file.
-## Command summary
+**Q**: How do I change my date's avatar?
+**A**: Currently, the avatars are randomly selected from a pool of 9 avatars. We are working on a feature to allow users
+to choose their own avatars.
-Action | Format, Examples
---------|------------------
-**Add** | `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…` e.g., `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague`
-**Clear** | `clear`
-**Delete** | `delete INDEX` e.g., `delete 3`
-**Edit** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]…` e.g.,`edit 2 n/James Lee e/jameslee@example.com`
-**Find** | `find KEYWORD [MORE_KEYWORDS]` e.g., `find James Jake`
-**List** | `list`
-**Help** | `help`
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+
+---
+
+## **Command Summary**
+
+
+
+Commands are sorted by alphabetical order.
+
+
+
+| Action | Format | Examples |
+|------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------|
+| [Adding a new date](#adding-a-new-date-add) | `add name/NAME age/AGE gender/GENDER height/HEIGHT horoscope/HOROSCOPE income/INCOME` | `add name/John age/25 gender/M height/175 horoscope/Aries income/5000` |
+| [Getting a recommended date](#getting-a-recommended-date-bestmatch) | `bestMatch` | `bestMatch` |
+| [Getting a blind date](#getting-a-blind-date-blinddate) | `blindDate` | `blindDate` |
+| [Clearing all dates](#clearing-all-dates-clear) | `clear` | `clear` |
+| [Deleting a date](#deleting-a-date-delete) | `delete INDEX` | `delete 2` |
+| [Editing a date](#editing-a-date-edit) | `edit INDEX [name/NAME] [age/AGE] [gender/GENDER] [height/HEIGHT] [income/INCOME] [horoscope/HOROSCOPE]` | `edit 3 name/Cleon` |
+| [Exiting the application](#exiting-the-application-exit) | `exit` | `exit` |
+| [Filtering dates by a certain metric](#filtering-dates-by-a-certain-metric-filter) | `filter METRIC/ARG` | `filter name/Cleon` |
+| [Finding a date](#finding-a-date-find) | `find NAME [MORE_NAMES]` | `find Cleon` |
+| [Getting help](#getting-help-help) | `help` | `help` |
+| [Listing all dates](#listing-all-dates-list) | `list` | `list` |
+| [Setting your date preferences](#setting-your-date-preferences-setp) | `setP [age/AGE] [height/HEIGHT] [income/INCOME] [horoscope/HOROSCOPE]` | `setP age/22 height/180 income/2000 horoscope/TAURUS` |
+| [Showing your date preferences](#showing-your-date-preferences-showp) | `showP` | `showP` |
+| [Sorting dates by a certain metric](#sorting-dates-by-a-certain-metric-sort) | `sort METRIC/ORDER` | `sort name/increasing` |
+| [Starring a date](#starring-a-date-star) | `star INDEX` | `star 1` |
+| [Unstarring a date](#unstarring-a-date-unstar) | `unstar INDEX` | `unstar 1` |
+
+[Scroll back to *Table of Contents*](#table-of-contents)
+
+---
diff --git a/docs/_config.yml b/docs/_config.yml
deleted file mode 100644
index 6bd245d8f4e..00000000000
--- a/docs/_config.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-title: "AB-3"
-theme: minima
-
-header_pages:
- - UserGuide.md
- - DeveloperGuide.md
- - AboutUs.md
-
-markdown: kramdown
-
-repository: "se-edu/addressbook-level3"
-github_icon: "images/github-icon.png"
-
-plugins:
- - jemoji
diff --git a/docs/_data/projects.yml b/docs/_data/projects.yml
deleted file mode 100644
index 8f3e50cb601..00000000000
--- a/docs/_data/projects.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-- name: "AB-1"
- url: https://se-edu.github.io/addressbook-level1
-
-- name: "AB-2"
- url: https://se-edu.github.io/addressbook-level2
-
-- name: "AB-3"
- url: https://se-edu.github.io/addressbook-level3
-
-- name: "AB-4"
- url: https://se-edu.github.io/addressbook-level4
-
-- name: "Duke"
- url: https://se-edu.github.io/duke
-
-- name: "Collate"
- url: https://se-edu.github.io/collate
-
-- name: "Book"
- url: https://se-edu.github.io/se-book
-
-- name: "Resources"
- url: https://se-edu.github.io/resources
diff --git a/docs/_includes/custom-head.html b/docs/_includes/custom-head.html
deleted file mode 100644
index 8559a67ffad..00000000000
--- a/docs/_includes/custom-head.html
+++ /dev/null
@@ -1,6 +0,0 @@
-{% comment %}
- Placeholder to allow defining custom head, in principle, you can add anything here, e.g. favicons:
-
- 1. Head over to https://realfavicongenerator.net/ to add your own favicons.
- 2. Customize default _includes/custom-head.html in your source directory and insert the given code snippet.
-{% endcomment %}
diff --git a/docs/_includes/head.html b/docs/_includes/head.html
deleted file mode 100644
index 83ac5326933..00000000000
--- a/docs/_includes/head.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
- {%- include custom-head.html -%}
-
- {{page.title}}
-
-
diff --git a/docs/_includes/header.html b/docs/_includes/header.html
deleted file mode 100644
index 33badcd4f99..00000000000
--- a/docs/_includes/header.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
+
-:information_source: Don’t forget to update `AddressBookParser` to use our new `RemarkCommandParser`!
+Don’t forget to update `LoveBookParser` to use our new `RemarkCommandParser`!
-
+
If you are stuck, check out the sample
-[here](https://github.com/se-edu/addressbook-level3/commit/dc6d5139d08f6403da0ec624ea32bd79a2ae0cbf#diff-8bf239e8e9529369b577701303ddd96af93178b4ed6735f91c2d8488b20c6b4a).
+[here](https://github.com/se-edu/LoveBook-level3/commit/dc6d5139d08f6403da0ec624ea32bd79a2ae0cbf#diff-8bf239e8e9529369b577701303ddd96af93178b4ed6735f91c2d8488b20c6b4a).
## Add `Remark` to the model
-Now that we have all the information that we need, let’s lay the groundwork for propagating the remarks added into the in-memory storage of person data. We achieve that by working with the `Person` model. Each field in a Person is implemented as a separate class (e.g. a `Name` object represents the person’s name). That means we should add a `Remark` class so that we can use a `Remark` object to represent a remark given to a person.
+Now that we have all the information that we need, let’s lay the groundwork for propagating the remarks added into the in-memory storage of date data. We achieve that by working with the `Person` model. Each field in a Person is implemented as a separate class (e.g. a `Name` object represents the date’s name). That means we should add a `Remark` class so that we can use a `Remark` object to represent a remark given to a date.
### Add a new `Remark` class
-Create a new `Remark` in `seedu.address.model.person`. Since a `Remark` is a field that is similar to `Address`, we can reuse a significant bit of code.
+Create a new `Remark` in `seedu.lovebook.model.date`. Since a `Remark` is a field that is similar to `Address`, we can reuse a significant bit of code.
-A copy-paste and search-replace later, you should have something like [this](https://github.com/se-edu/addressbook-level3/commit/4516e099699baa9e2d51801bd26f016d812dedcc#diff-41bb13c581e280c686198251ad6cc337cd5e27032772f06ed9bf7f1440995ece). Note how `Remark` has no constrains and thus does not require input
+A copy-paste and search-replace later, you should have something like [this](https://github.com/se-edu/LoveBook-level3/commit/4516e099699baa9e2d51801bd26f016d812dedcc#diff-41bb13c581e280c686198251ad6cc337cd5e27032772f06ed9bf7f1440995ece). Note how `Remark` has no constrains and thus does not require input
validation.
### Make use of `Remark`
@@ -238,13 +243,13 @@ Let’s change `RemarkCommand` and `RemarkCommandParser` to use the new `Remark`
## Add a placeholder element for remark to the UI
-Without getting too deep into `fxml`, let’s go on a 5 minute adventure to get some placeholder text to show up for each person.
+Without getting too deep into `fxml`, let’s go on a 5 minute adventure to get some placeholder text to show up for each date.
-Simply add the following to [`seedu.address.ui.PersonCard`](https://github.com/se-edu/addressbook-level3/commit/850b78879582f38accb05dd20c245963c65ea599#diff-639834f1e05afe2276a86372adf0fe5f69314642c2d93cfa543d614ce5a76688).
+Simply add the following to [`seedu.lovebook.ui.DateCard`](https://github.com/se-edu/LoveBook-level3/commit/850b78879582f38accb05dd20c245963c65ea599#diff-639834f1e05afe2276a86372adf0fe5f69314642c2d93cfa543d614ce5a76688).
-**`PersonCard.java`:**
+**`DateListCard.java`:**
-``` java
+```java
@FXML
private Label remark;
```
@@ -252,7 +257,7 @@ private Label remark;
`@FXML` is an annotation that marks a private or protected field and makes it accessible to FXML. It might sound like Greek to you right now, don’t worry — we will get back to it later.
-Then insert the following into [`main/resources/view/PersonListCard.fxml`](https://github.com/se-edu/addressbook-level3/commit/850b78879582f38accb05dd20c245963c65ea599#diff-d44c4f51c24f6253c277a2bb9bc440b8064d9c15ad7cb7ceda280bca032efce9).
+Then insert the following into [`main/resources/view/PersonListCard.fxml`](https://github.com/se-edu/LoveBook-level3/commit/850b78879582f38accb05dd20c245963c65ea599#diff-d44c4f51c24f6253c277a2bb9bc440b8064d9c15ad7cb7ceda280bca032efce9).
**`PersonListCard.fxml`:**
@@ -266,7 +271,7 @@ That’s it! Fire up the application again and you should see something like thi
## Modify `Person` to support a `Remark` field
-Since `PersonCard` displays data from a `Person`, we need to update `Person` to get our `Remark` displayed!
+Since `DateListCard` displays data from a `Person`, we need to update `Person` to get our `Remark` displayed!
### Modify `Person`
@@ -276,42 +281,42 @@ We change the constructor of `Person` to take a `Remark`. We will also need to d
Unfortunately, a change to `Person` will cause other commands to break, you will have to modify these commands to use the updated `Person`!
-
+
-:bulb: Use the `Find Usages` feature in IntelliJ IDEA on the `Person` class to find these commands.
+Use the `Find Usages` feature in IntelliJ IDEA on the `Person` class to find these commands.
-
+
-Refer to [this commit](https://github.com/se-edu/addressbook-level3/commit/ce998c37e65b92d35c91d28c7822cd139c2c0a5c) and check that you have got everything in order!
+Refer to [this commit](https://github.com/se-edu/LoveBook-level3/commit/ce998c37e65b92d35c91d28c7822cd139c2c0a5c) and check that you have got everything in order!
## Updating Storage
-AddressBook stores data by serializing `JsonAdaptedPerson` into `json` with the help of an external library — Jackson. Let’s update `JsonAdaptedPerson` to work with our new `Person`!
+LoveBook stores data by serializing `JsonAdaptedDate` into `json` with the help of an external library — Jackson. Let’s update `JsonAdaptedDate` to work with our new `Person`!
While the changes to code may be minimal, the test data will have to be updated as well.
-
+
-:exclamation: You must delete AddressBook’s storage file located at `/data/addressbook.json` before running it! Not doing so will cause AddressBook to default to an empty address book!
+You must delete LoveBook’s storage file located at `/data/LoveBook.json` before running it! Not doing so will cause LoveBook to default to an empty love book!
-
+
-Check out [this commit](https://github.com/se-edu/addressbook-level3/commit/556cbd0e03ff224d7a68afba171ad2eb0ce56bbf)
+Check out [this commit](https://github.com/se-edu/LoveBook-level3/commit/556cbd0e03ff224d7a68afba171ad2eb0ce56bbf)
to see what the changes entail.
## Finalizing the UI
Now that we have finalized the `Person` class and its dependencies, we can now bind the `Remark` field to the UI.
-Just add [this one line of code!](https://github.com/se-edu/addressbook-level3/commit/5b98fee11b6b3f5749b6b943c4f3bd3aa049b692)
+Just add [this one line of code!](https://github.com/se-edu/LoveBook-level3/commit/5b98fee11b6b3f5749b6b943c4f3bd3aa049b692)
-**`PersonCard.java`:**
+**`DateListCard.java`:**
-``` java
-public PersonCard(Person person, int displayedIndex) {
+```java
+public DateListCard(Person date, int displayedIndex) {
//...
- remark.setText(person.getRemark().value);
+ remark.setText(date.getRemark().value);
}
```
@@ -324,11 +329,11 @@ After the previous step, we notice a peculiar regression — we went from di
### Update `RemarkCommand` and `RemarkCommandParser`
In this last step, we modify `RemarkCommand#execute()` to change the `Remark` of a `Person`. Since all fields in a `Person` are immutable, we create a new instance of a `Person` with the values that we want and
-save it with `Model#setPerson()`.
+save it with `Model#setDate()`.
**`RemarkCommand.java`:**
-``` java
+```java
//...
public static final String MESSAGE_ADD_REMARK_SUCCESS = "Added remark to Person: %1$s";
public static final String MESSAGE_DELETE_REMARK_SUCCESS = "Removed remark from Person: %1$s";
@@ -341,25 +346,25 @@ save it with `Model#setPerson()`.
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
}
- Person personToEdit = lastShownList.get(index.getZeroBased());
- Person editedPerson = new Person(
- personToEdit.getName(), personToEdit.getPhone(), personToEdit.getEmail(),
- personToEdit.getAddress(), remark, personToEdit.getTags());
+ Person dateToEdit = lastShownList.get(index.getZeroBased());
+ Person editedDate = new Person(
+ dateToEdit.getName(), dateToEdit.getAge(), dateToEdit.getGender(),
+ dateToEdit.getHeight(), remark, dateToEdit.getTags());
- model.setPerson(personToEdit, editedPerson);
+ model.setDate(dateToEdit, editedDate);
model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
- return new CommandResult(generateSuccessMessage(editedPerson));
+ return new CommandResult(generateSuccessMessage(editedDate));
}
/**
* Generates a command execution success message based on whether
* the remark is added to or removed from
- * {@code personToEdit}.
+ * {@code dateToEdit}.
*/
- private String generateSuccessMessage(Person personToEdit) {
+ private String generateSuccessMessage(Person dateToEdit) {
String message = !remark.value.isEmpty() ? MESSAGE_ADD_REMARK_SUCCESS : MESSAGE_DELETE_REMARK_SUCCESS;
- return String.format(message, personToEdit);
+ return String.format(message, dateToEdit);
}
```
@@ -371,7 +376,7 @@ Tests are crucial to ensuring that bugs don’t slip into the codebase unnoticed
Let’s verify the correctness of our code by writing some tests!
-Of course you can simply add the test cases manually, like you've been doing all along this tutorial. The result would be like the test cases in [here](https://github.com/se-edu/addressbook-level3/commit/fac8f3fd855d55831ca0cc73313b5943d49d4d6e#diff-ff58f7c10338b34f76645df49b71ecb2bafaf7611b20e7ff59ebc98475538a01). Alternatively, you can get the help of IntelliJ to generate the skeletons of the test cases, as explained in the next section.
+Of course you can simply add the test cases manually, like you've been doing all along this tutorial. The result would be like the test cases in [here](https://github.com/se-edu/LoveBook-level3/commit/fac8f3fd855d55831ca0cc73313b5943d49d4d6e#diff-ff58f7c10338b34f76645df49b71ecb2bafaf7611b20e7ff59ebc98475538a01). Alternatively, you can get the help of IntelliJ to generate the skeletons of the test cases, as explained in the next section.
### Automatically generating tests
@@ -392,8 +397,8 @@ Following convention, let’s change the name of the generated method to `execut
Let’s use the utility functions provided in `CommandTestUtil`. The functions ensure that commands produce the expected `CommandResult` and output the correct message. In this case, `CommandTestUtil#assertCommandSuccess` is the best fit as we are testing that a `RemarkCommand` will successfully add a `Remark`.
-You should end up with a test that looks something like [this](https://github.com/se-edu/addressbook-level3/commit/fac8f3fd855d55831ca0cc73313b5943d49d4d6e#diff-ff58f7c10338b34f76645df49b71ecb2bafaf7611b20e7ff59ebc98475538a01R36-R49).
+You should end up with a test that looks something like [this](https://github.com/se-edu/LoveBook-level3/commit/fac8f3fd855d55831ca0cc73313b5943d49d4d6e#diff-ff58f7c10338b34f76645df49b71ecb2bafaf7611b20e7ff59ebc98475538a01R36-R49).
## Conclusion
-This concludes the tutorial for adding a new `Command` to AddressBook.
+This concludes the tutorial for adding a new `Command` to LoveBook.
diff --git a/docs/tutorials/RemovingFields.md b/docs/tutorials/RemovingFields.md
index f29169bc924..bd947c1222f 100644
--- a/docs/tutorials/RemovingFields.md
+++ b/docs/tutorials/RemovingFields.md
@@ -1,26 +1,29 @@
---
-layout: page
-title: "Tutorial: Removing Fields"
+ layout: default.md
+ title: "Tutorial: Removing Fields"
+ pageNav: 3
---
+# Tutorial: Removing Fields
+
> Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
>
> — Antoine de Saint-Exupery
When working on an existing code base, you will most likely find that some features that are no longer necessary.
-This tutorial aims to give you some practice on such a code 'removal' activity by removing the `address` field from `Person` class.
+This tutorial aims to give you some practice on such a code 'removal' activity by removing the `height` field from `Person` class.
-
+
-**If you have done the [Add `remark` command tutorial](AddRemark.html) already**, you should know where the code had to be updated to add the field `remark`. From that experience, you can deduce where the code needs to be changed to _remove_ that field too. The removing of the `address` field can be done similarly.
+**If you have done the [Add `remark` command tutorial](AddRemark.html) already**, you should know where the code had to be updated to add the field `remark`. From that experience, you can deduce where the code needs to be changed to _remove_ that field too. The removing of the `height` field can be done similarly.
However, if you have no such prior knowledge, removing a field can take a quite a bit of detective work. This tutorial takes you through that process. **At least have a read even if you don't actually do the steps yourself.**
-
+
-* Table of Contents
-{:toc}
+
+
## Safely deleting `Address`
@@ -28,7 +31,7 @@ IntelliJ IDEA provides a refactoring tool that can identify *most* parts of a re
### Assisted refactoring
-The `address` field in `Person` is actually an instance of the `seedu.address.model.person.Address` class. Since removing the `Address` class will break the application, we start by identifying `Address`'s usages. This allows us to see code that depends on `Address` to function properly and edit them on a case-by-case basis. Right-click the `Address` class and select `Refactor` \> `Safe Delete` through the menu.
+The `height` field in `Person` is actually an instance of the `seedu.lovebook.model.date.Address` class. Since removing the `Address` class will break the application, we start by identifying `Address`'s usages. This allows us to see code that depends on `Address` to function properly and edit them on a case-by-case basis. Right-click the `Address` class and select `Refactor` \> `Safe Delete` through the menu.
* :bulb: To make things simpler, you can unselect the options `Search in comments and strings` and `Search for text occurrences`
![Usages detected](../images/remove/UnsafeDelete.png)
@@ -41,19 +44,19 @@ Remove usages of `Address` by performing `Safe Delete`s on each entry i.e., doub
Let’s try removing references to `Address` in `EditPersonDescriptor`.
-1. Safe delete the field `address` in `EditPersonDescriptor`.
+1. Safe delete the field `height` in `EditPersonDescriptor`.
1. Select `Yes` when prompted to remove getters and setters.
1. Select `View Usages` again.
![UnsafeDeleteOnField](../images/remove/UnsafeDeleteOnField.png)
-1. Remove the usages of `address` and select `Do refactor` when you are done.
+1. Remove the usages of `height` and select `Do refactor` when you are done.
-
+
- :bulb: **Tip:** Removing usages may result in errors. Exercise discretion and fix them. For example, removing the `address` field from the `Person` class will require you to modify its constructor.
-
+ **Tip:** Removing usages may result in errors. Exercise discretion and fix them. For example, removing the `height` field from the `Person` class will require you to modify its constructor.
+
1. Repeat the steps for the remaining usages of `Address`
@@ -61,30 +64,30 @@ After you are done, verify that the application still works by compiling and run
### Manual refactoring
-Unfortunately, there are usages of `Address` that IntelliJ IDEA cannot identify. You can find them by searching for instances of the word `address` in your code (`Edit` \> `Find` \> `Find in path`).
+Unfortunately, there are usages of `Address` that IntelliJ IDEA cannot identify. You can find them by searching for instances of the word `height` in your code (`Edit` \> `Find` \> `Find in path`).
-Places of interest to look out for would be resources used by the application. `main/resources` contains images and `fxml` files used by the application and `test/resources` contains test data. For example, there is a `$address` in each `PersonCard` that has not been removed nor identified.
+Places of interest to look out for would be resources used by the application. `main/resources` contains images and `fxml` files used by the application and `test/resources` contains test data. For example, there is a `$height` in each `DateListCard` that has not been removed nor identified.
-![$address](../images/remove/$address.png)
+![$height](../images/remove/$height.png)
-A quick look at the `PersonCard` class and its `fxml` file quickly reveals why it slipped past the automated refactoring.
+A quick look at the `DateListCard` class and its `fxml` file quickly reveals why it slipped past the automated refactoring.
-**`PersonCard.java`**
+**`DateListCard.java`**
-``` java
+```java
...
@FXML
-private Label address;
+private Label height;
...
```
-**`PersonCard.fxml`**
+**`DateListCard.fxml`**
``` xml
...
-
-
-
+
+
+
...
```
@@ -94,19 +97,19 @@ After removing the `Label`, we can proceed to formally test our code. If everyth
At this point, your application is working as intended and all your tests are passing. What’s left to do is to clean up references to `Address` in test data and documentation.
-In `src/test/data/`, data meant for testing purposes are stored. While keeping the `address` field in the json files does not cause the tests to fail, it is not good practice to let cruft from old features accumulate.
+In `src/test/data/`, data meant for testing purposes are stored. While keeping the `height` field in the json files does not cause the tests to fail, it is not good practice to let cruft from old features accumulate.
-**`invalidPersonAddressBook.json`:**
+**`invalidPersonLoveBook.json`:**
```json
{
- "persons": [ {
+ "dates": [ {
"name": "Person with invalid name field: Ha!ns Mu@ster",
- "phone": "9482424",
- "email": "hans@example.com",
- "address": "4th street"
+ "age": "9482424",
+ "gender": "hans@example.com",
+ "height": "23245"
} ]
}
```
-You can go through each individual `json` file and manually remove the `address` field.
+You can go through each individual `json` file and manually remove the `height` field.
diff --git a/docs/tutorials/TracingCode.md b/docs/tutorials/TracingCode.md
index 4fb62a83ef6..d61ada9e6b9 100644
--- a/docs/tutorials/TracingCode.md
+++ b/docs/tutorials/TracingCode.md
@@ -1,26 +1,30 @@
---
-layout: page
-title: "Tutorial: Tracing code"
+ layout: default.md
+ title: "Tutorial: Tracing code"
+ pageNav: 3
---
+# Tutorial: Tracing code
+
+
> Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. …\[Therefore,\] making it easy to read makes it easier to write.
>
> — Robert C. Martin Clean Code: A Handbook of Agile Software Craftsmanship
When trying to understand an unfamiliar code base, one common strategy used is to trace some representative execution path through the code base. One easy way to trace an execution path is to use a debugger to step through the code. In this tutorial, you will be using the IntelliJ IDEA’s debugger to trace the execution path of a specific user command.
-* Table of Contents
-{:toc}
+
+
## Before we start
Before we jump into the code, it is useful to get an idea of the overall structure and the high-level behavior of the application. This is provided in the 'Architecture' section of the developer guide. In particular, the architecture diagram (reproduced below), tells us that the App consists of several components.
-![ArchitectureDiagram](../images/ArchitectureDiagram.png)
+
It also has a sequence diagram (reproduced below) that tells us how a command propagates through the App.
-
+
Note how the diagram shows only the execution flows _between_ the main components. That is, it does not show details of the execution path *inside* each component. By hiding those details, the diagram aims to inform the reader about the overall execution path of a command without overwhelming the reader with too much details. In this tutorial, you aim to find those omitted details so that you get a more in-depth understanding of how the code works.
@@ -37,18 +41,18 @@ As you know, the first step of debugging is to put in a breakpoint where you wan
In our case, we would want to begin the tracing at the very point where the App start processing user input (i.e., somewhere in the UI component), and then trace through how the execution proceeds through the UI component. However, the execution path through a GUI is often somewhat obscure due to various *event-driven mechanisms* used by GUI frameworks, which happens to be the case here too. Therefore, let us put the breakpoint where the `UI` transfers control to the `Logic` component.
-
+
-According to the sequence diagram you saw earlier (and repeated above for reference), the `UI` component yields control to the `Logic` component through a method named `execute`. Searching through the code base for an `execute()` method that belongs to the `Logic` component yields a promising candidate in `seedu.address.logic.Logic`.
+According to the sequence diagram you saw earlier (and repeated above for reference), the `UI` component yields control to the `Logic` component through a method named `execute`. Searching through the code base for an `execute()` method that belongs to the `Logic` component yields a promising candidate in `seedu.lovebook.logic.Logic`.
-
+
-:bulb: **Intellij Tip:** The ['**Search Everywhere**' feature](https://www.jetbrains.com/help/idea/searching-everywhere.html) can be used here. In particular, the '**Find Symbol**' ('Symbol' here refers to methods, variables, classes etc.) variant of that feature is quite useful here as we are looking for a _method_ named `execute`, not simply the text `execute`.
-
+**Intellij Tip:** The ['**Search Everywhere**' feature](https://www.jetbrains.com/help/idea/searching-everywhere.html) can be used here. In particular, the '**Find Symbol**' ('Symbol' here refers to methods, variables, classes etc.) variant of that feature is quite useful here as we are looking for a _method_ named `execute`, not simply the text `execute`.
+
-A quick look at the `seedu.address.logic.Logic` (an extract given below) confirms that this indeed might be what we’re looking for.
+A quick look at the `seedu.lovebook.logic.Logic` (an extract given below) confirms that this indeed might be what we’re looking for.
```java
public interface Logic {
@@ -67,14 +71,14 @@ public interface Logic {
But apparently, this is an interface, not a concrete implementation.
That should be fine because the [Architecture section of the Developer Guide](../DeveloperGuide.html#architecture) tells us that components interact through interfaces. Here's the relevant diagram:
-
+
Next, let's find out which statement(s) in the `UI` code is calling this method, thus transferring control from the `UI` to the `Logic`.
-
+
-:bulb: **Intellij Tip:** The ['**Find Usages**' feature](https://www.jetbrains.com/help/idea/find-highlight-usages.html#find-usages) can find from which parts of the code a class/method/variable is being used.
-
+**Intellij Tip:** The ['**Find Usages**' feature](https://www.jetbrains.com/help/idea/find-highlight-usages.html#find-usages) can find from which parts of the code a class/method/variable is being used.
+
![`Find Usages` tool window. `Edit` \> `Find` \> `Find Usages`.](../images/tracing/FindUsages.png)
@@ -85,12 +89,12 @@ Now let’s set the breakpoint. First, double-click the item to reach the corres
## Tracing the execution path
-Recall from the User Guide that the `edit` command has the format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]…` For this tutorial we will be issuing the command `edit 1 n/Alice Yeoh`.
+Recall from the User Guide that the `edit` command has the format: `edit INDEX [n/NAME] [age/AGE] [g/GENDER] [a/HEIGHT] [t/TAG]…` For this tutorial we will be issuing the command `edit 1 n/Alice Yeoh`.
-
+
-:bulb: **Tip:** Over the course of the debugging session, you will encounter every major component in the application. Try to keep track of what happens inside the component and where the execution transfers to another component.
-
+**Tip:** Over the course of the debugging session, you will encounter every major component in the application. Try to keep track of what happens inside the component and where the execution transfers to another component.
+
1. To start the debugging session, simply `Run` \> `Debug Main`
@@ -110,7 +114,7 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [
**LogicManager\#execute().**
- ``` java
+ ```java
@Override
public CommandResult execute(String commandText)
throws CommandException, ParseException {
@@ -120,14 +124,14 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [
CommandResult commandResult;
//Parse user input from String to a Command
- Command command = addressBookParser.parseCommand(commandText);
+ Command command = LoveBookParser.parseCommand(commandText);
//Executes the Command and stores the result
commandResult = command.execute(model);
try {
//We can deduce that the previous line of code modifies model in some way
// since it's being stored here.
- storage.saveAddressBook(model.getAddressBook());
+ storage.saveLoveBook(model.getLoveBook());
} catch (IOException ioe) {
throw new CommandException(FILE_OPS_ERROR_MESSAGE + ioe, ioe);
}
@@ -141,8 +145,8 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [
1. _Step over_ the logging code since it is of no interest to us now.
![StepOver](../images/tracing/StepOver.png)
-1. _Step into_ the line where user input in parsed from a String to a Command, which should bring you to the `AddressBookParser#parseCommand()` method (partial code given below):
- ``` java
+1. _Step into_ the line where user input in parsed from a String to a Command, which should bring you to the `LoveBookParser#parseCommand()` method (partial code given below):
+ ```java
public Command parseCommand(String userInput) throws ParseException {
...
final String commandWord = matcher.group("commandWord");
@@ -157,7 +161,7 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [
1. Stepping through the `switch` block, we end up at a call to `EditCommandParser().parse()` as expected (because the command we typed is an edit command).
- ``` java
+ ```java
...
case EditCommand.COMMAND_WORD:
return new EditCommandParser().parse(arguments);
@@ -166,8 +170,10 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [
1. Let’s see what `EditCommandParser#parse()` does by stepping into it. You might have to click the 'step into' button multiple times here because there are two method calls in that statement: `EditCommandParser()` and `parse()`.
-
:bulb: **Intellij Tip:** Sometimes, you might end up stepping into functions that are not of interest. Simply use the `step out` button to get out of them!
-
+
+
+ **Intellij Tip:** Sometimes, you might end up stepping into functions that are not of interest. Simply use the `step out` button to get out of them!
+
1. Stepping through the method shows that it calls `ArgumentTokenizer#tokenize()` and `ParserUtil#parseIndex()` to obtain the arguments and index required.
@@ -175,75 +181,79 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [
![EditCommand](../images/tracing/EditCommand.png)
1. As you just traced through some code involved in parsing a command, you can take a look at this class diagram to see where the various parsing-related classes you encountered fit into the design of the `Logic` component.
-
+
1. Let’s continue stepping through until we return to `LogicManager#execute()`.
The sequence diagram below shows the details of the execution path through the Logic component. Does the execution path you traced in the code so far match the diagram?
- ![Tracing an `edit` command through the Logic component](../images/tracing/LogicSequenceDiagram.png)
+
1. Now, step over until you read the statement that calls the `execute()` method of the `EditCommand` object received, and step into that `execute()` method (partial code given below):
**`EditCommand#execute()`:**
- ``` java
+ ```java
@Override
public CommandResult execute(Model model) throws CommandException {
...
- Person personToEdit = lastShownList.get(index.getZeroBased());
- Person editedPerson = createEditedPerson(personToEdit, editPersonDescriptor);
- if (!personToEdit.isSamePerson(editedPerson) && model.hasPerson(editedPerson)) {
+ Person dateToEdit = lastShownList.get(index.getZeroBased());
+ Person editedDate = createEditedPerson(dateToEdit, editPersonDescriptor);
+ if (!dateToEdit.isSamePerson(editedDate) && model.hasDate(editedDate)) {
throw new CommandException(MESSAGE_DUPLICATE_PERSON);
}
- model.setPerson(personToEdit, editedPerson);
+ model.setDate(dateToEdit, editedDate);
model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
- return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, editedPerson));
+ return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, editedDate));
}
```
1. As suspected, `command#execute()` does indeed make changes to the `model` object. Specifically,
- * it uses the `setPerson()` method (defined in the interface `Model` and implemented in `ModelManager` as per the usual pattern) to update the person data.
- * it uses the `updateFilteredPersonList` method to ask the `Model` to populate the 'filtered list' with _all_ persons.
- FYI, The 'filtered list' is the list of persons resulting from the most recent operation that will be shown to the user immediately after. For the `edit` command, we populate it with all the persons so that the user can see the edited person along with all other persons. If this was a `find` command, we would be setting that list to contain the search results instead.
- To provide some context, given below is the class diagram of the `Model` component. See if you can figure out where the 'filtered list' of persons is being tracked.
-
+ * it uses the `setDate()` method (defined in the interface `Model` and implemented in `ModelManager` as per the usual pattern) to update the date data.
+ * it uses the `updateFilteredPersonList` method to ask the `Model` to populate the 'filtered list' with _all_ dates.
+ FYI, The 'filtered list' is the list of dates resulting from the most recent operation that will be shown to the user immediately after. For the `edit` command, we populate it with all the dates so that the user can see the edited date along with all other dates. If this was a `find` command, we would be setting that list to contain the search results instead.
+ To provide some context, given below is the class diagram of the `Model` component. See if you can figure out where the 'filtered list' of dates is being tracked.
+
* :bulb: This may be a good time to read through the [`Model` component section of the DG](../DeveloperGuide.html#model-component)
1. As you step through the rest of the statements in the `EditCommand#execute()` method, you'll see that it creates a `CommandResult` object (containing information about the result of the execution) and returns it.
Advancing the debugger by one more step should take you back to the middle of the `LogicManager#execute()` method.
1. Given that you have already seen quite a few classes in the `Logic` component in action, see if you can identify in this partial class diagram some of the classes you've encountered so far, and see how they fit into the class structure of the `Logic` component:
-
+
+
* :bulb: This may be a good time to read through the [`Logic` component section of the DG](../DeveloperGuide.html#logic-component)
1. Similar to before, you can step over/into statements in the `LogicManager#execute()` method to examine how the control is transferred to the `Storage` component and what happens inside that component.
-
:bulb: **Intellij Tip:** When trying to step into a statement such as `storage.saveAddressBook(model.getAddressBook())` which contains multiple method calls, Intellij will let you choose (by clicking) which one you want to step into.
-
+
+
+ **Intellij Tip:** When trying to step into a statement such as `storage.saveLoveBook(model.getLoveBook())` which contains multiple method calls, Intellij will let you choose (by clicking) which one you want to step into.
+
-1. As you step through the code inside the `Storage` component, you will eventually arrive at the `JsonAddressBook#saveAddressBook()` method which calls the `JsonSerializableAddressBook` constructor, to create an object that can be _serialized_ (i.e., stored in storage medium) in JSON format. That constructor is given below (with added line breaks for easier readability):
+1. As you step through the code inside the `Storage` component, you will eventually arrive at the `JsonLoveBook#saveLoveBook()` method which calls the `JsonSerializableLoveBook` constructor, to create an object that can be _serialized_ (i.e., stored in storage medium) in JSON format. That constructor is given below (with added line breaks for easier readability):
- **`JsonSerializableAddressBook` constructor:**
- ``` java
+ **`JsonSerializableLoveBook` constructor:**
+ ```java
/**
- * Converts a given {@code ReadOnlyAddressBook} into this class for Jackson use.
+ * Converts a given {@code ReadOnlyLoveBook} into this class for Jackson use.
*
* @param source future changes to this will not affect the created
- * {@code JsonSerializableAddressBook}.
+ * {@code JsonSerializableLoveBook}.
*/
- public JsonSerializableAddressBook(ReadOnlyAddressBook source) {
- persons.addAll(
+ public JsonSerializableLoveBook(ReadOnlyLoveBook source) {
+ dates.addAll(
source.getPersonList()
.stream()
- .map(JsonAdaptedPerson::new)
+ .map(JsonAdaptedDate::new)
.collect(Collectors.toList()));
}
```
-1. It appears that a `JsonAdaptedPerson` is created for each `Person` and then added to the `JsonSerializableAddressBook`.
+1. It appears that a `JsonAdaptedDate` is created for each `Person` and then added to the `JsonSerializableLoveBook`.
This is because regular Java objects need to go through an _adaptation_ for them to be suitable to be saved in JSON format.
1. While you are stepping through the classes in the `Storage` component, here is the component's class diagram to help you understand how those classes fit into the structure of the component.
-
+
+
* :bulb: This may be a good time to read through the [`Storage` component section of the DG](../DeveloperGuide.html#storage-component)
1. We can continue to step through until you reach the end of the `LogicManager#execute()` method and return to the `MainWindow#executeCommand()` method (the place where we put the original breakpoint).
@@ -251,7 +261,7 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [
1. Stepping into `resultDisplay.setFeedbackToUser(commandResult.getFeedbackToUser());`, we end up in:
**`ResultDisplay#setFeedbackToUser()`**
- ``` java
+ ```java
public void setFeedbackToUser(String feedbackToUser) {
requireNonNull(feedbackToUser);
resultDisplay.setText(feedbackToUser);
@@ -292,10 +302,10 @@ Here are some quick questions you can try to answer based on your execution path
2. Allow `delete` to remove more than one index at a time
- 3. Save the address book in the CSV format instead
+ 3. Save the love book in the CSV format instead
4. Add a new command
5. Add a new field to `Person`
- 6. Add a new entity to the address book
+ 6. Add a new entity to the love book
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index e708b1c023e..41d9927a4d4 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/src/main/java/seedu/address/logic/Messages.java b/src/main/java/seedu/address/logic/Messages.java
deleted file mode 100644
index ecd32c31b53..00000000000
--- a/src/main/java/seedu/address/logic/Messages.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package seedu.address.logic;
-
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import seedu.address.logic.parser.Prefix;
-import seedu.address.model.person.Person;
-
-/**
- * Container for user visible messages.
- */
-public class Messages {
-
- public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command";
- public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s";
- public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid";
- public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!";
- public static final String MESSAGE_DUPLICATE_FIELDS =
- "Multiple values specified for the following single-valued field(s): ";
-
- /**
- * Returns an error message indicating the duplicate prefixes.
- */
- public static String getErrorMessageForDuplicatePrefixes(Prefix... duplicatePrefixes) {
- assert duplicatePrefixes.length > 0;
-
- Set duplicateFields =
- Stream.of(duplicatePrefixes).map(Prefix::toString).collect(Collectors.toSet());
-
- return MESSAGE_DUPLICATE_FIELDS + String.join(" ", duplicateFields);
- }
-
- /**
- * Formats the {@code person} for display to the user.
- */
- public static String format(Person person) {
- final StringBuilder builder = new StringBuilder();
- builder.append(person.getName())
- .append("; Phone: ")
- .append(person.getPhone())
- .append("; Email: ")
- .append(person.getEmail())
- .append("; Address: ")
- .append(person.getAddress())
- .append("; Tags: ");
- person.getTags().forEach(builder::append);
- return builder.toString();
- }
-
-}
diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java
deleted file mode 100644
index 5d7185a9680..00000000000
--- a/src/main/java/seedu/address/logic/commands/AddCommand.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package seedu.address.logic.commands;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-
-import seedu.address.commons.util.ToStringBuilder;
-import seedu.address.logic.Messages;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.model.Model;
-import seedu.address.model.person.Person;
-
-/**
- * Adds a person to the address book.
- */
-public class AddCommand extends Command {
-
- public static final String COMMAND_WORD = "add";
-
- public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the address book. "
- + "Parameters: "
- + PREFIX_NAME + "NAME "
- + PREFIX_PHONE + "PHONE "
- + PREFIX_EMAIL + "EMAIL "
- + PREFIX_ADDRESS + "ADDRESS "
- + "[" + PREFIX_TAG + "TAG]...\n"
- + "Example: " + COMMAND_WORD + " "
- + PREFIX_NAME + "John Doe "
- + PREFIX_PHONE + "98765432 "
- + PREFIX_EMAIL + "johnd@example.com "
- + PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25 "
- + PREFIX_TAG + "friends "
- + PREFIX_TAG + "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";
-
- private final Person toAdd;
-
- /**
- * Creates an AddCommand to add the specified {@code Person}
- */
- public AddCommand(Person person) {
- requireNonNull(person);
- toAdd = person;
- }
-
- @Override
- public CommandResult execute(Model model) throws CommandException {
- requireNonNull(model);
-
- if (model.hasPerson(toAdd)) {
- throw new CommandException(MESSAGE_DUPLICATE_PERSON);
- }
-
- model.addPerson(toAdd);
- return new CommandResult(String.format(MESSAGE_SUCCESS, Messages.format(toAdd)));
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof AddCommand)) {
- return false;
- }
-
- AddCommand otherAddCommand = (AddCommand) other;
- return toAdd.equals(otherAddCommand.toAdd);
- }
-
- @Override
- public String toString() {
- return new ToStringBuilder(this)
- .add("toAdd", toAdd)
- .toString();
- }
-}
diff --git a/src/main/java/seedu/address/logic/commands/EditCommand.java b/src/main/java/seedu/address/logic/commands/EditCommand.java
deleted file mode 100644
index 4b581c7331e..00000000000
--- a/src/main/java/seedu/address/logic/commands/EditCommand.java
+++ /dev/null
@@ -1,242 +0,0 @@
-package seedu.address.logic.commands;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-
-import seedu.address.commons.core.index.Index;
-import seedu.address.commons.util.CollectionUtil;
-import seedu.address.commons.util.ToStringBuilder;
-import seedu.address.logic.Messages;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.model.Model;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-
-/**
- * Edits the details of an existing person in the address book.
- */
-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 person identified "
- + "by the index number used in the displayed person 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_ADDRESS + "ADDRESS] "
- + "[" + PREFIX_TAG + "TAG]...\n"
- + "Example: " + COMMAND_WORD + " 1 "
- + PREFIX_PHONE + "91234567 "
- + PREFIX_EMAIL + "johndoe@example.com";
-
- public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Person: %1$s";
- public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided.";
- public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book.";
-
- private final Index index;
- private final EditPersonDescriptor editPersonDescriptor;
-
- /**
- * @param index of the person in the filtered person list to edit
- * @param editPersonDescriptor details to edit the person with
- */
- public EditCommand(Index index, EditPersonDescriptor editPersonDescriptor) {
- requireNonNull(index);
- requireNonNull(editPersonDescriptor);
-
- this.index = index;
- this.editPersonDescriptor = new EditPersonDescriptor(editPersonDescriptor);
- }
-
- @Override
- public CommandResult execute(Model model) throws CommandException {
- requireNonNull(model);
- List lastShownList = model.getFilteredPersonList();
-
- if (index.getZeroBased() >= lastShownList.size()) {
- throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
- }
-
- Person personToEdit = lastShownList.get(index.getZeroBased());
- Person editedPerson = createEditedPerson(personToEdit, editPersonDescriptor);
-
- if (!personToEdit.isSamePerson(editedPerson) && model.hasPerson(editedPerson)) {
- throw new CommandException(MESSAGE_DUPLICATE_PERSON);
- }
-
- model.setPerson(personToEdit, editedPerson);
- model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
- return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson)));
- }
-
- /**
- * Creates and returns a {@code Person} with the details of {@code personToEdit}
- * edited with {@code editPersonDescriptor}.
- */
- private static Person createEditedPerson(Person personToEdit, EditPersonDescriptor editPersonDescriptor) {
- assert personToEdit != null;
-
- Name updatedName = editPersonDescriptor.getName().orElse(personToEdit.getName());
- Phone updatedPhone = editPersonDescriptor.getPhone().orElse(personToEdit.getPhone());
- Email updatedEmail = editPersonDescriptor.getEmail().orElse(personToEdit.getEmail());
- Address updatedAddress = editPersonDescriptor.getAddress().orElse(personToEdit.getAddress());
- Set updatedTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags());
-
- return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags);
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof EditCommand)) {
- return false;
- }
-
- EditCommand otherEditCommand = (EditCommand) other;
- return index.equals(otherEditCommand.index)
- && editPersonDescriptor.equals(otherEditCommand.editPersonDescriptor);
- }
-
- @Override
- public String toString() {
- return new ToStringBuilder(this)
- .add("index", index)
- .add("editPersonDescriptor", editPersonDescriptor)
- .toString();
- }
-
- /**
- * Stores the details to edit the person with. Each non-empty field value will replace the
- * corresponding field value of the person.
- */
- public static class EditPersonDescriptor {
- private Name name;
- private Phone phone;
- private Email email;
- private Address address;
- private Set tags;
-
- public EditPersonDescriptor() {}
-
- /**
- * Copy constructor.
- * A defensive copy of {@code tags} is used internally.
- */
- public EditPersonDescriptor(EditPersonDescriptor toCopy) {
- setName(toCopy.name);
- setPhone(toCopy.phone);
- setEmail(toCopy.email);
- setAddress(toCopy.address);
- setTags(toCopy.tags);
- }
-
- /**
- * Returns true if at least one field is edited.
- */
- public boolean isAnyFieldEdited() {
- return CollectionUtil.isAnyNonNull(name, phone, email, address, tags);
- }
-
- public void setName(Name name) {
- this.name = name;
- }
-
- public Optional getName() {
- return Optional.ofNullable(name);
- }
-
- public void setPhone(Phone phone) {
- this.phone = phone;
- }
-
- public Optional getPhone() {
- return Optional.ofNullable(phone);
- }
-
- public void setEmail(Email email) {
- this.email = email;
- }
-
- public Optional getEmail() {
- return Optional.ofNullable(email);
- }
-
- public void setAddress(Address address) {
- this.address = address;
- }
-
- public Optional getAddress() {
- return Optional.ofNullable(address);
- }
-
- /**
- * Sets {@code tags} to this object's {@code tags}.
- * A defensive copy of {@code tags} is used internally.
- */
- public void setTags(Set tags) {
- this.tags = (tags != null) ? new HashSet<>(tags) : null;
- }
-
- /**
- * Returns an unmodifiable tag set, which throws {@code UnsupportedOperationException}
- * if modification is attempted.
- * Returns {@code Optional#empty()} if {@code tags} is null.
- */
- public Optional> getTags() {
- return (tags != null) ? Optional.of(Collections.unmodifiableSet(tags)) : Optional.empty();
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof EditPersonDescriptor)) {
- return false;
- }
-
- EditPersonDescriptor otherEditPersonDescriptor = (EditPersonDescriptor) other;
- return Objects.equals(name, otherEditPersonDescriptor.name)
- && Objects.equals(phone, otherEditPersonDescriptor.phone)
- && Objects.equals(email, otherEditPersonDescriptor.email)
- && Objects.equals(address, otherEditPersonDescriptor.address)
- && Objects.equals(tags, otherEditPersonDescriptor.tags);
- }
-
- @Override
- public String toString() {
- return new ToStringBuilder(this)
- .add("name", name)
- .add("phone", phone)
- .add("email", email)
- .add("address", address)
- .add("tags", tags)
- .toString();
- }
- }
-}
diff --git a/src/main/java/seedu/address/logic/commands/ListCommand.java b/src/main/java/seedu/address/logic/commands/ListCommand.java
deleted file mode 100644
index 84be6ad2596..00000000000
--- a/src/main/java/seedu/address/logic/commands/ListCommand.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package seedu.address.logic.commands;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS;
-
-import seedu.address.model.Model;
-
-/**
- * Lists all persons in the address book to the user.
- */
-public class ListCommand extends Command {
-
- public static final String COMMAND_WORD = "list";
-
- public static final String MESSAGE_SUCCESS = "Listed all persons";
-
-
- @Override
- public CommandResult execute(Model model) {
- requireNonNull(model);
- model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
- return new CommandResult(MESSAGE_SUCCESS);
- }
-}
diff --git a/src/main/java/seedu/address/logic/parser/AddCommandParser.java b/src/main/java/seedu/address/logic/parser/AddCommandParser.java
deleted file mode 100644
index 4ff1a97ed77..00000000000
--- a/src/main/java/seedu/address/logic/parser/AddCommandParser.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package seedu.address.logic.parser;
-
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-
-import java.util.Set;
-import java.util.stream.Stream;
-
-import seedu.address.logic.commands.AddCommand;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-
-/**
- * Parses input arguments and creates a new AddCommand object
- */
-public class AddCommandParser implements Parser {
-
- /**
- * Parses the given {@code String} of arguments in the context of the AddCommand
- * and returns an AddCommand object for execution.
- * @throws ParseException if the user input does not conform the expected format
- */
- public AddCommand parse(String args) throws ParseException {
- ArgumentMultimap argMultimap =
- ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG);
-
- if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL)
- || !argMultimap.getPreamble().isEmpty()) {
- throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
- }
-
- argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS);
- Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get());
- Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get());
- Email email = ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get());
- Address address = ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get());
- Set tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG));
-
- Person person = new Person(name, phone, email, address, tagList);
-
- return new AddCommand(person);
- }
-
- /**
- * Returns true if none of the prefixes contains empty {@code Optional} values in the given
- * {@code ArgumentMultimap}.
- */
- private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
- return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
- }
-
-}
diff --git a/src/main/java/seedu/address/logic/parser/CliSyntax.java b/src/main/java/seedu/address/logic/parser/CliSyntax.java
deleted file mode 100644
index 75b1a9bf119..00000000000
--- a/src/main/java/seedu/address/logic/parser/CliSyntax.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package seedu.address.logic.parser;
-
-/**
- * Contains Command Line Interface (CLI) syntax definitions common to multiple commands
- */
-public class CliSyntax {
-
- /* Prefix definitions */
- public static final Prefix PREFIX_NAME = new Prefix("n/");
- public static final Prefix PREFIX_PHONE = new Prefix("p/");
- public static final Prefix PREFIX_EMAIL = new Prefix("e/");
- public static final Prefix PREFIX_ADDRESS = new Prefix("a/");
- public static final Prefix PREFIX_TAG = new Prefix("t/");
-
-}
diff --git a/src/main/java/seedu/address/logic/parser/EditCommandParser.java b/src/main/java/seedu/address/logic/parser/EditCommandParser.java
deleted file mode 100644
index 46b3309a78b..00000000000
--- a/src/main/java/seedu/address/logic/parser/EditCommandParser.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package seedu.address.logic.parser;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Optional;
-import java.util.Set;
-
-import seedu.address.commons.core.index.Index;
-import seedu.address.logic.commands.EditCommand;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.tag.Tag;
-
-/**
- * Parses input arguments and creates a new EditCommand object
- */
-public class EditCommandParser implements Parser {
-
- /**
- * Parses the given {@code String} of arguments in the context of the EditCommand
- * and returns an EditCommand object for execution.
- * @throws ParseException if the user input does not conform the expected format
- */
- public EditCommand parse(String args) throws ParseException {
- requireNonNull(args);
- ArgumentMultimap argMultimap =
- ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG);
-
- Index index;
-
- try {
- index = ParserUtil.parseIndex(argMultimap.getPreamble());
- } catch (ParseException pe) {
- throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE), pe);
- }
-
- argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS);
-
- EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor();
-
- if (argMultimap.getValue(PREFIX_NAME).isPresent()) {
- editPersonDescriptor.setName(ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get()));
- }
- if (argMultimap.getValue(PREFIX_PHONE).isPresent()) {
- editPersonDescriptor.setPhone(ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get()));
- }
- if (argMultimap.getValue(PREFIX_EMAIL).isPresent()) {
- editPersonDescriptor.setEmail(ParserUtil.parseEmail(argMultimap.getValue(PREFIX_EMAIL).get()));
- }
- if (argMultimap.getValue(PREFIX_ADDRESS).isPresent()) {
- editPersonDescriptor.setAddress(ParserUtil.parseAddress(argMultimap.getValue(PREFIX_ADDRESS).get()));
- }
- parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags);
-
- if (!editPersonDescriptor.isAnyFieldEdited()) {
- throw new ParseException(EditCommand.MESSAGE_NOT_EDITED);
- }
-
- return new EditCommand(index, editPersonDescriptor);
- }
-
- /**
- * Parses {@code Collection tags} into a {@code Set} if {@code tags} is non-empty.
- * If {@code tags} contain only one element which is an empty string, it will be parsed into a
- * {@code Set} containing zero tags.
- */
- private Optional> parseTagsForEdit(Collection tags) throws ParseException {
- assert tags != null;
-
- if (tags.isEmpty()) {
- return Optional.empty();
- }
- Collection tagSet = tags.size() == 1 && tags.contains("") ? Collections.emptySet() : tags;
- return Optional.of(ParserUtil.parseTags(tagSet));
- }
-
-}
diff --git a/src/main/java/seedu/address/logic/parser/ParserUtil.java b/src/main/java/seedu/address/logic/parser/ParserUtil.java
deleted file mode 100644
index b117acb9c55..00000000000
--- a/src/main/java/seedu/address/logic/parser/ParserUtil.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package seedu.address.logic.parser;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import seedu.address.commons.core.index.Index;
-import seedu.address.commons.util.StringUtil;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-
-/**
- * Contains utility methods used for parsing strings in the various *Parser classes.
- */
-public class ParserUtil {
-
- public static final String MESSAGE_INVALID_INDEX = "Index is not a non-zero unsigned integer.";
-
- /**
- * Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing whitespaces will be
- * trimmed.
- * @throws ParseException if the specified index is invalid (not non-zero unsigned integer).
- */
- public static Index parseIndex(String oneBasedIndex) throws ParseException {
- String trimmedIndex = oneBasedIndex.trim();
- if (!StringUtil.isNonZeroUnsignedInteger(trimmedIndex)) {
- throw new ParseException(MESSAGE_INVALID_INDEX);
- }
- return Index.fromOneBased(Integer.parseInt(trimmedIndex));
- }
-
- /**
- * Parses a {@code String name} into a {@code Name}.
- * Leading and trailing whitespaces will be trimmed.
- *
- * @throws ParseException if the given {@code name} is invalid.
- */
- public static Name parseName(String name) throws ParseException {
- requireNonNull(name);
- String trimmedName = name.trim();
- if (!Name.isValidName(trimmedName)) {
- throw new ParseException(Name.MESSAGE_CONSTRAINTS);
- }
- return new Name(trimmedName);
- }
-
- /**
- * Parses a {@code String phone} into a {@code Phone}.
- * Leading and trailing whitespaces will be trimmed.
- *
- * @throws ParseException if the given {@code phone} is invalid.
- */
- public static Phone parsePhone(String phone) throws ParseException {
- requireNonNull(phone);
- String trimmedPhone = phone.trim();
- if (!Phone.isValidPhone(trimmedPhone)) {
- throw new ParseException(Phone.MESSAGE_CONSTRAINTS);
- }
- return new Phone(trimmedPhone);
- }
-
- /**
- * Parses a {@code String address} into an {@code Address}.
- * Leading and trailing whitespaces will be trimmed.
- *
- * @throws ParseException if the given {@code address} is invalid.
- */
- public static Address parseAddress(String address) throws ParseException {
- requireNonNull(address);
- String trimmedAddress = address.trim();
- if (!Address.isValidAddress(trimmedAddress)) {
- throw new ParseException(Address.MESSAGE_CONSTRAINTS);
- }
- return new Address(trimmedAddress);
- }
-
- /**
- * Parses a {@code String email} into an {@code Email}.
- * Leading and trailing whitespaces will be trimmed.
- *
- * @throws ParseException if the given {@code email} is invalid.
- */
- public static Email parseEmail(String email) throws ParseException {
- requireNonNull(email);
- String trimmedEmail = email.trim();
- if (!Email.isValidEmail(trimmedEmail)) {
- throw new ParseException(Email.MESSAGE_CONSTRAINTS);
- }
- return new Email(trimmedEmail);
- }
-
- /**
- * Parses a {@code String tag} into a {@code Tag}.
- * Leading and trailing whitespaces will be trimmed.
- *
- * @throws ParseException if the given {@code tag} is invalid.
- */
- public static Tag parseTag(String tag) throws ParseException {
- requireNonNull(tag);
- String trimmedTag = tag.trim();
- if (!Tag.isValidTagName(trimmedTag)) {
- throw new ParseException(Tag.MESSAGE_CONSTRAINTS);
- }
- return new Tag(trimmedTag);
- }
-
- /**
- * Parses {@code Collection tags} into a {@code Set}.
- */
- public static Set parseTags(Collection tags) throws ParseException {
- requireNonNull(tags);
- final Set tagSet = new HashSet<>();
- for (String tagName : tags) {
- tagSet.add(parseTag(tagName));
- }
- return tagSet;
- }
-}
diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java
deleted file mode 100644
index 73397161e84..00000000000
--- a/src/main/java/seedu/address/model/AddressBook.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package seedu.address.model;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.List;
-
-import javafx.collections.ObservableList;
-import seedu.address.commons.util.ToStringBuilder;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.UniquePersonList;
-
-/**
- * Wraps all data at the address-book level
- * Duplicates are not allowed (by .isSamePerson comparison)
- */
-public class AddressBook implements ReadOnlyAddressBook {
-
- private final UniquePersonList persons;
-
- /*
- * The 'unusual' code block below is a non-static initialization block, sometimes used to avoid duplication
- * between constructors. See https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
- *
- * Note that non-static init blocks are not recommended to use. There are other ways to avoid duplication
- * among constructors.
- */
- {
- persons = new UniquePersonList();
- }
-
- public AddressBook() {}
-
- /**
- * Creates an AddressBook using the Persons in the {@code toBeCopied}
- */
- public AddressBook(ReadOnlyAddressBook toBeCopied) {
- this();
- resetData(toBeCopied);
- }
-
- //// list overwrite operations
-
- /**
- * Replaces the contents of the person list with {@code persons}.
- * {@code persons} must not contain duplicate persons.
- */
- public void setPersons(List persons) {
- this.persons.setPersons(persons);
- }
-
- /**
- * Resets the existing data of this {@code AddressBook} with {@code newData}.
- */
- public void resetData(ReadOnlyAddressBook newData) {
- requireNonNull(newData);
-
- setPersons(newData.getPersonList());
- }
-
- //// person-level operations
-
- /**
- * Returns true if a person with the same identity as {@code person} exists in the address book.
- */
- public boolean hasPerson(Person person) {
- requireNonNull(person);
- return persons.contains(person);
- }
-
- /**
- * Adds a person to the address book.
- * The person must not already exist in the address book.
- */
- public void addPerson(Person p) {
- persons.add(p);
- }
-
- /**
- * Replaces the given person {@code target} in the list with {@code editedPerson}.
- * {@code target} must exist in the address book.
- * The person identity of {@code editedPerson} must not be the same as another existing person in the address book.
- */
- public void setPerson(Person target, Person editedPerson) {
- requireNonNull(editedPerson);
-
- persons.setPerson(target, editedPerson);
- }
-
- /**
- * Removes {@code key} from this {@code AddressBook}.
- * {@code key} must exist in the address book.
- */
- public void removePerson(Person key) {
- persons.remove(key);
- }
-
- //// util methods
-
- @Override
- public String toString() {
- return new ToStringBuilder(this)
- .add("persons", persons)
- .toString();
- }
-
- @Override
- public ObservableList getPersonList() {
- return persons.asUnmodifiableObservableList();
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof AddressBook)) {
- return false;
- }
-
- AddressBook otherAddressBook = (AddressBook) other;
- return persons.equals(otherAddressBook.persons);
- }
-
- @Override
- public int hashCode() {
- return persons.hashCode();
- }
-}
diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java
deleted file mode 100644
index d54df471c1f..00000000000
--- a/src/main/java/seedu/address/model/Model.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package seedu.address.model;
-
-import java.nio.file.Path;
-import java.util.function.Predicate;
-
-import javafx.collections.ObservableList;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.model.person.Person;
-
-/**
- * The API of the Model component.
- */
-public interface Model {
- /** {@code Predicate} that always evaluate to true */
- Predicate PREDICATE_SHOW_ALL_PERSONS = unused -> true;
-
- /**
- * Replaces user prefs data with the data in {@code userPrefs}.
- */
- void setUserPrefs(ReadOnlyUserPrefs userPrefs);
-
- /**
- * Returns the user prefs.
- */
- ReadOnlyUserPrefs getUserPrefs();
-
- /**
- * Returns the user prefs' GUI settings.
- */
- GuiSettings getGuiSettings();
-
- /**
- * Sets the user prefs' GUI settings.
- */
- void setGuiSettings(GuiSettings guiSettings);
-
- /**
- * Returns the user prefs' address book file path.
- */
- Path getAddressBookFilePath();
-
- /**
- * Sets the user prefs' address book file path.
- */
- void setAddressBookFilePath(Path addressBookFilePath);
-
- /**
- * Replaces address book data with the data in {@code addressBook}.
- */
- void setAddressBook(ReadOnlyAddressBook addressBook);
-
- /** Returns the AddressBook */
- ReadOnlyAddressBook getAddressBook();
-
- /**
- * Returns true if a person with the same identity as {@code person} exists in the address book.
- */
- boolean hasPerson(Person person);
-
- /**
- * Deletes the given person.
- * The person must exist in the address book.
- */
- void deletePerson(Person target);
-
- /**
- * Adds the given person.
- * {@code person} must not already exist in the address book.
- */
- void addPerson(Person person);
-
- /**
- * Replaces the given person {@code target} with {@code editedPerson}.
- * {@code target} must exist in the address book.
- * The person identity of {@code editedPerson} must not be the same as another existing person in the address book.
- */
- void setPerson(Person target, Person editedPerson);
-
- /** Returns an unmodifiable view of the filtered person list */
- ObservableList getFilteredPersonList();
-
- /**
- * Updates the filter of the filtered person list to filter by the given {@code predicate}.
- * @throws NullPointerException if {@code predicate} is null.
- */
- void updateFilteredPersonList(Predicate predicate);
-}
diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java
deleted file mode 100644
index 57bc563fde6..00000000000
--- a/src/main/java/seedu/address/model/ModelManager.java
+++ /dev/null
@@ -1,148 +0,0 @@
-package seedu.address.model;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
-
-import java.nio.file.Path;
-import java.util.function.Predicate;
-import java.util.logging.Logger;
-
-import javafx.collections.ObservableList;
-import javafx.collections.transformation.FilteredList;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.model.person.Person;
-
-/**
- * Represents the in-memory model of the address book data.
- */
-public class ModelManager implements Model {
- private static final Logger logger = LogsCenter.getLogger(ModelManager.class);
-
- private final AddressBook addressBook;
- private final UserPrefs userPrefs;
- private final FilteredList filteredPersons;
-
- /**
- * Initializes a ModelManager with the given addressBook and userPrefs.
- */
- public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs) {
- requireAllNonNull(addressBook, userPrefs);
-
- logger.fine("Initializing with address book: " + addressBook + " and user prefs " + userPrefs);
-
- this.addressBook = new AddressBook(addressBook);
- this.userPrefs = new UserPrefs(userPrefs);
- filteredPersons = new FilteredList<>(this.addressBook.getPersonList());
- }
-
- public ModelManager() {
- this(new AddressBook(), new UserPrefs());
- }
-
- //=========== UserPrefs ==================================================================================
-
- @Override
- public void setUserPrefs(ReadOnlyUserPrefs userPrefs) {
- requireNonNull(userPrefs);
- this.userPrefs.resetData(userPrefs);
- }
-
- @Override
- public ReadOnlyUserPrefs getUserPrefs() {
- return userPrefs;
- }
-
- @Override
- public GuiSettings getGuiSettings() {
- return userPrefs.getGuiSettings();
- }
-
- @Override
- public void setGuiSettings(GuiSettings guiSettings) {
- requireNonNull(guiSettings);
- userPrefs.setGuiSettings(guiSettings);
- }
-
- @Override
- public Path getAddressBookFilePath() {
- return userPrefs.getAddressBookFilePath();
- }
-
- @Override
- public void setAddressBookFilePath(Path addressBookFilePath) {
- requireNonNull(addressBookFilePath);
- userPrefs.setAddressBookFilePath(addressBookFilePath);
- }
-
- //=========== AddressBook ================================================================================
-
- @Override
- public void setAddressBook(ReadOnlyAddressBook addressBook) {
- this.addressBook.resetData(addressBook);
- }
-
- @Override
- public ReadOnlyAddressBook getAddressBook() {
- return addressBook;
- }
-
- @Override
- public boolean hasPerson(Person person) {
- requireNonNull(person);
- return addressBook.hasPerson(person);
- }
-
- @Override
- public void deletePerson(Person target) {
- addressBook.removePerson(target);
- }
-
- @Override
- public void addPerson(Person person) {
- addressBook.addPerson(person);
- updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
- }
-
- @Override
- public void setPerson(Person target, Person editedPerson) {
- requireAllNonNull(target, editedPerson);
-
- addressBook.setPerson(target, editedPerson);
- }
-
- //=========== Filtered Person List Accessors =============================================================
-
- /**
- * Returns an unmodifiable view of the list of {@code Person} backed by the internal list of
- * {@code versionedAddressBook}
- */
- @Override
- public ObservableList getFilteredPersonList() {
- return filteredPersons;
- }
-
- @Override
- public void updateFilteredPersonList(Predicate predicate) {
- requireNonNull(predicate);
- filteredPersons.setPredicate(predicate);
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof ModelManager)) {
- return false;
- }
-
- ModelManager otherModelManager = (ModelManager) other;
- return addressBook.equals(otherModelManager.addressBook)
- && userPrefs.equals(otherModelManager.userPrefs)
- && filteredPersons.equals(otherModelManager.filteredPersons);
- }
-
-}
diff --git a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java b/src/main/java/seedu/address/model/ReadOnlyAddressBook.java
deleted file mode 100644
index 6ddc2cd9a29..00000000000
--- a/src/main/java/seedu/address/model/ReadOnlyAddressBook.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package seedu.address.model;
-
-import javafx.collections.ObservableList;
-import seedu.address.model.person.Person;
-
-/**
- * Unmodifiable view of an address book
- */
-public interface ReadOnlyAddressBook {
-
- /**
- * Returns an unmodifiable view of the persons list.
- * This list will not contain any duplicate persons.
- */
- ObservableList getPersonList();
-
-}
diff --git a/src/main/java/seedu/address/model/person/Address.java b/src/main/java/seedu/address/model/person/Address.java
deleted file mode 100644
index 469a2cc9a1e..00000000000
--- a/src/main/java/seedu/address/model/person/Address.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package seedu.address.model.person;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
-
-/**
- * Represents a Person's address in the address book.
- * Guarantees: immutable; is valid as declared in {@link #isValidAddress(String)}
- */
-public class Address {
-
- public static final String MESSAGE_CONSTRAINTS = "Addresses can take any values, and it should not be blank";
-
- /*
- * The first character of the address must not be a whitespace,
- * otherwise " " (a blank string) becomes a valid input.
- */
- public static final String VALIDATION_REGEX = "[^\\s].*";
-
- public final String value;
-
- /**
- * Constructs an {@code Address}.
- *
- * @param address A valid address.
- */
- public Address(String address) {
- requireNonNull(address);
- checkArgument(isValidAddress(address), MESSAGE_CONSTRAINTS);
- value = address;
- }
-
- /**
- * Returns true if a given string is a valid email.
- */
- public static boolean isValidAddress(String test) {
- return test.matches(VALIDATION_REGEX);
- }
-
- @Override
- public String toString() {
- return value;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof Address)) {
- return false;
- }
-
- Address otherAddress = (Address) other;
- return value.equals(otherAddress.value);
- }
-
- @Override
- public int hashCode() {
- return value.hashCode();
- }
-
-}
diff --git a/src/main/java/seedu/address/model/person/Email.java b/src/main/java/seedu/address/model/person/Email.java
deleted file mode 100644
index c62e512bc29..00000000000
--- a/src/main/java/seedu/address/model/person/Email.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package seedu.address.model.person;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
-
-/**
- * Represents a Person's email in the address book.
- * Guarantees: immutable; is valid as declared in {@link #isValidEmail(String)}
- */
-public class Email {
-
- private static final String SPECIAL_CHARACTERS = "+_.-";
- public static final String MESSAGE_CONSTRAINTS = "Emails should be of the format local-part@domain "
- + "and adhere to the following constraints:\n"
- + "1. The local-part should only contain alphanumeric characters and these special characters, excluding "
- + "the parentheses, (" + SPECIAL_CHARACTERS + "). The local-part may not start or end with any special "
- + "characters.\n"
- + "2. This is followed by a '@' and then a domain name. The domain name is made up of domain labels "
- + "separated by periods.\n"
- + "The domain name must:\n"
- + " - end with a domain label at least 2 characters long\n"
- + " - have each domain label start and end with alphanumeric characters\n"
- + " - have each domain label consist of alphanumeric characters, separated only by hyphens, if any.";
- // alphanumeric and special characters
- private static final String ALPHANUMERIC_NO_UNDERSCORE = "[^\\W_]+"; // alphanumeric characters except underscore
- private static final String LOCAL_PART_REGEX = "^" + ALPHANUMERIC_NO_UNDERSCORE + "([" + SPECIAL_CHARACTERS + "]"
- + ALPHANUMERIC_NO_UNDERSCORE + ")*";
- private static final String DOMAIN_PART_REGEX = ALPHANUMERIC_NO_UNDERSCORE
- + "(-" + ALPHANUMERIC_NO_UNDERSCORE + ")*";
- private static final String DOMAIN_LAST_PART_REGEX = "(" + DOMAIN_PART_REGEX + "){2,}$"; // At least two chars
- private static final String DOMAIN_REGEX = "(" + DOMAIN_PART_REGEX + "\\.)*" + DOMAIN_LAST_PART_REGEX;
- public static final String VALIDATION_REGEX = LOCAL_PART_REGEX + "@" + DOMAIN_REGEX;
-
- public final String value;
-
- /**
- * Constructs an {@code Email}.
- *
- * @param email A valid email address.
- */
- public Email(String email) {
- requireNonNull(email);
- checkArgument(isValidEmail(email), MESSAGE_CONSTRAINTS);
- value = email;
- }
-
- /**
- * Returns if a given string is a valid email.
- */
- public static boolean isValidEmail(String test) {
- return test.matches(VALIDATION_REGEX);
- }
-
- @Override
- public String toString() {
- return value;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof Email)) {
- return false;
- }
-
- Email otherEmail = (Email) other;
- return value.equals(otherEmail.value);
- }
-
- @Override
- public int hashCode() {
- return value.hashCode();
- }
-
-}
diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java
deleted file mode 100644
index abe8c46b535..00000000000
--- a/src/main/java/seedu/address/model/person/Person.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package seedu.address.model.person;
-
-import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-import seedu.address.commons.util.ToStringBuilder;
-import seedu.address.model.tag.Tag;
-
-/**
- * Represents a Person in the address book.
- * Guarantees: details are present and not null, field values are validated, immutable.
- */
-public class Person {
-
- // Identity fields
- private final Name name;
- private final Phone phone;
- private final Email email;
-
- // Data fields
- private final Address address;
- private final Set tags = new HashSet<>();
-
- /**
- * Every field must be present and not null.
- */
- public Person(Name name, Phone phone, Email email, Address address, Set tags) {
- requireAllNonNull(name, phone, email, address, tags);
- this.name = name;
- this.phone = phone;
- this.email = email;
- this.address = address;
- this.tags.addAll(tags);
- }
-
- public Name getName() {
- return name;
- }
-
- public Phone getPhone() {
- return phone;
- }
-
- public Email getEmail() {
- return email;
- }
-
- public Address getAddress() {
- return address;
- }
-
- /**
- * Returns an immutable tag set, which throws {@code UnsupportedOperationException}
- * if modification is attempted.
- */
- public Set getTags() {
- return Collections.unmodifiableSet(tags);
- }
-
- /**
- * Returns true if both persons have the same name.
- * This defines a weaker notion of equality between two persons.
- */
- public boolean isSamePerson(Person otherPerson) {
- if (otherPerson == this) {
- return true;
- }
-
- return otherPerson != null
- && otherPerson.getName().equals(getName());
- }
-
- /**
- * Returns true if both persons have the same identity and data fields.
- * This defines a stronger notion of equality between two persons.
- */
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof Person)) {
- return false;
- }
-
- Person otherPerson = (Person) other;
- return name.equals(otherPerson.name)
- && phone.equals(otherPerson.phone)
- && email.equals(otherPerson.email)
- && address.equals(otherPerson.address)
- && tags.equals(otherPerson.tags);
- }
-
- @Override
- public int hashCode() {
- // use this method for custom fields hashing instead of implementing your own
- return Objects.hash(name, phone, email, address, tags);
- }
-
- @Override
- public String toString() {
- return new ToStringBuilder(this)
- .add("name", name)
- .add("phone", phone)
- .add("email", email)
- .add("address", address)
- .add("tags", tags)
- .toString();
- }
-
-}
diff --git a/src/main/java/seedu/address/model/person/Phone.java b/src/main/java/seedu/address/model/person/Phone.java
deleted file mode 100644
index d733f63d739..00000000000
--- a/src/main/java/seedu/address/model/person/Phone.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package seedu.address.model.person;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
-
-/**
- * Represents a Person's phone number in the address book.
- * Guarantees: immutable; is valid as declared in {@link #isValidPhone(String)}
- */
-public class Phone {
-
-
- public static final String MESSAGE_CONSTRAINTS =
- "Phone numbers should only contain numbers, and it should be at least 3 digits long";
- public static final String VALIDATION_REGEX = "\\d{3,}";
- public final String value;
-
- /**
- * Constructs a {@code Phone}.
- *
- * @param phone A valid phone number.
- */
- public Phone(String phone) {
- requireNonNull(phone);
- checkArgument(isValidPhone(phone), MESSAGE_CONSTRAINTS);
- value = phone;
- }
-
- /**
- * Returns true if a given string is a valid phone number.
- */
- public static boolean isValidPhone(String test) {
- return test.matches(VALIDATION_REGEX);
- }
-
- @Override
- public String toString() {
- return value;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof Phone)) {
- return false;
- }
-
- Phone otherPhone = (Phone) other;
- return value.equals(otherPhone.value);
- }
-
- @Override
- public int hashCode() {
- return value.hashCode();
- }
-
-}
diff --git a/src/main/java/seedu/address/model/person/UniquePersonList.java b/src/main/java/seedu/address/model/person/UniquePersonList.java
deleted file mode 100644
index cc0a68d79f9..00000000000
--- a/src/main/java/seedu/address/model/person/UniquePersonList.java
+++ /dev/null
@@ -1,150 +0,0 @@
-package seedu.address.model.person;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
-
-import java.util.Iterator;
-import java.util.List;
-
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-import seedu.address.model.person.exceptions.DuplicatePersonException;
-import seedu.address.model.person.exceptions.PersonNotFoundException;
-
-/**
- * A list of persons that enforces uniqueness between its elements and does not allow nulls.
- * A person is considered unique by comparing using {@code Person#isSamePerson(Person)}. As such, adding and updating of
- * persons uses Person#isSamePerson(Person) for equality so as to ensure that the person being added or updated is
- * unique in terms of identity in the UniquePersonList. However, the removal of a person uses Person#equals(Object) so
- * as to ensure that the person with exactly the same fields will be removed.
- *
- * Supports a minimal set of list operations.
- *
- * @see Person#isSamePerson(Person)
- */
-public class UniquePersonList implements Iterable {
-
- private final ObservableList internalList = FXCollections.observableArrayList();
- private final ObservableList internalUnmodifiableList =
- FXCollections.unmodifiableObservableList(internalList);
-
- /**
- * Returns true if the list contains an equivalent person as the given argument.
- */
- public boolean contains(Person toCheck) {
- requireNonNull(toCheck);
- return internalList.stream().anyMatch(toCheck::isSamePerson);
- }
-
- /**
- * Adds a person to the list.
- * The person must not already exist in the list.
- */
- public void add(Person toAdd) {
- requireNonNull(toAdd);
- if (contains(toAdd)) {
- throw new DuplicatePersonException();
- }
- internalList.add(toAdd);
- }
-
- /**
- * Replaces the person {@code target} in the list with {@code editedPerson}.
- * {@code target} must exist in the list.
- * The person identity of {@code editedPerson} must not be the same as another existing person in the list.
- */
- public void setPerson(Person target, Person editedPerson) {
- requireAllNonNull(target, editedPerson);
-
- int index = internalList.indexOf(target);
- if (index == -1) {
- throw new PersonNotFoundException();
- }
-
- if (!target.isSamePerson(editedPerson) && contains(editedPerson)) {
- throw new DuplicatePersonException();
- }
-
- internalList.set(index, editedPerson);
- }
-
- /**
- * Removes the equivalent person from the list.
- * The person must exist in the list.
- */
- public void remove(Person toRemove) {
- requireNonNull(toRemove);
- if (!internalList.remove(toRemove)) {
- throw new PersonNotFoundException();
- }
- }
-
- public void setPersons(UniquePersonList replacement) {
- requireNonNull(replacement);
- internalList.setAll(replacement.internalList);
- }
-
- /**
- * Replaces the contents of this list with {@code persons}.
- * {@code persons} must not contain duplicate persons.
- */
- public void setPersons(List persons) {
- requireAllNonNull(persons);
- if (!personsAreUnique(persons)) {
- throw new DuplicatePersonException();
- }
-
- internalList.setAll(persons);
- }
-
- /**
- * Returns the backing list as an unmodifiable {@code ObservableList}.
- */
- public ObservableList asUnmodifiableObservableList() {
- return internalUnmodifiableList;
- }
-
- @Override
- public Iterator iterator() {
- return internalList.iterator();
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof UniquePersonList)) {
- return false;
- }
-
- UniquePersonList otherUniquePersonList = (UniquePersonList) other;
- return internalList.equals(otherUniquePersonList.internalList);
- }
-
- @Override
- public int hashCode() {
- return internalList.hashCode();
- }
-
- @Override
- public String toString() {
- return internalList.toString();
- }
-
- /**
- * Returns true if {@code persons} contains only unique persons.
- */
- private boolean personsAreUnique(List persons) {
- for (int i = 0; i < persons.size() - 1; i++) {
- for (int j = i + 1; j < persons.size(); j++) {
- if (persons.get(i).isSamePerson(persons.get(j))) {
- return false;
- }
- }
- }
- return true;
- }
-}
diff --git a/src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java b/src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java
deleted file mode 100644
index fa764426ca7..00000000000
--- a/src/main/java/seedu/address/model/person/exceptions/PersonNotFoundException.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package seedu.address.model.person.exceptions;
-
-/**
- * Signals that the operation is unable to find the specified person.
- */
-public class PersonNotFoundException extends RuntimeException {}
diff --git a/src/main/java/seedu/address/model/tag/Tag.java b/src/main/java/seedu/address/model/tag/Tag.java
deleted file mode 100644
index f1a0d4e233b..00000000000
--- a/src/main/java/seedu/address/model/tag/Tag.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package seedu.address.model.tag;
-
-import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
-
-/**
- * Represents a Tag in the address book.
- * Guarantees: immutable; name is valid as declared in {@link #isValidTagName(String)}
- */
-public class Tag {
-
- public static final String MESSAGE_CONSTRAINTS = "Tags names should be alphanumeric";
- public static final String VALIDATION_REGEX = "\\p{Alnum}+";
-
- public final String tagName;
-
- /**
- * Constructs a {@code Tag}.
- *
- * @param tagName A valid tag name.
- */
- public Tag(String tagName) {
- requireNonNull(tagName);
- checkArgument(isValidTagName(tagName), MESSAGE_CONSTRAINTS);
- this.tagName = tagName;
- }
-
- /**
- * Returns true if a given string is a valid tag name.
- */
- public static boolean isValidTagName(String test) {
- return test.matches(VALIDATION_REGEX);
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
-
- // instanceof handles nulls
- if (!(other instanceof Tag)) {
- return false;
- }
-
- Tag otherTag = (Tag) other;
- return tagName.equals(otherTag.tagName);
- }
-
- @Override
- public int hashCode() {
- return tagName.hashCode();
- }
-
- /**
- * Format state as text for viewing.
- */
- public String toString() {
- return '[' + tagName + ']';
- }
-
-}
diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java
deleted file mode 100644
index 1806da4facf..00000000000
--- a/src/main/java/seedu/address/model/util/SampleDataUtil.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package seedu.address.model.util;
-
-import java.util.Arrays;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import seedu.address.model.AddressBook;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-
-/**
- * Contains utility methods for populating {@code AddressBook} with sample data.
- */
-public class SampleDataUtil {
- public static Person[] getSamplePersons() {
- return new Person[] {
- new Person(new Name("Alex Yeoh"), new Phone("87438807"), new Email("alexyeoh@example.com"),
- new Address("Blk 30 Geylang Street 29, #06-40"),
- getTagSet("friends")),
- new Person(new Name("Bernice Yu"), new Phone("99272758"), new Email("berniceyu@example.com"),
- new Address("Blk 30 Lorong 3 Serangoon Gardens, #07-18"),
- getTagSet("colleagues", "friends")),
- new Person(new Name("Charlotte Oliveiro"), new Phone("93210283"), new Email("charlotte@example.com"),
- new Address("Blk 11 Ang Mo Kio Street 74, #11-04"),
- getTagSet("neighbours")),
- new Person(new Name("David Li"), new Phone("91031282"), new Email("lidavid@example.com"),
- new Address("Blk 436 Serangoon Gardens Street 26, #16-43"),
- getTagSet("family")),
- new Person(new Name("Irfan Ibrahim"), new Phone("92492021"), new Email("irfan@example.com"),
- new Address("Blk 47 Tampines Street 20, #17-35"),
- getTagSet("classmates")),
- new Person(new Name("Roy Balakrishnan"), new Phone("92624417"), new Email("royb@example.com"),
- new Address("Blk 45 Aljunied Street 85, #11-31"),
- getTagSet("colleagues"))
- };
- }
-
- public static ReadOnlyAddressBook getSampleAddressBook() {
- AddressBook sampleAb = new AddressBook();
- for (Person samplePerson : getSamplePersons()) {
- sampleAb.addPerson(samplePerson);
- }
- return sampleAb;
- }
-
- /**
- * Returns a tag set containing the list of strings given.
- */
- public static Set getTagSet(String... strings) {
- return Arrays.stream(strings)
- .map(Tag::new)
- .collect(Collectors.toSet());
- }
-
-}
diff --git a/src/main/java/seedu/address/storage/AddressBookStorage.java b/src/main/java/seedu/address/storage/AddressBookStorage.java
deleted file mode 100644
index f2e015105ae..00000000000
--- a/src/main/java/seedu/address/storage/AddressBookStorage.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package seedu.address.storage;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Optional;
-
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.model.ReadOnlyAddressBook;
-
-/**
- * Represents a storage for {@link seedu.address.model.AddressBook}.
- */
-public interface AddressBookStorage {
-
- /**
- * Returns the file path of the data file.
- */
- Path getAddressBookFilePath();
-
- /**
- * Returns AddressBook data as a {@link ReadOnlyAddressBook}.
- * Returns {@code Optional.empty()} if storage file is not found.
- *
- * @throws DataLoadingException if loading the data from storage failed.
- */
- Optional readAddressBook() throws DataLoadingException;
-
- /**
- * @see #getAddressBookFilePath()
- */
- Optional readAddressBook(Path filePath) throws DataLoadingException;
-
- /**
- * Saves the given {@link ReadOnlyAddressBook} to the storage.
- * @param addressBook cannot be null.
- * @throws IOException if there was any problem writing to the file.
- */
- void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException;
-
- /**
- * @see #saveAddressBook(ReadOnlyAddressBook)
- */
- void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) throws IOException;
-
-}
diff --git a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java b/src/main/java/seedu/address/storage/JsonAdaptedPerson.java
deleted file mode 100644
index bd1ca0f56c8..00000000000
--- a/src/main/java/seedu/address/storage/JsonAdaptedPerson.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package seedu.address.storage;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-
-/**
- * Jackson-friendly version of {@link Person}.
- */
-class JsonAdaptedPerson {
-
- public static final String MISSING_FIELD_MESSAGE_FORMAT = "Person's %s field is missing!";
-
- private final String name;
- private final String phone;
- private final String email;
- private final String address;
- private final List tags = new ArrayList<>();
-
- /**
- * Constructs a {@code JsonAdaptedPerson} with the given person details.
- */
- @JsonCreator
- public JsonAdaptedPerson(@JsonProperty("name") String name, @JsonProperty("phone") String phone,
- @JsonProperty("email") String email, @JsonProperty("address") String address,
- @JsonProperty("tags") List tags) {
- this.name = name;
- this.phone = phone;
- this.email = email;
- this.address = address;
- if (tags != null) {
- this.tags.addAll(tags);
- }
- }
-
- /**
- * Converts a given {@code Person} into this class for Jackson use.
- */
- public JsonAdaptedPerson(Person source) {
- name = source.getName().fullName;
- phone = source.getPhone().value;
- email = source.getEmail().value;
- address = source.getAddress().value;
- tags.addAll(source.getTags().stream()
- .map(JsonAdaptedTag::new)
- .collect(Collectors.toList()));
- }
-
- /**
- * Converts this Jackson-friendly adapted person object into the model's {@code Person} object.
- *
- * @throws IllegalValueException if there were any data constraints violated in the adapted person.
- */
- public Person toModelType() throws IllegalValueException {
- final List personTags = new ArrayList<>();
- for (JsonAdaptedTag tag : tags) {
- personTags.add(tag.toModelType());
- }
-
- if (name == null) {
- throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName()));
- }
- if (!Name.isValidName(name)) {
- throw new IllegalValueException(Name.MESSAGE_CONSTRAINTS);
- }
- final Name modelName = new Name(name);
-
- if (phone == null) {
- throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName()));
- }
- if (!Phone.isValidPhone(phone)) {
- throw new IllegalValueException(Phone.MESSAGE_CONSTRAINTS);
- }
- final Phone modelPhone = new Phone(phone);
-
- if (email == null) {
- throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName()));
- }
- if (!Email.isValidEmail(email)) {
- throw new IllegalValueException(Email.MESSAGE_CONSTRAINTS);
- }
- final Email modelEmail = new Email(email);
-
- if (address == null) {
- throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName()));
- }
- if (!Address.isValidAddress(address)) {
- throw new IllegalValueException(Address.MESSAGE_CONSTRAINTS);
- }
- final Address modelAddress = new Address(address);
-
- final Set modelTags = new HashSet<>(personTags);
- return new Person(modelName, modelPhone, modelEmail, modelAddress, modelTags);
- }
-
-}
diff --git a/src/main/java/seedu/address/storage/JsonAdaptedTag.java b/src/main/java/seedu/address/storage/JsonAdaptedTag.java
deleted file mode 100644
index 0df22bdb754..00000000000
--- a/src/main/java/seedu/address/storage/JsonAdaptedTag.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package seedu.address.storage;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonValue;
-
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.model.tag.Tag;
-
-/**
- * Jackson-friendly version of {@link Tag}.
- */
-class JsonAdaptedTag {
-
- private final String tagName;
-
- /**
- * Constructs a {@code JsonAdaptedTag} with the given {@code tagName}.
- */
- @JsonCreator
- public JsonAdaptedTag(String tagName) {
- this.tagName = tagName;
- }
-
- /**
- * Converts a given {@code Tag} into this class for Jackson use.
- */
- public JsonAdaptedTag(Tag source) {
- tagName = source.tagName;
- }
-
- @JsonValue
- public String getTagName() {
- return tagName;
- }
-
- /**
- * Converts this Jackson-friendly adapted tag object into the model's {@code Tag} object.
- *
- * @throws IllegalValueException if there were any data constraints violated in the adapted tag.
- */
- public Tag toModelType() throws IllegalValueException {
- if (!Tag.isValidTagName(tagName)) {
- throw new IllegalValueException(Tag.MESSAGE_CONSTRAINTS);
- }
- return new Tag(tagName);
- }
-
-}
diff --git a/src/main/java/seedu/address/storage/JsonAddressBookStorage.java b/src/main/java/seedu/address/storage/JsonAddressBookStorage.java
deleted file mode 100644
index 41e06f264e1..00000000000
--- a/src/main/java/seedu/address/storage/JsonAddressBookStorage.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package seedu.address.storage;
-
-import static java.util.Objects.requireNonNull;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Optional;
-import java.util.logging.Logger;
-
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.commons.util.FileUtil;
-import seedu.address.commons.util.JsonUtil;
-import seedu.address.model.ReadOnlyAddressBook;
-
-/**
- * A class to access AddressBook data stored as a json file on the hard disk.
- */
-public class JsonAddressBookStorage implements AddressBookStorage {
-
- private static final Logger logger = LogsCenter.getLogger(JsonAddressBookStorage.class);
-
- private Path filePath;
-
- public JsonAddressBookStorage(Path filePath) {
- this.filePath = filePath;
- }
-
- public Path getAddressBookFilePath() {
- return filePath;
- }
-
- @Override
- public Optional readAddressBook() throws DataLoadingException {
- return readAddressBook(filePath);
- }
-
- /**
- * Similar to {@link #readAddressBook()}.
- *
- * @param filePath location of the data. Cannot be null.
- * @throws DataLoadingException if loading the data from storage failed.
- */
- public Optional readAddressBook(Path filePath) throws DataLoadingException {
- requireNonNull(filePath);
-
- Optional jsonAddressBook = JsonUtil.readJsonFile(
- filePath, JsonSerializableAddressBook.class);
- if (!jsonAddressBook.isPresent()) {
- return Optional.empty();
- }
-
- try {
- return Optional.of(jsonAddressBook.get().toModelType());
- } catch (IllegalValueException ive) {
- logger.info("Illegal values found in " + filePath + ": " + ive.getMessage());
- throw new DataLoadingException(ive);
- }
- }
-
- @Override
- public void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException {
- saveAddressBook(addressBook, filePath);
- }
-
- /**
- * Similar to {@link #saveAddressBook(ReadOnlyAddressBook)}.
- *
- * @param filePath location of the data. Cannot be null.
- */
- public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) throws IOException {
- requireNonNull(addressBook);
- requireNonNull(filePath);
-
- FileUtil.createIfMissing(filePath);
- JsonUtil.saveJsonFile(new JsonSerializableAddressBook(addressBook), filePath);
- }
-
-}
diff --git a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java b/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java
deleted file mode 100644
index 5efd834091d..00000000000
--- a/src/main/java/seedu/address/storage/JsonSerializableAddressBook.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package seedu.address.storage;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonRootName;
-
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.model.AddressBook;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.person.Person;
-
-/**
- * An Immutable AddressBook that is serializable to JSON format.
- */
-@JsonRootName(value = "addressbook")
-class JsonSerializableAddressBook {
-
- public static final String MESSAGE_DUPLICATE_PERSON = "Persons list contains duplicate person(s).";
-
- private final List persons = new ArrayList<>();
-
- /**
- * Constructs a {@code JsonSerializableAddressBook} with the given persons.
- */
- @JsonCreator
- public JsonSerializableAddressBook(@JsonProperty("persons") List persons) {
- this.persons.addAll(persons);
- }
-
- /**
- * Converts a given {@code ReadOnlyAddressBook} into this class for Jackson use.
- *
- * @param source future changes to this will not affect the created {@code JsonSerializableAddressBook}.
- */
- public JsonSerializableAddressBook(ReadOnlyAddressBook source) {
- persons.addAll(source.getPersonList().stream().map(JsonAdaptedPerson::new).collect(Collectors.toList()));
- }
-
- /**
- * Converts this address book into the model's {@code AddressBook} object.
- *
- * @throws IllegalValueException if there were any data constraints violated.
- */
- public AddressBook toModelType() throws IllegalValueException {
- AddressBook addressBook = new AddressBook();
- for (JsonAdaptedPerson jsonAdaptedPerson : persons) {
- Person person = jsonAdaptedPerson.toModelType();
- if (addressBook.hasPerson(person)) {
- throw new IllegalValueException(MESSAGE_DUPLICATE_PERSON);
- }
- addressBook.addPerson(person);
- }
- return addressBook;
- }
-
-}
diff --git a/src/main/java/seedu/address/storage/Storage.java b/src/main/java/seedu/address/storage/Storage.java
deleted file mode 100644
index 9fba0c7a1d6..00000000000
--- a/src/main/java/seedu/address/storage/Storage.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package seedu.address.storage;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Optional;
-
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.UserPrefs;
-
-/**
- * API of the Storage component
- */
-public interface Storage extends AddressBookStorage, UserPrefsStorage {
-
- @Override
- Optional readUserPrefs() throws DataLoadingException;
-
- @Override
- void saveUserPrefs(ReadOnlyUserPrefs userPrefs) throws IOException;
-
- @Override
- Path getAddressBookFilePath();
-
- @Override
- Optional readAddressBook() throws DataLoadingException;
-
- @Override
- void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException;
-
-}
diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java
deleted file mode 100644
index 8b84a9024d5..00000000000
--- a/src/main/java/seedu/address/storage/StorageManager.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package seedu.address.storage;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Optional;
-import java.util.logging.Logger;
-
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.UserPrefs;
-
-/**
- * Manages storage of AddressBook data in local storage.
- */
-public class StorageManager implements Storage {
-
- private static final Logger logger = LogsCenter.getLogger(StorageManager.class);
- private AddressBookStorage addressBookStorage;
- private UserPrefsStorage userPrefsStorage;
-
- /**
- * Creates a {@code StorageManager} with the given {@code AddressBookStorage} and {@code UserPrefStorage}.
- */
- public StorageManager(AddressBookStorage addressBookStorage, UserPrefsStorage userPrefsStorage) {
- this.addressBookStorage = addressBookStorage;
- this.userPrefsStorage = userPrefsStorage;
- }
-
- // ================ UserPrefs methods ==============================
-
- @Override
- public Path getUserPrefsFilePath() {
- return userPrefsStorage.getUserPrefsFilePath();
- }
-
- @Override
- public Optional readUserPrefs() throws DataLoadingException {
- return userPrefsStorage.readUserPrefs();
- }
-
- @Override
- public void saveUserPrefs(ReadOnlyUserPrefs userPrefs) throws IOException {
- userPrefsStorage.saveUserPrefs(userPrefs);
- }
-
-
- // ================ AddressBook methods ==============================
-
- @Override
- public Path getAddressBookFilePath() {
- return addressBookStorage.getAddressBookFilePath();
- }
-
- @Override
- public Optional readAddressBook() throws DataLoadingException {
- return readAddressBook(addressBookStorage.getAddressBookFilePath());
- }
-
- @Override
- public Optional readAddressBook(Path filePath) throws DataLoadingException {
- logger.fine("Attempting to read data from file: " + filePath);
- return addressBookStorage.readAddressBook(filePath);
- }
-
- @Override
- public void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException {
- saveAddressBook(addressBook, addressBookStorage.getAddressBookFilePath());
- }
-
- @Override
- public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) throws IOException {
- logger.fine("Attempting to write to data file: " + filePath);
- addressBookStorage.saveAddressBook(addressBook, filePath);
- }
-
-}
diff --git a/src/main/java/seedu/address/ui/PersonCard.java b/src/main/java/seedu/address/ui/PersonCard.java
deleted file mode 100644
index 094c42cda82..00000000000
--- a/src/main/java/seedu/address/ui/PersonCard.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package seedu.address.ui;
-
-import java.util.Comparator;
-
-import javafx.fxml.FXML;
-import javafx.scene.control.Label;
-import javafx.scene.layout.FlowPane;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Region;
-import seedu.address.model.person.Person;
-
-/**
- * An UI component that displays information of a {@code Person}.
- */
-public class PersonCard extends UiPart {
-
- private static final String FXML = "PersonListCard.fxml";
-
- /**
- * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX.
- * As a consequence, UI elements' variable names cannot be set to such keywords
- * or an exception will be thrown by JavaFX during runtime.
- *
- * @see The issue on AddressBook level 4
- */
-
- public final Person person;
-
- @FXML
- private HBox cardPane;
- @FXML
- private Label name;
- @FXML
- private Label id;
- @FXML
- private Label phone;
- @FXML
- private Label address;
- @FXML
- private Label email;
- @FXML
- private FlowPane tags;
-
- /**
- * Creates a {@code PersonCode} with the given {@code Person} and index to display.
- */
- public PersonCard(Person person, int displayedIndex) {
- super(FXML);
- this.person = person;
- id.setText(displayedIndex + ". ");
- name.setText(person.getName().fullName);
- phone.setText(person.getPhone().value);
- address.setText(person.getAddress().value);
- email.setText(person.getEmail().value);
- person.getTags().stream()
- .sorted(Comparator.comparing(tag -> tag.tagName))
- .forEach(tag -> tags.getChildren().add(new Label(tag.tagName)));
- }
-}
diff --git a/src/main/java/seedu/address/ui/PersonListPanel.java b/src/main/java/seedu/address/ui/PersonListPanel.java
deleted file mode 100644
index f4c501a897b..00000000000
--- a/src/main/java/seedu/address/ui/PersonListPanel.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package seedu.address.ui;
-
-import java.util.logging.Logger;
-
-import javafx.collections.ObservableList;
-import javafx.fxml.FXML;
-import javafx.scene.control.ListCell;
-import javafx.scene.control.ListView;
-import javafx.scene.layout.Region;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.model.person.Person;
-
-/**
- * Panel containing the list of persons.
- */
-public class PersonListPanel extends UiPart {
- private static final String FXML = "PersonListPanel.fxml";
- private final Logger logger = LogsCenter.getLogger(PersonListPanel.class);
-
- @FXML
- private ListView personListView;
-
- /**
- * Creates a {@code PersonListPanel} with the given {@code ObservableList}.
- */
- public PersonListPanel(ObservableList personList) {
- super(FXML);
- personListView.setItems(personList);
- personListView.setCellFactory(listView -> new PersonListViewCell());
- }
-
- /**
- * Custom {@code ListCell} that displays the graphics of a {@code Person} using a {@code PersonCard}.
- */
- class PersonListViewCell extends ListCell {
- @Override
- protected void updateItem(Person person, boolean empty) {
- super.updateItem(person, empty);
-
- if (empty || person == null) {
- setGraphic(null);
- setText(null);
- } else {
- setGraphic(new PersonCard(person, getIndex() + 1).getRoot());
- }
- }
- }
-
-}
diff --git a/src/main/java/seedu/address/AppParameters.java b/src/main/java/seedu/lovebook/AppParameters.java
similarity index 92%
rename from src/main/java/seedu/address/AppParameters.java
rename to src/main/java/seedu/lovebook/AppParameters.java
index 3d603622d4e..a2e29955eb5 100644
--- a/src/main/java/seedu/address/AppParameters.java
+++ b/src/main/java/seedu/lovebook/AppParameters.java
@@ -1,4 +1,4 @@
-package seedu.address;
+package seedu.lovebook;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -7,9 +7,9 @@
import java.util.logging.Logger;
import javafx.application.Application;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.util.FileUtil;
-import seedu.address.commons.util.ToStringBuilder;
+import seedu.lovebook.commons.core.LogsCenter;
+import seedu.lovebook.commons.util.FileUtil;
+import seedu.lovebook.commons.util.ToStringBuilder;
/**
* Represents the parsed command-line parameters given to the application.
diff --git a/src/main/java/seedu/address/Main.java b/src/main/java/seedu/lovebook/Main.java
similarity index 95%
rename from src/main/java/seedu/address/Main.java
rename to src/main/java/seedu/lovebook/Main.java
index ec1b7958746..807668590d7 100644
--- a/src/main/java/seedu/address/Main.java
+++ b/src/main/java/seedu/lovebook/Main.java
@@ -1,9 +1,9 @@
-package seedu.address;
+package seedu.lovebook;
import java.util.logging.Logger;
import javafx.application.Application;
-import seedu.address.commons.core.LogsCenter;
+import seedu.lovebook.commons.core.LogsCenter;
/**
* The main entry point to the application.
diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/lovebook/MainApp.java
similarity index 57%
rename from src/main/java/seedu/address/MainApp.java
rename to src/main/java/seedu/lovebook/MainApp.java
index 3d6bd06d5af..2c650b3369f 100644
--- a/src/main/java/seedu/address/MainApp.java
+++ b/src/main/java/seedu/lovebook/MainApp.java
@@ -1,4 +1,4 @@
-package seedu.address;
+package seedu.lovebook;
import java.io.IOException;
import java.nio.file.Path;
@@ -7,29 +7,34 @@
import javafx.application.Application;
import javafx.stage.Stage;
-import seedu.address.commons.core.Config;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.core.Version;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.commons.util.ConfigUtil;
-import seedu.address.commons.util.StringUtil;
-import seedu.address.logic.Logic;
-import seedu.address.logic.LogicManager;
-import seedu.address.model.AddressBook;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.UserPrefs;
-import seedu.address.model.util.SampleDataUtil;
-import seedu.address.storage.AddressBookStorage;
-import seedu.address.storage.JsonAddressBookStorage;
-import seedu.address.storage.JsonUserPrefsStorage;
-import seedu.address.storage.Storage;
-import seedu.address.storage.StorageManager;
-import seedu.address.storage.UserPrefsStorage;
-import seedu.address.ui.Ui;
-import seedu.address.ui.UiManager;
+import seedu.lovebook.commons.core.Config;
+import seedu.lovebook.commons.core.LogsCenter;
+import seedu.lovebook.commons.core.Version;
+import seedu.lovebook.commons.exceptions.DataLoadingException;
+import seedu.lovebook.commons.util.ConfigUtil;
+import seedu.lovebook.commons.util.StringUtil;
+import seedu.lovebook.logic.Logic;
+import seedu.lovebook.logic.LogicManager;
+import seedu.lovebook.model.DatePrefs;
+import seedu.lovebook.model.LoveBook;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ModelManager;
+import seedu.lovebook.model.ReadOnlyDatePrefs;
+import seedu.lovebook.model.ReadOnlyLoveBook;
+import seedu.lovebook.model.ReadOnlyUserPrefs;
+import seedu.lovebook.model.UserPrefs;
+import seedu.lovebook.model.util.SampleDataUtil;
+import seedu.lovebook.model.util.SampleDatePrefUtil;
+import seedu.lovebook.storage.DatePrefsStorage;
+import seedu.lovebook.storage.JsonDatePrefsStorage;
+import seedu.lovebook.storage.JsonLoveBookStorage;
+import seedu.lovebook.storage.JsonUserPrefsStorage;
+import seedu.lovebook.storage.LoveBookStorage;
+import seedu.lovebook.storage.Storage;
+import seedu.lovebook.storage.StorageManager;
+import seedu.lovebook.storage.UserPrefsStorage;
+import seedu.lovebook.ui.Ui;
+import seedu.lovebook.ui.UiManager;
/**
* Runs the application.
@@ -48,7 +53,7 @@ public class MainApp extends Application {
@Override
public void init() throws Exception {
- logger.info("=============================[ Initializing AddressBook ]===========================");
+ logger.info("=============================[ Initializing LoveBook ]===========================");
super.init();
AppParameters appParameters = AppParameters.parse(getParameters());
@@ -57,40 +62,53 @@ public void init() throws Exception {
UserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(config.getUserPrefsFilePath());
UserPrefs userPrefs = initPrefs(userPrefsStorage);
- AddressBookStorage addressBookStorage = new JsonAddressBookStorage(userPrefs.getAddressBookFilePath());
- storage = new StorageManager(addressBookStorage, userPrefsStorage);
-
+ LoveBookStorage loveBookStorage = new JsonLoveBookStorage(userPrefs.getLoveBookFilePath());
+ DatePrefsStorage datePrefsStorage = new JsonDatePrefsStorage(userPrefs.getDatePrefsFilePath());
+ storage = new StorageManager(loveBookStorage, userPrefsStorage, datePrefsStorage);
model = initModelManager(storage, userPrefs);
-
logic = new LogicManager(model, storage);
-
ui = new UiManager(logic);
}
/**
- * Returns a {@code ModelManager} with the data from {@code storage}'s address book and {@code userPrefs}.
- * The data from the sample address book will be used instead if {@code storage}'s address book is not found,
- * or an empty address book will be used instead if errors occur when reading {@code storage}'s address book.
+ * Returns a {@code ModelManager} with the data from {@code storage}'s LoveBook and {@code userPrefs}.
+ * The data from the sample LoveBook will be used instead if {@code storage}'s LoveBook is not found,
+ * or an empty LoveBook will be used instead if errors occur when reading {@code storage}'s LoveBook.
*/
private Model initModelManager(Storage storage, ReadOnlyUserPrefs userPrefs) {
- logger.info("Using data file : " + storage.getAddressBookFilePath());
+ logger.info("Using data file : " + storage.getLoveBookFilePath());
- Optional addressBookOptional;
- ReadOnlyAddressBook initialData;
+ Optional loveBookOptional;
+ Optional datePrefsOptional;
+ ReadOnlyLoveBook initialData;
+ ReadOnlyDatePrefs initialDatePrefs;
try {
- addressBookOptional = storage.readAddressBook();
- if (!addressBookOptional.isPresent()) {
- logger.info("Creating a new data file " + storage.getAddressBookFilePath()
- + " populated with a sample AddressBook.");
+ loveBookOptional = storage.readLoveBook();
+ if (!loveBookOptional.isPresent()) {
+ logger.info("Creating a new data file " + storage.getLoveBookFilePath()
+ + " populated with a sample LoveBook.");
}
- initialData = addressBookOptional.orElseGet(SampleDataUtil::getSampleAddressBook);
+ initialData = loveBookOptional.orElseGet(SampleDataUtil::getSampleLoveBook);
} catch (DataLoadingException e) {
- logger.warning("Data file at " + storage.getAddressBookFilePath() + " could not be loaded."
- + " Will be starting with an empty AddressBook.");
- initialData = new AddressBook();
+ logger.warning("Data file at " + storage.getLoveBookFilePath() + " could not be loaded."
+ + " Will be starting with an empty LoveBook.");
+ initialData = new LoveBook();
}
- return new ModelManager(initialData, userPrefs);
+ try {
+ datePrefsOptional = storage.readDatePrefs();
+ if (!datePrefsOptional.isPresent()) {
+ logger.info("Creating a new data file " + storage.getDatePrefsFilePath()
+ + " populated with a sample DatePrefs.");
+ }
+ initialDatePrefs = datePrefsOptional.orElseGet(SampleDatePrefUtil::getSamplePreferences);
+ } catch (DataLoadingException e) {
+ logger.warning("Data file at " + storage.getDatePrefsFilePath() + " could not be loaded."
+ + " Will be starting with empty preferences.");
+ initialDatePrefs = new DatePrefs();
+ }
+
+ return new ModelManager(initialData, userPrefs, initialDatePrefs);
}
private void initLogging(Config config) {
@@ -170,15 +188,17 @@ protected UserPrefs initPrefs(UserPrefsStorage storage) {
@Override
public void start(Stage primaryStage) {
- logger.info("Starting AddressBook " + MainApp.VERSION);
+ logger.info("Starting LoveBook " + MainApp.VERSION);
ui.start(primaryStage);
}
+
@Override
public void stop() {
- logger.info("============================ [ Stopping Address Book ] =============================");
+ logger.info("============================ [ Stopping LoveBook ] =============================");
try {
storage.saveUserPrefs(model.getUserPrefs());
+ storage.saveDatePrefs(model.getDatePrefs());
} catch (IOException e) {
logger.severe("Failed to save preferences " + StringUtil.getDetails(e));
}
diff --git a/src/main/java/seedu/address/commons/core/Config.java b/src/main/java/seedu/lovebook/commons/core/Config.java
similarity index 94%
rename from src/main/java/seedu/address/commons/core/Config.java
rename to src/main/java/seedu/lovebook/commons/core/Config.java
index 485f85a5e05..f4360bec1f3 100644
--- a/src/main/java/seedu/address/commons/core/Config.java
+++ b/src/main/java/seedu/lovebook/commons/core/Config.java
@@ -1,11 +1,11 @@
-package seedu.address.commons.core;
+package seedu.lovebook.commons.core;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.logging.Level;
-import seedu.address.commons.util.ToStringBuilder;
+import seedu.lovebook.commons.util.ToStringBuilder;
/**
* Config values used by the app
diff --git a/src/main/java/seedu/address/commons/core/GuiSettings.java b/src/main/java/seedu/lovebook/commons/core/GuiSettings.java
similarity index 96%
rename from src/main/java/seedu/address/commons/core/GuiSettings.java
rename to src/main/java/seedu/lovebook/commons/core/GuiSettings.java
index a97a86ee8d7..25fe73d9959 100644
--- a/src/main/java/seedu/address/commons/core/GuiSettings.java
+++ b/src/main/java/seedu/lovebook/commons/core/GuiSettings.java
@@ -1,10 +1,10 @@
-package seedu.address.commons.core;
+package seedu.lovebook.commons.core;
import java.awt.Point;
import java.io.Serializable;
import java.util.Objects;
-import seedu.address.commons.util.ToStringBuilder;
+import seedu.lovebook.commons.util.ToStringBuilder;
/**
* A Serializable class that contains the GUI settings.
diff --git a/src/main/java/seedu/address/commons/core/LogsCenter.java b/src/main/java/seedu/lovebook/commons/core/LogsCenter.java
similarity index 97%
rename from src/main/java/seedu/address/commons/core/LogsCenter.java
rename to src/main/java/seedu/lovebook/commons/core/LogsCenter.java
index 8cf8e15a0f0..040b98d3708 100644
--- a/src/main/java/seedu/address/commons/core/LogsCenter.java
+++ b/src/main/java/seedu/lovebook/commons/core/LogsCenter.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.core;
+package seedu.lovebook.commons.core;
import static java.util.Objects.requireNonNull;
@@ -20,7 +20,7 @@
public class LogsCenter {
private static final int MAX_FILE_COUNT = 5;
private static final int MAX_FILE_SIZE_IN_BYTES = (int) (Math.pow(2, 20) * 5); // 5MB
- private static final String LOG_FILE = "addressbook.log";
+ private static final String LOG_FILE = "LoveBook.log";
private static final Logger logger; // logger for this class
private static Logger baseLogger; // to be used as the parent of all other loggers created by this class.
private static Level currentLogLevel = Level.INFO;
diff --git a/src/main/java/seedu/address/commons/core/Version.java b/src/main/java/seedu/lovebook/commons/core/Version.java
similarity index 98%
rename from src/main/java/seedu/address/commons/core/Version.java
rename to src/main/java/seedu/lovebook/commons/core/Version.java
index 491d24559b4..2289ec1eb5e 100644
--- a/src/main/java/seedu/address/commons/core/Version.java
+++ b/src/main/java/seedu/lovebook/commons/core/Version.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.core;
+package seedu.lovebook.commons.core;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
diff --git a/src/main/java/seedu/address/commons/core/index/Index.java b/src/main/java/seedu/lovebook/commons/core/index/Index.java
similarity index 95%
rename from src/main/java/seedu/address/commons/core/index/Index.java
rename to src/main/java/seedu/lovebook/commons/core/index/Index.java
index dd170d8b68d..24028711de0 100644
--- a/src/main/java/seedu/address/commons/core/index/Index.java
+++ b/src/main/java/seedu/lovebook/commons/core/index/Index.java
@@ -1,6 +1,6 @@
-package seedu.address.commons.core.index;
+package seedu.lovebook.commons.core.index;
-import seedu.address.commons.util.ToStringBuilder;
+import seedu.lovebook.commons.util.ToStringBuilder;
/**
* Represents a zero-based or one-based index.
diff --git a/src/main/java/seedu/address/commons/exceptions/DataLoadingException.java b/src/main/java/seedu/lovebook/commons/exceptions/DataLoadingException.java
similarity index 82%
rename from src/main/java/seedu/address/commons/exceptions/DataLoadingException.java
rename to src/main/java/seedu/lovebook/commons/exceptions/DataLoadingException.java
index 9904ba47afe..652a01ea8a7 100644
--- a/src/main/java/seedu/address/commons/exceptions/DataLoadingException.java
+++ b/src/main/java/seedu/lovebook/commons/exceptions/DataLoadingException.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.exceptions;
+package seedu.lovebook.commons.exceptions;
/**
* Represents an error during loading of data from a file.
diff --git a/src/main/java/seedu/address/commons/exceptions/IllegalValueException.java b/src/main/java/seedu/lovebook/commons/exceptions/IllegalValueException.java
similarity index 92%
rename from src/main/java/seedu/address/commons/exceptions/IllegalValueException.java
rename to src/main/java/seedu/lovebook/commons/exceptions/IllegalValueException.java
index 19124db485c..1d0517c9340 100644
--- a/src/main/java/seedu/address/commons/exceptions/IllegalValueException.java
+++ b/src/main/java/seedu/lovebook/commons/exceptions/IllegalValueException.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.exceptions;
+package seedu.lovebook.commons.exceptions;
/**
* Signals that some given data does not fulfill some constraints.
diff --git a/src/main/java/seedu/address/commons/util/AppUtil.java b/src/main/java/seedu/lovebook/commons/util/AppUtil.java
similarity index 94%
rename from src/main/java/seedu/address/commons/util/AppUtil.java
rename to src/main/java/seedu/lovebook/commons/util/AppUtil.java
index 87aa89c0326..edbb835461e 100644
--- a/src/main/java/seedu/address/commons/util/AppUtil.java
+++ b/src/main/java/seedu/lovebook/commons/util/AppUtil.java
@@ -1,9 +1,9 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
import static java.util.Objects.requireNonNull;
import javafx.scene.image.Image;
-import seedu.address.MainApp;
+import seedu.lovebook.MainApp;
/**
* A container for App specific utility functions
diff --git a/src/main/java/seedu/address/commons/util/CollectionUtil.java b/src/main/java/seedu/lovebook/commons/util/CollectionUtil.java
similarity index 96%
rename from src/main/java/seedu/address/commons/util/CollectionUtil.java
rename to src/main/java/seedu/lovebook/commons/util/CollectionUtil.java
index eafe4dfd681..f515df0e7df 100644
--- a/src/main/java/seedu/address/commons/util/CollectionUtil.java
+++ b/src/main/java/seedu/lovebook/commons/util/CollectionUtil.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
import static java.util.Objects.requireNonNull;
diff --git a/src/main/java/seedu/address/commons/util/ConfigUtil.java b/src/main/java/seedu/lovebook/commons/util/ConfigUtil.java
similarity index 77%
rename from src/main/java/seedu/address/commons/util/ConfigUtil.java
rename to src/main/java/seedu/lovebook/commons/util/ConfigUtil.java
index 7b829c3c4cc..a800d194be0 100644
--- a/src/main/java/seedu/address/commons/util/ConfigUtil.java
+++ b/src/main/java/seedu/lovebook/commons/util/ConfigUtil.java
@@ -1,11 +1,11 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
-import seedu.address.commons.core.Config;
-import seedu.address.commons.exceptions.DataLoadingException;
+import seedu.lovebook.commons.core.Config;
+import seedu.lovebook.commons.exceptions.DataLoadingException;
/**
* A class for accessing the Config File.
diff --git a/src/main/java/seedu/address/commons/util/FileUtil.java b/src/main/java/seedu/lovebook/commons/util/FileUtil.java
similarity index 98%
rename from src/main/java/seedu/address/commons/util/FileUtil.java
rename to src/main/java/seedu/lovebook/commons/util/FileUtil.java
index b1e2767cdd9..afa929c3c58 100644
--- a/src/main/java/seedu/address/commons/util/FileUtil.java
+++ b/src/main/java/seedu/lovebook/commons/util/FileUtil.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
import java.io.IOException;
import java.nio.file.Files;
diff --git a/src/main/java/seedu/address/commons/util/JsonUtil.java b/src/main/java/seedu/lovebook/commons/util/JsonUtil.java
similarity index 97%
rename from src/main/java/seedu/address/commons/util/JsonUtil.java
rename to src/main/java/seedu/lovebook/commons/util/JsonUtil.java
index 100cb16c395..31fe7d83226 100644
--- a/src/main/java/seedu/address/commons/util/JsonUtil.java
+++ b/src/main/java/seedu/lovebook/commons/util/JsonUtil.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
import static java.util.Objects.requireNonNull;
@@ -20,8 +20,8 @@
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.exceptions.DataLoadingException;
+import seedu.lovebook.commons.core.LogsCenter;
+import seedu.lovebook.commons.exceptions.DataLoadingException;
/**
* Converts a Java object instance to JSON and vice versa
diff --git a/src/main/java/seedu/lovebook/commons/util/PredicatesUtil.java b/src/main/java/seedu/lovebook/commons/util/PredicatesUtil.java
new file mode 100644
index 00000000000..3fce198f11b
--- /dev/null
+++ b/src/main/java/seedu/lovebook/commons/util/PredicatesUtil.java
@@ -0,0 +1,36 @@
+package seedu.lovebook.commons.util;
+
+import java.util.ArrayList;
+import java.util.function.Predicate;
+
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.model.date.MetricContainsKeywordPredicate;
+
+/**
+ * A class that takes in an arraylist of predicates and package it into a predicate
+ */
+public class PredicatesUtil implements Predicate {
+ private ArrayList p;
+
+ /**
+ * Constructor for PredicatesUtil
+ * @param predicates
+ */
+ public PredicatesUtil(ArrayList predicates) {
+ this.p = predicates;
+ }
+
+ /**
+ * Test if the input argument satisfies all the predicates in the arraylist
+ * @param person the input argument
+ * @return
+ */
+ public boolean test(Date person) {
+ for (MetricContainsKeywordPredicate predicate : p) {
+ if (!predicate.test(person)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/seedu/address/commons/util/StringUtil.java b/src/main/java/seedu/lovebook/commons/util/StringUtil.java
similarity index 74%
rename from src/main/java/seedu/address/commons/util/StringUtil.java
rename to src/main/java/seedu/lovebook/commons/util/StringUtil.java
index 61cc8c9a1cb..254f83c4f52 100644
--- a/src/main/java/seedu/address/commons/util/StringUtil.java
+++ b/src/main/java/seedu/lovebook/commons/util/StringUtil.java
@@ -1,7 +1,7 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
+import static seedu.lovebook.commons.util.AppUtil.checkArgument;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -38,6 +38,26 @@ public static boolean containsWordIgnoreCase(String sentence, String word) {
.anyMatch(preppedWord::equalsIgnoreCase);
}
+ /**
+ * Returns true if the {@code sentence} contains the {@code multiWord}.
+ * @param sentence cannot be null
+ * @param multiWord cannot be null, cannot be empty
+ * @return
+ */
+
+ public static boolean containsMultiWordIgnoreCase(String sentence, String multiWord) {
+ requireNonNull(sentence);
+ requireNonNull(multiWord);
+
+ String preppedMultiWord = multiWord.trim();
+ checkArgument(!preppedMultiWord.isEmpty(), "Multi-word parameter cannot be empty");
+
+ String preppedSentence = sentence.toLowerCase();
+ String preppedMultiWordLowerCase = preppedMultiWord.toLowerCase();
+
+ return preppedSentence.contains(preppedMultiWordLowerCase);
+ }
+
/**
* Returns a detailed message of the t, including the stack trace.
*/
diff --git a/src/main/java/seedu/address/commons/util/ToStringBuilder.java b/src/main/java/seedu/lovebook/commons/util/ToStringBuilder.java
similarity index 97%
rename from src/main/java/seedu/address/commons/util/ToStringBuilder.java
rename to src/main/java/seedu/lovebook/commons/util/ToStringBuilder.java
index d979b926734..58e52db44a1 100644
--- a/src/main/java/seedu/address/commons/util/ToStringBuilder.java
+++ b/src/main/java/seedu/lovebook/commons/util/ToStringBuilder.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
/**
* Builds a string representation of an object that is suitable as the return value of {@link Object#toString()}.
diff --git a/src/main/java/seedu/address/logic/Logic.java b/src/main/java/seedu/lovebook/logic/Logic.java
similarity index 53%
rename from src/main/java/seedu/address/logic/Logic.java
rename to src/main/java/seedu/lovebook/logic/Logic.java
index 92cd8fa605a..2a97da3240a 100644
--- a/src/main/java/seedu/address/logic/Logic.java
+++ b/src/main/java/seedu/lovebook/logic/Logic.java
@@ -1,14 +1,14 @@
-package seedu.address.logic;
+package seedu.lovebook.logic;
import java.nio.file.Path;
import javafx.collections.ObservableList;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.logic.commands.CommandResult;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.person.Person;
+import seedu.lovebook.commons.core.GuiSettings;
+import seedu.lovebook.logic.commands.CommandResult;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+import seedu.lovebook.model.ReadOnlyLoveBook;
+import seedu.lovebook.model.date.Date;
/**
* API of the Logic component
@@ -24,19 +24,19 @@ public interface Logic {
CommandResult execute(String commandText) throws CommandException, ParseException;
/**
- * Returns the AddressBook.
+ * Returns the LoveBook.
*
- * @see seedu.address.model.Model#getAddressBook()
+ * @see seedu.lovebook.model.Model#getLoveBook()
*/
- ReadOnlyAddressBook getAddressBook();
+ ReadOnlyLoveBook getLoveBook();
- /** Returns an unmodifiable view of the filtered list of persons */
- ObservableList getFilteredPersonList();
+ /** Returns an unmodifiable view of the filtered list of dates */
+ ObservableList getFilteredPersonList();
/**
- * Returns the user prefs' address book file path.
+ * Returns the user prefs' LoveBook file path.
*/
- Path getAddressBookFilePath();
+ Path getLoveBookFilePath();
/**
* Returns the user prefs' GUI settings.
@@ -47,4 +47,6 @@ public interface Logic {
* Set the user prefs' GUI settings.
*/
void setGuiSettings(GuiSettings guiSettings);
+
+ String getWelcomeMessage();
}
diff --git a/src/main/java/seedu/address/logic/LogicManager.java b/src/main/java/seedu/lovebook/logic/LogicManager.java
similarity index 63%
rename from src/main/java/seedu/address/logic/LogicManager.java
rename to src/main/java/seedu/lovebook/logic/LogicManager.java
index 5aa3b91c7d0..0835a61ab56 100644
--- a/src/main/java/seedu/address/logic/LogicManager.java
+++ b/src/main/java/seedu/lovebook/logic/LogicManager.java
@@ -1,4 +1,4 @@
-package seedu.address.logic;
+package seedu.lovebook.logic;
import java.io.IOException;
import java.nio.file.AccessDeniedException;
@@ -6,17 +6,17 @@
import java.util.logging.Logger;
import javafx.collections.ObservableList;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.logic.commands.Command;
-import seedu.address.logic.commands.CommandResult;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.logic.parser.AddressBookParser;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.Model;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.person.Person;
-import seedu.address.storage.Storage;
+import seedu.lovebook.commons.core.GuiSettings;
+import seedu.lovebook.commons.core.LogsCenter;
+import seedu.lovebook.logic.commands.Command;
+import seedu.lovebook.logic.commands.CommandResult;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.logic.parser.LoveBookParser;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ReadOnlyLoveBook;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.storage.Storage;
/**
* The main LogicManager of the app.
@@ -31,7 +31,7 @@ public class LogicManager implements Logic {
private final Model model;
private final Storage storage;
- private final AddressBookParser addressBookParser;
+ private final LoveBookParser loveBookParser;
/**
* Constructs a {@code LogicManager} with the given {@code Model} and {@code Storage}.
@@ -39,7 +39,7 @@ public class LogicManager implements Logic {
public LogicManager(Model model, Storage storage) {
this.model = model;
this.storage = storage;
- addressBookParser = new AddressBookParser();
+ loveBookParser = new LoveBookParser();
}
@Override
@@ -47,11 +47,11 @@ public CommandResult execute(String commandText) throws CommandException, ParseE
logger.info("----------------[USER COMMAND][" + commandText + "]");
CommandResult commandResult;
- Command command = addressBookParser.parseCommand(commandText);
+ Command command = loveBookParser.parseCommand(commandText);
commandResult = command.execute(model);
try {
- storage.saveAddressBook(model.getAddressBook());
+ storage.saveLoveBook(model.getLoveBook());
} catch (AccessDeniedException e) {
throw new CommandException(String.format(FILE_OPS_PERMISSION_ERROR_FORMAT, e.getMessage()), e);
} catch (IOException ioe) {
@@ -62,18 +62,18 @@ public CommandResult execute(String commandText) throws CommandException, ParseE
}
@Override
- public ReadOnlyAddressBook getAddressBook() {
- return model.getAddressBook();
+ public ReadOnlyLoveBook getLoveBook() {
+ return model.getLoveBook();
}
@Override
- public ObservableList getFilteredPersonList() {
+ public ObservableList getFilteredPersonList() {
return model.getFilteredPersonList();
}
@Override
- public Path getAddressBookFilePath() {
- return model.getAddressBookFilePath();
+ public Path getLoveBookFilePath() {
+ return model.getLoveBookFilePath();
}
@Override
@@ -85,4 +85,9 @@ public GuiSettings getGuiSettings() {
public void setGuiSettings(GuiSettings guiSettings) {
model.setGuiSettings(guiSettings);
}
+ @Override
+ public String getWelcomeMessage() {
+ return model.getWelcomeMessage();
+ }
+
}
diff --git a/src/main/java/seedu/lovebook/logic/Messages.java b/src/main/java/seedu/lovebook/logic/Messages.java
new file mode 100644
index 00000000000..63511ec7a8b
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/Messages.java
@@ -0,0 +1,95 @@
+package seedu.lovebook.logic;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import seedu.lovebook.logic.commands.SetPrefCommand;
+import seedu.lovebook.logic.parser.Prefix;
+import seedu.lovebook.model.DatePrefs;
+import seedu.lovebook.model.date.Date;
+
+/**
+ * Container for user visible messages.
+ */
+public class Messages {
+
+ public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command";
+ public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s";
+ public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The date index provided is invalid";
+ public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d date(s) listed!";
+ public static final String MESSAGE_DUPLICATE_FIELDS =
+ "Multiple values specified for the following single-valued field(s): ";
+ public static final String WELCOME_MESSAGE = "Hey there, fabulous single!" + "\n"
+ + "Get ready to embark on an exciting journey with LoveBook to find your perfect match ❤︎₊ ⊹";
+ public static final String MESSAGE_RANDOM_PERSON_SUCCESS = "Here's a blind date for you!";
+ public static final String MESSAGE_NO_PERSONS = "There are no dates in your list!";
+ public static final String MESSAGE_SORTED = "Sorted!";
+
+ public static final String MESSAGE_INVALID_PREFIX = "Invalid prefix!";
+ public static final String MESSAGE_INVALID_SEQUENCE = "Invalid sequence!";
+
+ /**
+ * Returns an error message indicating the duplicate prefixes.
+ */
+ public static String getErrorMessageForDuplicatePrefixes(Prefix... duplicatePrefixes) {
+ assert duplicatePrefixes.length > 0;
+
+ Set duplicateFields =
+ Stream.of(duplicatePrefixes).map(Prefix::toString).collect(Collectors.toSet());
+
+ return MESSAGE_DUPLICATE_FIELDS + String.join(" ", duplicateFields);
+ }
+
+ /**
+ * Formats the {@code date} for display to the user.
+ */
+ public static String format(Date date) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(date.getName())
+ .append("; Age: ")
+ .append(date.getAge())
+ .append("; Gender: ")
+ .append(date.getGender())
+ .append("; Height: ")
+ .append(date.getHeight())
+ .append("; Income: ")
+ .append(date.getIncome())
+ .append("; Horoscope: ")
+ .append(date.getHoroscope());
+ return builder.toString();
+ }
+
+ /**
+ * Formats the {@code datePrefs} for display to the user.
+ */
+ public static String format(DatePrefs datePrefs) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("Age: ")
+ .append(datePrefs.getAge())
+ .append("; Height: ")
+ .append(datePrefs.getHeight())
+ .append("; Income: ")
+ .append(datePrefs.getIncome())
+ .append("; Horoscope: ")
+ .append(datePrefs.getHoroscope());
+ return builder.toString();
+ }
+
+ /**
+ * Formats the {@code datePrefs} for display to the user.
+ */
+ public static String format(SetPrefCommand.SetPreferenceDescriptor descriptor) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("Age: ")
+ .append(descriptor.getAge().get())
+ .append("; Height: ")
+ .append(descriptor.getHeight().get())
+ .append("; Income: ")
+ .append(descriptor.getIncome().get())
+ .append("; Horoscope: ")
+ .append(descriptor.getHoroscope().get());
+ return builder.toString();
+ }
+
+}
diff --git a/src/main/java/seedu/lovebook/logic/commands/AddCommand.java b/src/main/java/seedu/lovebook/logic/commands/AddCommand.java
new file mode 100644
index 00000000000..99ea926bea3
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/commands/AddCommand.java
@@ -0,0 +1,89 @@
+package seedu.lovebook.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_GENDER;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HOROSCOPE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_INCOME;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME;
+
+import java.util.Comparator;
+
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.date.Date;
+
+/**
+ * Adds a Date to the LoveBook.
+ */
+public class AddCommand extends Command {
+
+ public static final String COMMAND_WORD = "add";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a Date to the LoveBook. "
+ + "Parameters: "
+ + PREFIX_NAME + "NAME "
+ + PREFIX_AGE + "AGE "
+ + PREFIX_GENDER + "GENDER "
+ + PREFIX_HEIGHT + "HEIGHT "
+ + PREFIX_INCOME + "INCOME "
+ + PREFIX_HOROSCOPE + "HOROSCOPE "
+ + "Example: " + COMMAND_WORD + " "
+ + PREFIX_NAME + "John Doe "
+ + PREFIX_AGE + "21 "
+ + PREFIX_GENDER + "M "
+ + PREFIX_HEIGHT + "123 "
+ + PREFIX_INCOME + "3000 "
+ + PREFIX_HOROSCOPE + "Libra";
+
+ public static final String MESSAGE_SUCCESS = "New Date added: %1$s";
+ public static final String MESSAGE_DUPLICATE_PERSON = "This Date already exists in the LoveBook";
+
+ private final Date toAdd;
+
+ /**
+ * Creates an AddCommand to add the specified {@code Date}
+ */
+ public AddCommand(Date date) {
+ requireNonNull(date);
+ toAdd = date;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+
+ if (model.hasDate(toAdd)) {
+ throw new CommandException(MESSAGE_DUPLICATE_PERSON);
+ }
+
+ model.addDate(toAdd);
+ model.updateSortedDateList(Comparator.naturalOrder());
+ return new CommandResult(String.format(MESSAGE_SUCCESS, Messages.format(toAdd)));
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof AddCommand)) {
+ return false;
+ }
+
+ AddCommand otherAddCommand = (AddCommand) other;
+ return toAdd.equals(otherAddCommand.toAdd);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("toAdd", toAdd)
+ .toString();
+ }
+}
diff --git a/src/main/java/seedu/lovebook/logic/commands/BestMatchCommand.java b/src/main/java/seedu/lovebook/logic/commands/BestMatchCommand.java
new file mode 100644
index 00000000000..b3bad76479c
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/commands/BestMatchCommand.java
@@ -0,0 +1,22 @@
+package seedu.lovebook.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.model.Model;
+
+/**
+ * Finds the best match based on Date Preferences of the user.
+ */
+public class BestMatchCommand extends Command {
+ public static final String COMMAND_WORD = "bestMatch";
+
+ public static final String MESSAGE_SUCCESS = "Here's your best match!";
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ model.getBestDate();
+ return new CommandResult(MESSAGE_SUCCESS);
+ }
+
+}
diff --git a/src/main/java/seedu/lovebook/logic/commands/BlindDateCommand.java b/src/main/java/seedu/lovebook/logic/commands/BlindDateCommand.java
new file mode 100644
index 00000000000..9083b058c3e
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/commands/BlindDateCommand.java
@@ -0,0 +1,31 @@
+package seedu.lovebook.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.model.Model;
+/**
+ * Generates a random Date
+ * @author lynnlow175
+ */
+public class BlindDateCommand extends Command {
+ public static final String COMMAND_WORD = "blindDate";
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Generates a blind Date"
+ + "Example: " + COMMAND_WORD;
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ model.getBlindDate();
+ return new CommandResult(Messages.MESSAGE_RANDOM_PERSON_SUCCESS);
+ }
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ // instanceof handles nulls
+ return other instanceof BlindDateCommand;
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/ClearCommand.java b/src/main/java/seedu/lovebook/logic/commands/ClearCommand.java
similarity index 53%
rename from src/main/java/seedu/address/logic/commands/ClearCommand.java
rename to src/main/java/seedu/lovebook/logic/commands/ClearCommand.java
index 9c86b1fa6e4..807e8bbf91e 100644
--- a/src/main/java/seedu/address/logic/commands/ClearCommand.java
+++ b/src/main/java/seedu/lovebook/logic/commands/ClearCommand.java
@@ -1,23 +1,23 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
import static java.util.Objects.requireNonNull;
-import seedu.address.model.AddressBook;
-import seedu.address.model.Model;
+import seedu.lovebook.model.LoveBook;
+import seedu.lovebook.model.Model;
/**
- * Clears the address book.
+ * Clears the LoveBook.
*/
public class ClearCommand extends Command {
public static final String COMMAND_WORD = "clear";
- public static final String MESSAGE_SUCCESS = "Address book has been cleared!";
+ public static final String MESSAGE_SUCCESS = "LoveBook has been cleared!";
@Override
public CommandResult execute(Model model) {
requireNonNull(model);
- model.setAddressBook(new AddressBook());
+ model.setLoveBook(new LoveBook());
return new CommandResult(MESSAGE_SUCCESS);
}
}
diff --git a/src/main/java/seedu/address/logic/commands/Command.java b/src/main/java/seedu/lovebook/logic/commands/Command.java
similarity index 67%
rename from src/main/java/seedu/address/logic/commands/Command.java
rename to src/main/java/seedu/lovebook/logic/commands/Command.java
index 64f18992160..1369202a484 100644
--- a/src/main/java/seedu/address/logic/commands/Command.java
+++ b/src/main/java/seedu/lovebook/logic/commands/Command.java
@@ -1,7 +1,8 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.model.Model;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+import seedu.lovebook.model.Model;
/**
* Represents a command with hidden internal logic and the ability to be executed.
@@ -15,6 +16,6 @@ public abstract class Command {
* @return feedback message of the operation result for display
* @throws CommandException If an error occurs during command execution.
*/
- public abstract CommandResult execute(Model model) throws CommandException;
+ public abstract CommandResult execute(Model model) throws CommandException, ParseException;
}
diff --git a/src/main/java/seedu/address/logic/commands/CommandResult.java b/src/main/java/seedu/lovebook/logic/commands/CommandResult.java
similarity index 95%
rename from src/main/java/seedu/address/logic/commands/CommandResult.java
rename to src/main/java/seedu/lovebook/logic/commands/CommandResult.java
index 249b6072d0d..3a87cd4c8dd 100644
--- a/src/main/java/seedu/address/logic/commands/CommandResult.java
+++ b/src/main/java/seedu/lovebook/logic/commands/CommandResult.java
@@ -1,10 +1,10 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
import static java.util.Objects.requireNonNull;
import java.util.Objects;
-import seedu.address.commons.util.ToStringBuilder;
+import seedu.lovebook.commons.util.ToStringBuilder;
/**
* Represents the result of a command execution.
diff --git a/src/main/java/seedu/address/logic/commands/DeleteCommand.java b/src/main/java/seedu/lovebook/logic/commands/DeleteCommand.java
similarity index 65%
rename from src/main/java/seedu/address/logic/commands/DeleteCommand.java
rename to src/main/java/seedu/lovebook/logic/commands/DeleteCommand.java
index 1135ac19b74..f27616d3188 100644
--- a/src/main/java/seedu/address/logic/commands/DeleteCommand.java
+++ b/src/main/java/seedu/lovebook/logic/commands/DeleteCommand.java
@@ -1,29 +1,29 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
import static java.util.Objects.requireNonNull;
import java.util.List;
-import seedu.address.commons.core.index.Index;
-import seedu.address.commons.util.ToStringBuilder;
-import seedu.address.logic.Messages;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.model.Model;
-import seedu.address.model.person.Person;
+import seedu.lovebook.commons.core.index.Index;
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.date.Date;
/**
- * Deletes a person identified using it's displayed index from the address book.
+ * Deletes a date identified using it's displayed index from the LoveBook.
*/
public class DeleteCommand extends Command {
public static final String COMMAND_WORD = "delete";
public static final String MESSAGE_USAGE = COMMAND_WORD
- + ": Deletes the person identified by the index number used in the displayed person list.\n"
+ + ": Deletes the Date identified by the index number used in the displayed Date list.\n"
+ "Parameters: INDEX (must be a positive integer)\n"
+ "Example: " + COMMAND_WORD + " 1";
- public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s";
+ public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Date: %1$s";
private final Index targetIndex;
@@ -34,15 +34,15 @@ public DeleteCommand(Index targetIndex) {
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
- List lastShownList = model.getFilteredPersonList();
+ List lastShownList = model.getFilteredPersonList();
if (targetIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
}
- Person personToDelete = lastShownList.get(targetIndex.getZeroBased());
- model.deletePerson(personToDelete);
- return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, Messages.format(personToDelete)));
+ Date dateToDelete = lastShownList.get(targetIndex.getZeroBased());
+ model.deleteDate(dateToDelete);
+ return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, Messages.format(dateToDelete)));
}
@Override
diff --git a/src/main/java/seedu/lovebook/logic/commands/EditCommand.java b/src/main/java/seedu/lovebook/logic/commands/EditCommand.java
new file mode 100644
index 00000000000..929ec170194
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/commands/EditCommand.java
@@ -0,0 +1,257 @@
+package seedu.lovebook.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_GENDER;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HOROSCOPE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_INCOME;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME;
+import static seedu.lovebook.model.Model.PREDICATE_SHOW_ALL_PERSONS;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import seedu.lovebook.commons.core.index.Index;
+import seedu.lovebook.commons.util.CollectionUtil;
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.date.Age;
+import seedu.lovebook.model.date.Avatar;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.model.date.Gender;
+import seedu.lovebook.model.date.Height;
+import seedu.lovebook.model.date.Income;
+import seedu.lovebook.model.date.Name;
+import seedu.lovebook.model.date.horoscope.Horoscope;
+
+/**
+ * Edits the details of an existing Date in the LoveBook.
+ */
+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 Date identified "
+ + "by the index number used in the displayed Date list. "
+ + "Existing values will be overwritten by the input values.\n"
+ + "Parameters: INDEX (must be a positive integer) "
+ + "[" + PREFIX_NAME + "NAME] "
+ + "[" + PREFIX_AGE + "AGE] "
+ + "[" + PREFIX_GENDER + "GENDER] "
+ + "[" + PREFIX_HEIGHT + "HEIGHT] "
+ + "[" + PREFIX_INCOME + "INCOME] "
+ + "[" + PREFIX_HOROSCOPE + "HOROSCOPE] "
+ + "Example: " + COMMAND_WORD + " 1 "
+ + PREFIX_AGE + "24 "
+ + PREFIX_GENDER + "M "
+ + PREFIX_HEIGHT + "180 "
+ + PREFIX_INCOME + "3000 "
+ + PREFIX_HOROSCOPE + "SCORPIO ";
+
+ public static final String MESSAGE_EDIT_PERSON_SUCCESS = "Edited Date: %1$s";
+ public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided.";
+ public static final String MESSAGE_DUPLICATE_PERSON = "This Date already exists in the LoveBook.";
+
+ private final Index index;
+ private final EditPersonDescriptor editPersonDescriptor;
+
+ /**
+ * @param index of the date in the filtered date list to edit
+ * @param editPersonDescriptor details to edit the date with
+ */
+ public EditCommand(Index index, EditPersonDescriptor editPersonDescriptor) {
+ requireNonNull(index);
+ requireNonNull(editPersonDescriptor);
+
+ this.index = index;
+ this.editPersonDescriptor = new EditPersonDescriptor(editPersonDescriptor);
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ List lastShownList = model.getFilteredPersonList();
+
+ if (index.getZeroBased() >= lastShownList.size()) {
+ throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ }
+
+ Date dateToEdit = lastShownList.get(index.getZeroBased());
+ Date editedDate = createEditedPerson(dateToEdit, editPersonDescriptor);
+
+ if (!dateToEdit.isSamePerson(editedDate) && model.hasDate(editedDate)) {
+ throw new CommandException(MESSAGE_DUPLICATE_PERSON);
+ }
+
+ model.setDate(dateToEdit, editedDate);
+ model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
+ return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedDate)));
+ }
+
+ /**
+ * Creates and returns a {@code Date} with the details of {@code dateToEdit}
+ * edited with {@code editPersonDescriptor}.
+ */
+ private static Date createEditedPerson(Date dateToEdit, EditPersonDescriptor editPersonDescriptor) {
+ assert dateToEdit != null;
+
+ Name updatedName = editPersonDescriptor.getName().orElse(dateToEdit.getName());
+ Age updatedAge = editPersonDescriptor.getAge().orElse(dateToEdit.getAge());
+ Gender updatedGender = editPersonDescriptor.getGender().orElse(dateToEdit.getGender());
+ Height updatedHeight = editPersonDescriptor.getHeight().orElse(dateToEdit.getHeight());
+ Income updatedIncome = editPersonDescriptor.getIncome().orElse(dateToEdit.getIncome());
+ Horoscope updatedHoroscope = editPersonDescriptor.getHoroscope().orElse(dateToEdit.getHoroscope());
+
+ return new Date(updatedName, updatedAge, updatedGender, updatedHeight, updatedIncome, updatedHoroscope,
+ dateToEdit.getStar(), dateToEdit.getAvatar());
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof EditCommand)) {
+ return false;
+ }
+
+ EditCommand otherEditCommand = (EditCommand) other;
+ return index.equals(otherEditCommand.index)
+ && editPersonDescriptor.equals(otherEditCommand.editPersonDescriptor);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("index", index)
+ .add("editPersonDescriptor", editPersonDescriptor)
+ .toString();
+ }
+
+ /**
+ * Stores the details to edit the date with. Each non-empty field value will replace the
+ * corresponding field value of the date.
+ */
+ public static class EditPersonDescriptor {
+ private Name name;
+ private Age age;
+ private Gender gender;
+ private Height height;
+ private Income income;
+ private Horoscope horoscope;
+ private Avatar avatar;
+
+ public EditPersonDescriptor() {}
+
+ /**
+ * Copy constructor.
+ * A defensive copy of {@code tags} is used internally.
+ */
+ public EditPersonDescriptor(EditPersonDescriptor toCopy) {
+ setName(toCopy.name);
+ setAge(toCopy.age);
+ setGender(toCopy.gender);
+ setHeight(toCopy.height);
+ setIncome(toCopy.income);
+ setHoroscope(toCopy.horoscope);
+ setAvatar(toCopy.avatar);
+ }
+
+ /**
+ * Returns true if at least one field is edited.
+ */
+ public boolean isAnyFieldEdited() {
+ return CollectionUtil.isAnyNonNull(name, age, gender, height, income, horoscope);
+ }
+
+ public void setName(Name name) {
+ this.name = name;
+ }
+
+ public Optional getName() {
+ return Optional.ofNullable(name);
+ }
+
+ public void setAge(Age age) {
+ this.age = age;
+ }
+
+ public Optional getAge() {
+ return Optional.ofNullable(age);
+ }
+
+ public void setGender(Gender gender) {
+ this.gender = gender;
+ }
+
+ public Optional getGender() {
+ return Optional.ofNullable(gender);
+ }
+
+ public void setHeight(Height height) {
+ this.height = height;
+ }
+
+ public void setIncome(Income income) {
+ this.income = income;
+ }
+
+ public Optional getHeight() {
+ return Optional.ofNullable(height);
+ }
+
+ public Optional getIncome() {
+ return Optional.ofNullable(income);
+ }
+
+ public void setHoroscope(Horoscope horoscope) {
+ this.horoscope = horoscope;
+ }
+ public Optional getHoroscope() {
+ return Optional.ofNullable(horoscope);
+ }
+
+ public void setAvatar(Avatar avatar) {
+ this.avatar = avatar;
+ }
+ public Optional getAvatar() {
+ return Optional.ofNullable(avatar);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof EditPersonDescriptor)) {
+ return false;
+ }
+
+ EditPersonDescriptor otherEditPersonDescriptor = (EditPersonDescriptor) other;
+ return Objects.equals(name, otherEditPersonDescriptor.name)
+ && Objects.equals(age, otherEditPersonDescriptor.age)
+ && Objects.equals(gender, otherEditPersonDescriptor.gender)
+ && Objects.equals(height, otherEditPersonDescriptor.height)
+ && Objects.equals(income, otherEditPersonDescriptor.income);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("name", name)
+ .add("age", age)
+ .add("gender", gender)
+ .add("height", height)
+ .add("income", income)
+ .toString();
+ }
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/ExitCommand.java b/src/main/java/seedu/lovebook/logic/commands/ExitCommand.java
similarity index 75%
rename from src/main/java/seedu/address/logic/commands/ExitCommand.java
rename to src/main/java/seedu/lovebook/logic/commands/ExitCommand.java
index 3dd85a8ba90..b421d2d79e8 100644
--- a/src/main/java/seedu/address/logic/commands/ExitCommand.java
+++ b/src/main/java/seedu/lovebook/logic/commands/ExitCommand.java
@@ -1,6 +1,6 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
-import seedu.address.model.Model;
+import seedu.lovebook.model.Model;
/**
* Terminates the program.
@@ -9,7 +9,7 @@ public class ExitCommand extends Command {
public static final String COMMAND_WORD = "exit";
- public static final String MESSAGE_EXIT_ACKNOWLEDGEMENT = "Exiting Address Book as requested ...";
+ public static final String MESSAGE_EXIT_ACKNOWLEDGEMENT = "Exiting LoveBook as requested ...";
@Override
public CommandResult execute(Model model) {
diff --git a/src/main/java/seedu/lovebook/logic/commands/FilterCommand.java b/src/main/java/seedu/lovebook/logic/commands/FilterCommand.java
new file mode 100644
index 00000000000..52d4091b3ed
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/commands/FilterCommand.java
@@ -0,0 +1,65 @@
+package seedu.lovebook.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME;
+
+import java.util.ArrayList;
+
+import seedu.lovebook.commons.util.PredicatesUtil;
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.date.MetricContainsKeywordPredicate;
+
+
+/**
+ * Filter based on a specific metric and list the Dates whose metric contains the keyword.
+ * Keyword matching is case-insensitive.
+ * @author lynnlow175
+ *
+ */
+public class FilterCommand extends Command {
+
+ public static final String COMMAND_WORD = "filter";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all Dates whose specified metric contain any of "
+ + "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n"
+ + "Parameters: METRIC/ KEYWORD \n"
+ + "Parameter constraints: Metric limited to gender, name, age, height only\n"
+ + "Example: " + COMMAND_WORD + " " + PREFIX_NAME + " Bob (i.e. find Dates whose name equals Bob)";
+ private final ArrayList predicateList;
+
+
+ public FilterCommand(ArrayList predicateList) {
+ this.predicateList = predicateList;
+ }
+
+ @Override
+ public CommandResult execute(Model model) {
+ requireNonNull(model);
+ model.updateFilteredPersonList(new PredicatesUtil(predicateList));
+ return new CommandResult(
+ String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size()));
+ }
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof FilterCommand)) {
+ return false;
+ }
+
+ FilterCommand otherFilterCommand = (FilterCommand) other;
+ return predicateList.equals(otherFilterCommand.predicateList);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("predicateList", predicateList)
+ .toString();
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/FindCommand.java b/src/main/java/seedu/lovebook/logic/commands/FindCommand.java
similarity index 78%
rename from src/main/java/seedu/address/logic/commands/FindCommand.java
rename to src/main/java/seedu/lovebook/logic/commands/FindCommand.java
index 72b9eddd3a7..7fd1b2977fc 100644
--- a/src/main/java/seedu/address/logic/commands/FindCommand.java
+++ b/src/main/java/seedu/lovebook/logic/commands/FindCommand.java
@@ -1,21 +1,21 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
import static java.util.Objects.requireNonNull;
-import seedu.address.commons.util.ToStringBuilder;
-import seedu.address.logic.Messages;
-import seedu.address.model.Model;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.date.NameContainsKeywordsPredicate;
/**
- * Finds and lists all persons in address book whose name contains any of the argument keywords.
- * Keyword matching is case insensitive.
+ * Finds and lists all Dates in LoveBook whose name contains any of the argument keywords.
+ * Keyword matching is case-insensitive.
*/
public class FindCommand extends Command {
public static final String COMMAND_WORD = "find";
- public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons whose names contain any of "
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all Dates whose names contain any of "
+ "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n"
+ "Parameters: KEYWORD [MORE_KEYWORDS]...\n"
+ "Example: " + COMMAND_WORD + " alice bob charlie";
@@ -55,4 +55,5 @@ public String toString() {
.add("predicate", predicate)
.toString();
}
+
}
diff --git a/src/main/java/seedu/address/logic/commands/HelpCommand.java b/src/main/java/seedu/lovebook/logic/commands/HelpCommand.java
similarity index 87%
rename from src/main/java/seedu/address/logic/commands/HelpCommand.java
rename to src/main/java/seedu/lovebook/logic/commands/HelpCommand.java
index bf824f91bd0..fb2ecbb7ddd 100644
--- a/src/main/java/seedu/address/logic/commands/HelpCommand.java
+++ b/src/main/java/seedu/lovebook/logic/commands/HelpCommand.java
@@ -1,6 +1,6 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
-import seedu.address.model.Model;
+import seedu.lovebook.model.Model;
/**
* Format full help instructions for every command for display.
diff --git a/src/main/java/seedu/lovebook/logic/commands/ListCommand.java b/src/main/java/seedu/lovebook/logic/commands/ListCommand.java
new file mode 100644
index 00000000000..1f6c65ae6b2
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/commands/ListCommand.java
@@ -0,0 +1,28 @@
+package seedu.lovebook.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.model.Model.PREDICATE_SHOW_ALL_PERSONS;
+
+import java.util.Comparator;
+
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.date.Date;
+
+/**
+ * Lists all Dates in the LoveBook to the user.
+ */
+public class ListCommand extends Command {
+
+ public static final String COMMAND_WORD = "list";
+
+ public static final String MESSAGE_SUCCESS = "Listed all Dates";
+
+
+ @Override
+ public CommandResult execute(Model model) {
+ requireNonNull(model);
+ model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
+ model.updateSortedDateList(Comparator.naturalOrder());
+ return new CommandResult(MESSAGE_SUCCESS);
+ }
+}
diff --git a/src/main/java/seedu/lovebook/logic/commands/SetPrefCommand.java b/src/main/java/seedu/lovebook/logic/commands/SetPrefCommand.java
new file mode 100644
index 00000000000..78996a9907c
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/commands/SetPrefCommand.java
@@ -0,0 +1,215 @@
+package seedu.lovebook.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HOROSCOPE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_INCOME;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import seedu.lovebook.commons.util.CollectionUtil;
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.model.DatePrefs;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.date.Age;
+import seedu.lovebook.model.date.Height;
+import seedu.lovebook.model.date.Income;
+import seedu.lovebook.model.date.horoscope.Horoscope;
+
+/**
+ * Sets the Date Preference of the user in the LoveBook.
+ */
+public class SetPrefCommand extends Command {
+
+ public static final String COMMAND_WORD = "setP";
+
+ /**
+ * editP only for Age, Gender, Height, Income
+ */
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Sets Date Preference. "
+ + "Parameters: "
+ + PREFIX_AGE + "AGE "
+ + PREFIX_HEIGHT + "HEIGHT "
+ + PREFIX_INCOME + "INCOME "
+ + PREFIX_HOROSCOPE + "HOROSCOPE "
+ + "Example: " + COMMAND_WORD + " "
+ + PREFIX_AGE + "21 "
+ + PREFIX_HEIGHT + "180 "
+ + PREFIX_INCOME + "3000 "
+ + PREFIX_HOROSCOPE + "Scorpio ";
+
+ public static final String MESSAGE_EDIT_PREF_SUCCESS = "Updated Preferences: %1$s";
+ public static final String MESSAGE_NOT_EDITED = "At least one field to edit must be provided.\n"
+ + "Please try the following command format:\n"
+ + MESSAGE_USAGE;
+
+ private final SetPreferenceDescriptor setPreferenceDescriptor;
+
+ /**
+ * Creates a SetPrefCommand to edit the specified {@code DatePrefs}
+ * @param setPreferenceDescriptor details to edit the preferences with
+ */
+ public SetPrefCommand(SetPreferenceDescriptor setPreferenceDescriptor) {
+ requireNonNull(setPreferenceDescriptor);
+ if (!setPreferenceDescriptor.isAnyFieldEdited()) {
+ throw new RuntimeException("SetPreferenceDescriptor cannot have empty fields");
+ }
+ this.setPreferenceDescriptor = new SetPreferenceDescriptor(setPreferenceDescriptor);
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+
+ // OK to type cast this because I know this is ReadOnlyDatePrefs
+ DatePrefs datePrefsToEdit = (DatePrefs) model.getDatePrefs();
+ DatePrefs editedDatePreference = createEditedPreference(datePrefsToEdit, setPreferenceDescriptor);
+ model.setDatePrefs(editedDatePreference);
+ return new CommandResult(String.format(MESSAGE_EDIT_PREF_SUCCESS, Messages.format(editedDatePreference)));
+ }
+
+ /**
+ * Creates and returns a {@code DatePrefs} with the details of {@code datePrefsToEdit}
+ * edited with {@code setPreferenceDescriptor}.
+ * @param datePrefsToEdit the datePrefs to edit
+ * @param setPreferenceDescriptor the descriptor to edit the datePrefs with
+ */
+ private static DatePrefs createEditedPreference(
+ DatePrefs datePrefsToEdit, SetPreferenceDescriptor setPreferenceDescriptor) {
+ assert datePrefsToEdit != null;
+
+ Age updatedAge = setPreferenceDescriptor.getAge().orElse(datePrefsToEdit.getAge());
+ Height updatedHeight = setPreferenceDescriptor.getHeight().orElse(datePrefsToEdit.getHeight());
+ Income updatedIncome = setPreferenceDescriptor.getIncome().orElse(datePrefsToEdit.getIncome());
+ Horoscope updatedHoroscope = setPreferenceDescriptor.getHoroscope().orElse(datePrefsToEdit.getHoroscope());
+
+ return new DatePrefs(updatedAge, updatedHeight, updatedIncome, updatedHoroscope);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof SetPrefCommand)) {
+ return false;
+ }
+
+ SetPrefCommand otherSetPrefCommand = (SetPrefCommand) other;
+ return setPreferenceDescriptor.equals(otherSetPrefCommand.setPreferenceDescriptor);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("setPreferenceDescriptor", setPreferenceDescriptor)
+ .toString();
+ }
+
+ /**
+ * Stores the details to edit the preferences with. Each non-empty field value will replace the
+ * corresponding field value of the preference.
+ */
+ public static class SetPreferenceDescriptor {
+ private Age age;
+ private Height height;
+ private Income income;
+ private Horoscope horoscope;
+
+ public SetPreferenceDescriptor() {}
+
+ /**
+ * Constructor that accepts default values for each metric
+ */
+ public SetPreferenceDescriptor(Age age, Height height, Income income, Horoscope horoscope) {
+ setAge(age);
+ setHeight(height);
+ setIncome(income);
+ setHoroscope(horoscope);
+ }
+
+ /**
+ * Copy Constructor
+ * A defensive copy of {@code tags} is used internally.
+ */
+ public SetPreferenceDescriptor(SetPreferenceDescriptor toCopy) {
+ setAge(toCopy.age);
+ setHeight(toCopy.height);
+ setIncome(toCopy.income);
+ setHoroscope(toCopy.horoscope);
+ }
+
+ /**
+ * Returns true if at least one field is edited.
+ */
+ public boolean isAnyFieldEdited() {
+ return CollectionUtil.isAnyNonNull(age, height, income, horoscope);
+ }
+
+ public void setAge(Age age) {
+ this.age = age;
+ }
+
+ public Optional getAge() {
+ return Optional.ofNullable(age);
+ }
+
+ public void setHeight(Height height) {
+ this.height = height;
+ }
+
+ public Optional getHeight() {
+ return Optional.ofNullable(height);
+ }
+
+ public void setIncome(Income income) {
+ this.income = income;
+ }
+
+ public Optional getIncome() {
+ return Optional.ofNullable(income);
+ }
+
+ public void setHoroscope(Horoscope horoscope) {
+ this.horoscope = horoscope;
+ }
+
+ public Optional getHoroscope() {
+ return Optional.ofNullable(horoscope);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof SetPreferenceDescriptor)) {
+ return false;
+ }
+
+ SetPreferenceDescriptor otherEditPreferenceDescriptor = (SetPreferenceDescriptor) other;
+ return Objects.equals(age, otherEditPreferenceDescriptor.age)
+ && Objects.equals(height, otherEditPreferenceDescriptor.height)
+ && Objects.equals(income, otherEditPreferenceDescriptor.income)
+ && Objects.equals(horoscope, otherEditPreferenceDescriptor.horoscope);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("age", age)
+ .add("height", height)
+ .add("income", income)
+ .add("horoscope", horoscope)
+ .toString();
+ }
+ }
+}
diff --git a/src/main/java/seedu/lovebook/logic/commands/ShowPrefCommand.java b/src/main/java/seedu/lovebook/logic/commands/ShowPrefCommand.java
new file mode 100644
index 00000000000..7319e3479f7
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/commands/ShowPrefCommand.java
@@ -0,0 +1,24 @@
+package seedu.lovebook.logic.commands;
+
+import static java.util.Objects.requireNonNull;
+
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.model.DatePrefs;
+import seedu.lovebook.model.Model;
+
+/**
+ * Lists all date preferences to the user.
+ */
+public class ShowPrefCommand extends Command {
+ public static final String COMMAND_WORD = "showP";
+
+ public static final String MESSAGE_SUCCESS = "Here are your preferences: ";
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ DatePrefs prefs = model.getDatePrefs().getPreferences().get(0);
+ return new CommandResult(MESSAGE_SUCCESS + Messages.format(prefs));
+ }
+}
diff --git a/src/main/java/seedu/lovebook/logic/commands/SortCommand.java b/src/main/java/seedu/lovebook/logic/commands/SortCommand.java
new file mode 100644
index 00000000000..1079f9dcf63
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/commands/SortCommand.java
@@ -0,0 +1,114 @@
+package seedu.lovebook.logic.commands;
+
+import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_PREFIX;
+import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_SEQUENCE;
+import static seedu.lovebook.logic.Messages.MESSAGE_SORTED;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HOROSCOPE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_INCOME;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME;
+
+import java.util.Comparator;
+
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.logic.parser.Prefix;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.date.Date;
+
+/**
+ * Sorts all dates in LoveBook alphabetically or numerically.
+ * @author lynnlow175
+ */
+public class SortCommand extends Command {
+ public static final String COMMAND_WORD = "sort";
+ public static final String MESSAGE_USAGE = COMMAND_WORD + ": Sorts all dates in LoveBook alphabetically "
+ + "or numerically based on ONE metric.\n"
+ + "Parameters: name/ OR age/ OR height/ OR income/ OR horoscope/ + increasing OR decreasing" + "\n"
+ + "Example: " + COMMAND_WORD + " " + PREFIX_NAME + "increasing";
+ public static final String SEQUENCE_ASCENDING = "increasing";
+ public static final String SEQUENCE_DESCENDING = "decreasing";
+ public final Prefix prefix;
+ public final String sequence;
+
+ /**
+ * Creates a SortCommand to sort the specified {@code Date}
+ * @param prefix
+ * @param sequence
+ */
+ public SortCommand(Prefix prefix, String sequence) {
+ this.prefix = prefix;
+ this.sequence = sequence;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ Comparator c;
+ if (sequence.equals(SortCommand.SEQUENCE_ASCENDING)) {
+ if (prefix.equals(PREFIX_NAME)) {
+ c = Comparator.comparing(Date::getName);
+ } else if (prefix.equals(PREFIX_INCOME)) {
+ c = Comparator.comparing(Date::getIncome);
+ } else if (prefix.equals(PREFIX_AGE)) {
+ c = Comparator.comparing(Date::getAge);
+ } else if (prefix.equals(PREFIX_HEIGHT)) {
+ c = Comparator.comparing(Date::getHeight);
+ } else if (prefix.equals(PREFIX_HOROSCOPE)) {
+ c = Comparator.comparing(Date::getHoroscope);
+ } else {
+ throw new CommandException(MESSAGE_INVALID_PREFIX);
+ }
+ } else if (sequence.equals(SortCommand.SEQUENCE_DESCENDING)) {
+ if (prefix.equals(PREFIX_NAME)) {
+ c = Comparator.comparing(Date::getName).reversed();
+ } else if (prefix.equals(PREFIX_INCOME)) {
+ c = Comparator.comparing(Date::getIncome).reversed();
+ } else if (prefix.equals(PREFIX_AGE)) {
+ c = Comparator.comparing(Date::getAge).reversed();
+ } else if (prefix.equals(PREFIX_HEIGHT)) {
+ c = Comparator.comparing(Date::getHeight).reversed();
+ } else if (prefix.equals(PREFIX_HOROSCOPE)) {
+ c = Comparator.comparing(Date::getHoroscope).reversed();
+ } else {
+ throw new CommandException(MESSAGE_INVALID_PREFIX);
+ }
+ } else {
+ throw new CommandException(MESSAGE_INVALID_SEQUENCE);
+ }
+ model.updateSortedDateList(c);
+ return new CommandResult(MESSAGE_SORTED);
+ }
+
+ public Prefix getPrefix() {
+ return this.prefix;
+ }
+
+ public String getSequence() {
+ return this.sequence;
+ }
+
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof SortCommand)) {
+ return false;
+ }
+
+ SortCommand otherSortCommand = (SortCommand) other;
+ return prefix.equals((otherSortCommand.getPrefix())) && sequence.equals(otherSortCommand.getSequence());
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("prefix", prefix)
+ .add("sequence", sequence)
+ .toString();
+ }
+}
diff --git a/src/main/java/seedu/lovebook/logic/commands/StarCommand.java b/src/main/java/seedu/lovebook/logic/commands/StarCommand.java
new file mode 100644
index 00000000000..45e8883a400
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/commands/StarCommand.java
@@ -0,0 +1,78 @@
+package seedu.lovebook.logic.commands;
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.model.Model.PREDICATE_SHOW_ALL_PERSONS;
+
+import java.util.List;
+
+import seedu.lovebook.commons.core.index.Index;
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.model.date.Star;
+
+
+/**
+ * Star a Date identified using it's displayed index from the LoveBook.
+ */
+public class StarCommand extends Command {
+ public static final String COMMAND_WORD = "star";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD
+ + ": stars the date identified by the index number used in the displayed Date list.\n"
+ + "Parameters: INDEX (must be a positive integer)\n"
+ + "Example: " + COMMAND_WORD + " 1";
+
+ public static final String MESSAGE_STAR_PERSON_SUCCESS = "Starred Date: %1$s";
+
+ private final Index targetIndex;
+
+ public StarCommand(Index targetIndex) {
+ this.targetIndex = targetIndex;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ List lastShownList = model.getFilteredPersonList();
+
+ if (targetIndex.getZeroBased() >= lastShownList.size()) {
+ throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ }
+
+ Date dateToStar = lastShownList.get(targetIndex.getZeroBased());
+ if (dateToStar.getStar().isStarred.equals("true")) {
+ throw new CommandException("Date has already been starred");
+ }
+ Star star = new Star("true");
+ Date starredDate = new Date(dateToStar.getName(), dateToStar.getAge(), dateToStar.getGender(),
+ dateToStar.getHeight(), dateToStar.getIncome(),
+ dateToStar.getHoroscope(), star, dateToStar.getAvatar());
+ model.setDate(dateToStar, starredDate);
+ model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
+ return new CommandResult(String.format(MESSAGE_STAR_PERSON_SUCCESS, Messages.format(dateToStar)));
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof StarCommand)) {
+ return false;
+ }
+
+ StarCommand otherStarCommand = (StarCommand) other;
+ return targetIndex.equals(otherStarCommand.targetIndex);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("targetIndex", targetIndex)
+ .toString();
+ }
+}
diff --git a/src/main/java/seedu/lovebook/logic/commands/UnstarCommand.java b/src/main/java/seedu/lovebook/logic/commands/UnstarCommand.java
new file mode 100644
index 00000000000..342f9386849
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/commands/UnstarCommand.java
@@ -0,0 +1,78 @@
+package seedu.lovebook.logic.commands;
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.model.Model.PREDICATE_SHOW_ALL_PERSONS;
+
+import java.util.List;
+
+import seedu.lovebook.commons.core.index.Index;
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.model.date.Star;
+
+
+/**
+ * Star a Date identified using it's displayed index from the LoveBook.
+ */
+public class UnstarCommand extends Command {
+ public static final String COMMAND_WORD = "unstar";
+
+ public static final String MESSAGE_USAGE = COMMAND_WORD
+ + ": unstars the date identified by the index number used in the displayed Date list.\n"
+ + "Parameters: INDEX (must be a positive integer)\n"
+ + "Example: " + COMMAND_WORD + " 1";
+
+ public static final String MESSAGE_STAR_PERSON_SUCCESS = "Unstarred Date: %1$s";
+
+ private final Index targetIndex;
+
+ public UnstarCommand(Index targetIndex) {
+ this.targetIndex = targetIndex;
+ }
+
+ @Override
+ public CommandResult execute(Model model) throws CommandException {
+ requireNonNull(model);
+ List lastShownList = model.getFilteredPersonList();
+
+ if (targetIndex.getZeroBased() >= lastShownList.size()) {
+ throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
+ }
+
+ Date dateToStar = lastShownList.get(targetIndex.getZeroBased());
+ if (dateToStar.getStar().isStarred.equals("false")) {
+ throw new CommandException("Date has already been unstarred");
+ }
+ Star star = new Star("false");
+ Date starredDate = new Date(dateToStar.getName(), dateToStar.getAge(), dateToStar.getGender(),
+ dateToStar.getHeight(), dateToStar.getIncome(),
+ dateToStar.getHoroscope(), star, dateToStar.getAvatar());
+ model.setDate(dateToStar, starredDate);
+ model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
+ return new CommandResult(String.format(MESSAGE_STAR_PERSON_SUCCESS, Messages.format(dateToStar)));
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof UnstarCommand)) {
+ return false;
+ }
+
+ UnstarCommand otherUnstarCommand = (UnstarCommand) other;
+ return targetIndex.equals(otherUnstarCommand.targetIndex);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("targetIndex", targetIndex)
+ .toString();
+ }
+}
diff --git a/src/main/java/seedu/address/logic/commands/exceptions/CommandException.java b/src/main/java/seedu/lovebook/logic/commands/exceptions/CommandException.java
similarity index 89%
rename from src/main/java/seedu/address/logic/commands/exceptions/CommandException.java
rename to src/main/java/seedu/lovebook/logic/commands/exceptions/CommandException.java
index a16bd14f2cd..c45568d7147 100644
--- a/src/main/java/seedu/address/logic/commands/exceptions/CommandException.java
+++ b/src/main/java/seedu/lovebook/logic/commands/exceptions/CommandException.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.commands.exceptions;
+package seedu.lovebook.logic.commands.exceptions;
/**
* Represents an error which occurs during execution of a {@link Command}.
diff --git a/src/main/java/seedu/lovebook/logic/parser/AddCommandParser.java b/src/main/java/seedu/lovebook/logic/parser/AddCommandParser.java
new file mode 100644
index 00000000000..da1531877e7
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/parser/AddCommandParser.java
@@ -0,0 +1,66 @@
+package seedu.lovebook.logic.parser;
+
+import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_GENDER;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HOROSCOPE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_INCOME;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME;
+
+import java.util.stream.Stream;
+
+import seedu.lovebook.logic.commands.AddCommand;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+import seedu.lovebook.model.date.Age;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.model.date.Gender;
+import seedu.lovebook.model.date.Height;
+import seedu.lovebook.model.date.Income;
+import seedu.lovebook.model.date.Name;
+import seedu.lovebook.model.date.horoscope.Horoscope;
+
+
+/**
+ * Parses input arguments and creates a new AddCommand object
+ */
+public class AddCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the AddCommand
+ * and returns an AddCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public AddCommand parse(String args) throws ParseException {
+ ArgumentMultimap argMultimap =
+ ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_AGE, PREFIX_GENDER, PREFIX_HEIGHT, PREFIX_INCOME,
+ PREFIX_HOROSCOPE);
+
+ if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_HEIGHT, PREFIX_AGE, PREFIX_GENDER, PREFIX_INCOME,
+ PREFIX_HOROSCOPE) || !argMultimap.getPreamble().isEmpty()) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
+ }
+
+ argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_AGE, PREFIX_GENDER, PREFIX_HEIGHT, PREFIX_INCOME,
+ PREFIX_HOROSCOPE);
+ Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get());
+ Age age = ParserUtil.parseAge(argMultimap.getValue(PREFIX_AGE).get());
+ Gender gender = ParserUtil.parseGender(argMultimap.getValue(PREFIX_GENDER).get());
+ Height height = ParserUtil.parseHeight(argMultimap.getValue(PREFIX_HEIGHT).get());
+ Income income = ParserUtil.parseIncome(argMultimap.getValue(PREFIX_INCOME).get());
+ Horoscope horoscope = ParserUtil.parseHoroscope(argMultimap.getValue(PREFIX_HOROSCOPE).get());
+
+ Date date = new Date(name, age, gender, height, income, horoscope);
+
+ return new AddCommand(date);
+ }
+
+ /**
+ * Returns true if none of the prefixes contains empty {@code Optional} values in the given
+ * {@code ArgumentMultimap}.
+ */
+ private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
+ return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
+ }
+
+}
diff --git a/src/main/java/seedu/address/logic/parser/ArgumentMultimap.java b/src/main/java/seedu/lovebook/logic/parser/ArgumentMultimap.java
similarity index 95%
rename from src/main/java/seedu/address/logic/parser/ArgumentMultimap.java
rename to src/main/java/seedu/lovebook/logic/parser/ArgumentMultimap.java
index 21e26887a83..61b74a04b14 100644
--- a/src/main/java/seedu/address/logic/parser/ArgumentMultimap.java
+++ b/src/main/java/seedu/lovebook/logic/parser/ArgumentMultimap.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.parser;
+package seedu.lovebook.logic.parser;
import java.util.ArrayList;
import java.util.HashMap;
@@ -7,8 +7,8 @@
import java.util.Optional;
import java.util.stream.Stream;
-import seedu.address.logic.Messages;
-import seedu.address.logic.parser.exceptions.ParseException;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
/**
* Stores mapping of prefixes to their respective arguments.
diff --git a/src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java b/src/main/java/seedu/lovebook/logic/parser/ArgumentTokenizer.java
similarity index 99%
rename from src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java
rename to src/main/java/seedu/lovebook/logic/parser/ArgumentTokenizer.java
index 5c9aebfa488..124413e8c54 100644
--- a/src/main/java/seedu/address/logic/parser/ArgumentTokenizer.java
+++ b/src/main/java/seedu/lovebook/logic/parser/ArgumentTokenizer.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.parser;
+package seedu.lovebook.logic.parser;
import java.util.ArrayList;
import java.util.Arrays;
@@ -85,7 +85,6 @@ private static int findPrefixPosition(String argsString, String prefix, int from
* @return ArgumentMultimap object that maps prefixes to their arguments
*/
private static ArgumentMultimap extractArguments(String argsString, List prefixPositions) {
-
// Sort by start position
prefixPositions.sort((prefix1, prefix2) -> prefix1.getStartPosition() - prefix2.getStartPosition());
diff --git a/src/main/java/seedu/lovebook/logic/parser/CliSyntax.java b/src/main/java/seedu/lovebook/logic/parser/CliSyntax.java
new file mode 100644
index 00000000000..36c719bf43e
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/parser/CliSyntax.java
@@ -0,0 +1,16 @@
+package seedu.lovebook.logic.parser;
+
+/**
+ * Contains Command Line Interface (CLI) syntax definitions common to multiple commands
+ */
+public class CliSyntax {
+
+ /* Prefix definitions */
+ public static final Prefix PREFIX_NAME = new Prefix("name/");
+ public static final Prefix PREFIX_AGE = new Prefix("age/");
+ public static final Prefix PREFIX_GENDER = new Prefix("gender/");
+ public static final Prefix PREFIX_HEIGHT = new Prefix("height/");
+ public static final Prefix PREFIX_INCOME = new Prefix("income/");
+ public static final Prefix PREFIX_HOROSCOPE = new Prefix("horoscope/");
+
+}
diff --git a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java b/src/main/java/seedu/lovebook/logic/parser/DeleteCommandParser.java
similarity index 73%
rename from src/main/java/seedu/address/logic/parser/DeleteCommandParser.java
rename to src/main/java/seedu/lovebook/logic/parser/DeleteCommandParser.java
index 3527fe76a3e..999b5b5e320 100644
--- a/src/main/java/seedu/address/logic/parser/DeleteCommandParser.java
+++ b/src/main/java/seedu/lovebook/logic/parser/DeleteCommandParser.java
@@ -1,10 +1,10 @@
-package seedu.address.logic.parser;
+package seedu.lovebook.logic.parser;
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import seedu.address.commons.core.index.Index;
-import seedu.address.logic.commands.DeleteCommand;
-import seedu.address.logic.parser.exceptions.ParseException;
+import seedu.lovebook.commons.core.index.Index;
+import seedu.lovebook.logic.commands.DeleteCommand;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
/**
* Parses input arguments and creates a new DeleteCommand object
diff --git a/src/main/java/seedu/lovebook/logic/parser/EditCommandParser.java b/src/main/java/seedu/lovebook/logic/parser/EditCommandParser.java
new file mode 100644
index 00000000000..bf1774ea101
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/parser/EditCommandParser.java
@@ -0,0 +1,71 @@
+package seedu.lovebook.logic.parser;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_GENDER;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HOROSCOPE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_INCOME;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME;
+
+import seedu.lovebook.commons.core.index.Index;
+import seedu.lovebook.logic.commands.EditCommand;
+import seedu.lovebook.logic.commands.EditCommand.EditPersonDescriptor;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+
+/**
+ * Parses input arguments and creates a new EditCommand object
+ */
+public class EditCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the EditCommand
+ * and returns an EditCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public EditCommand parse(String args) throws ParseException {
+ requireNonNull(args);
+ ArgumentMultimap argMultimap =
+ ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_AGE, PREFIX_GENDER, PREFIX_HEIGHT, PREFIX_INCOME,
+ PREFIX_HOROSCOPE);
+
+ Index index;
+
+ try {
+ index = ParserUtil.parseIndex(argMultimap.getPreamble());
+ } catch (ParseException pe) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE), pe);
+ }
+
+ argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_AGE, PREFIX_GENDER, PREFIX_HEIGHT, PREFIX_INCOME,
+ PREFIX_HOROSCOPE);
+
+ EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor();
+
+ if (argMultimap.getValue(PREFIX_NAME).isPresent()) {
+ editPersonDescriptor.setName(ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get()));
+ }
+ if (argMultimap.getValue(PREFIX_AGE).isPresent()) {
+ editPersonDescriptor.setAge(ParserUtil.parseAge(argMultimap.getValue(PREFIX_AGE).get()));
+ }
+ if (argMultimap.getValue(PREFIX_GENDER).isPresent()) {
+ editPersonDescriptor.setGender(ParserUtil.parseGender(argMultimap.getValue(PREFIX_GENDER).get()));
+ }
+ if (argMultimap.getValue(PREFIX_HEIGHT).isPresent()) {
+ editPersonDescriptor.setHeight(ParserUtil.parseHeight(argMultimap.getValue(PREFIX_HEIGHT).get()));
+ }
+ if (argMultimap.getValue(PREFIX_INCOME).isPresent()) {
+ editPersonDescriptor.setIncome(ParserUtil.parseIncome(argMultimap.getValue(PREFIX_INCOME).get()));
+ }
+ if (argMultimap.getValue(PREFIX_HOROSCOPE).isPresent()) {
+ editPersonDescriptor.setHoroscope(ParserUtil.parseHoroscope(argMultimap.getValue(PREFIX_HOROSCOPE).get()));
+ }
+
+ if (!editPersonDescriptor.isAnyFieldEdited()) {
+ throw new ParseException(EditCommand.MESSAGE_NOT_EDITED);
+ }
+
+ return new EditCommand(index, editPersonDescriptor);
+ }
+}
diff --git a/src/main/java/seedu/lovebook/logic/parser/FilterCommandParser.java b/src/main/java/seedu/lovebook/logic/parser/FilterCommandParser.java
new file mode 100644
index 00000000000..1f1226be102
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/parser/FilterCommandParser.java
@@ -0,0 +1,76 @@
+package seedu.lovebook.logic.parser;
+
+import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_GENDER;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HOROSCOPE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_INCOME;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME;
+
+import java.util.ArrayList;
+
+import seedu.lovebook.logic.commands.FilterCommand;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+import seedu.lovebook.model.date.MetricContainsKeywordPredicate;
+
+/**
+ * Parses input arguments and creates a new FindCommand object
+ */
+public class FilterCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the FindCommand
+ * and returns a FindCommand object for execution.
+ *
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public FilterCommand parse(String args) throws ParseException {
+ String trimmedArgs = args.trim();
+ if (trimmedArgs.isEmpty()) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, FilterCommand.MESSAGE_USAGE));
+ }
+
+ ArgumentMultimap argMultimap =
+ ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_AGE, PREFIX_GENDER, PREFIX_HEIGHT, PREFIX_INCOME,
+ PREFIX_HOROSCOPE);
+ argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_AGE, PREFIX_GENDER, PREFIX_HEIGHT, PREFIX_INCOME,
+ PREFIX_HOROSCOPE);
+
+ String keyword = null;
+ Prefix metric = null;
+ ArrayList predicates = new ArrayList<>();
+
+ if (argMultimap.getValue(PREFIX_NAME).isPresent()) {
+ keyword = argMultimap.getValue(PREFIX_NAME).get();
+ metric = new Prefix("name/");
+ ParserUtil.parseName(keyword); // checks validity
+ predicates.add(new MetricContainsKeywordPredicate(keyword, metric));
+ }
+ if (argMultimap.getValue(PREFIX_AGE).isPresent()) {
+ keyword = argMultimap.getValue(PREFIX_AGE).get();
+ metric = new Prefix("age/");
+ ParserUtil.parseAge(keyword); // checks validity
+ predicates.add(new MetricContainsKeywordPredicate(keyword, metric));
+ }
+ if (argMultimap.getValue(PREFIX_GENDER).isPresent()) {
+ keyword = argMultimap.getValue(PREFIX_GENDER).get();
+ metric = new Prefix("gender/");
+ ParserUtil.parseGender(keyword); // checks validity
+ predicates.add(new MetricContainsKeywordPredicate(keyword, metric));
+ }
+ if (argMultimap.getValue(PREFIX_HEIGHT).isPresent()) {
+ keyword = argMultimap.getValue(PREFIX_HEIGHT).get();
+ metric = new Prefix("height/");
+ System.out.println("keyword: " + keyword);
+ ParserUtil.parseHeight(keyword); // checks validity
+ predicates.add(new MetricContainsKeywordPredicate(keyword, metric));
+ }
+ if (metric == null || keyword.isEmpty()) {
+ throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, FilterCommand.MESSAGE_USAGE));
+ }
+ return new FilterCommand(predicates);
+ }
+}
+
diff --git a/src/main/java/seedu/address/logic/parser/FindCommandParser.java b/src/main/java/seedu/lovebook/logic/parser/FindCommandParser.java
similarity index 74%
rename from src/main/java/seedu/address/logic/parser/FindCommandParser.java
rename to src/main/java/seedu/lovebook/logic/parser/FindCommandParser.java
index 2867bde857b..2a6015c3e9d 100644
--- a/src/main/java/seedu/address/logic/parser/FindCommandParser.java
+++ b/src/main/java/seedu/lovebook/logic/parser/FindCommandParser.java
@@ -1,12 +1,12 @@
-package seedu.address.logic.parser;
+package seedu.lovebook.logic.parser;
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import java.util.Arrays;
-import seedu.address.logic.commands.FindCommand;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
+import seedu.lovebook.logic.commands.FindCommand;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+import seedu.lovebook.model.date.NameContainsKeywordsPredicate;
/**
* Parses input arguments and creates a new FindCommand object
diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/lovebook/logic/parser/LoveBookParser.java
similarity index 52%
rename from src/main/java/seedu/address/logic/parser/AddressBookParser.java
rename to src/main/java/seedu/lovebook/logic/parser/LoveBookParser.java
index 3149ee07e0b..1f504f5ed3b 100644
--- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java
+++ b/src/main/java/seedu/lovebook/logic/parser/LoveBookParser.java
@@ -1,34 +1,42 @@
-package seedu.address.logic.parser;
+package seedu.lovebook.logic.parser;
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.Messages.MESSAGE_UNKNOWN_COMMAND;
+import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.lovebook.logic.Messages.MESSAGE_UNKNOWN_COMMAND;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.logic.commands.AddCommand;
-import seedu.address.logic.commands.ClearCommand;
-import seedu.address.logic.commands.Command;
-import seedu.address.logic.commands.DeleteCommand;
-import seedu.address.logic.commands.EditCommand;
-import seedu.address.logic.commands.ExitCommand;
-import seedu.address.logic.commands.FindCommand;
-import seedu.address.logic.commands.HelpCommand;
-import seedu.address.logic.commands.ListCommand;
-import seedu.address.logic.parser.exceptions.ParseException;
+import seedu.lovebook.commons.core.LogsCenter;
+import seedu.lovebook.logic.commands.AddCommand;
+import seedu.lovebook.logic.commands.BestMatchCommand;
+import seedu.lovebook.logic.commands.BlindDateCommand;
+import seedu.lovebook.logic.commands.ClearCommand;
+import seedu.lovebook.logic.commands.Command;
+import seedu.lovebook.logic.commands.DeleteCommand;
+import seedu.lovebook.logic.commands.EditCommand;
+import seedu.lovebook.logic.commands.ExitCommand;
+import seedu.lovebook.logic.commands.FilterCommand;
+import seedu.lovebook.logic.commands.FindCommand;
+import seedu.lovebook.logic.commands.HelpCommand;
+import seedu.lovebook.logic.commands.ListCommand;
+import seedu.lovebook.logic.commands.SetPrefCommand;
+import seedu.lovebook.logic.commands.ShowPrefCommand;
+import seedu.lovebook.logic.commands.SortCommand;
+import seedu.lovebook.logic.commands.StarCommand;
+import seedu.lovebook.logic.commands.UnstarCommand;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
/**
* Parses user input.
*/
-public class AddressBookParser {
+public class LoveBookParser {
/**
* Used for initial separation of command word and args.
*/
private static final Pattern BASIC_COMMAND_FORMAT = Pattern.compile("(?\\S+)(?.*)");
- private static final Logger logger = LogsCenter.getLogger(AddressBookParser.class);
+ private static final Logger logger = LogsCenter.getLogger(LoveBookParser.class);
/**
* Parses user input into command for execution.
@@ -50,7 +58,6 @@ public Command parseCommand(String userInput) throws ParseException {
// log messages such as the one below.
// Lower level log messages are used sparingly to minimize noise in the code.
logger.fine("Command word: " + commandWord + "; Arguments: " + arguments);
-
switch (commandWord) {
case AddCommand.COMMAND_WORD:
@@ -77,6 +84,30 @@ public Command parseCommand(String userInput) throws ParseException {
case HelpCommand.COMMAND_WORD:
return new HelpCommand();
+ case SetPrefCommand.COMMAND_WORD:
+ return new SetPrefCommandParser().parse(arguments);
+
+ case FilterCommand.COMMAND_WORD:
+ return new FilterCommandParser().parse(arguments);
+
+ case BlindDateCommand.COMMAND_WORD:
+ return new BlindDateCommand();
+
+ case ShowPrefCommand.COMMAND_WORD:
+ return new ShowPrefCommand();
+
+ case StarCommand.COMMAND_WORD:
+ return new StarCommandParser().parse(arguments);
+
+ case UnstarCommand.COMMAND_WORD:
+ return new UnstarCommandParser().parse(arguments);
+
+ case SortCommand.COMMAND_WORD:
+ return new SortCommandParser().parse(arguments);
+
+ case BestMatchCommand.COMMAND_WORD:
+ return new BestMatchCommand();
+
default:
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
diff --git a/src/main/java/seedu/address/logic/parser/Parser.java b/src/main/java/seedu/lovebook/logic/parser/Parser.java
similarity index 72%
rename from src/main/java/seedu/address/logic/parser/Parser.java
rename to src/main/java/seedu/lovebook/logic/parser/Parser.java
index d6551ad8e3f..f63b4a1335e 100644
--- a/src/main/java/seedu/address/logic/parser/Parser.java
+++ b/src/main/java/seedu/lovebook/logic/parser/Parser.java
@@ -1,7 +1,7 @@
-package seedu.address.logic.parser;
+package seedu.lovebook.logic.parser;
-import seedu.address.logic.commands.Command;
-import seedu.address.logic.parser.exceptions.ParseException;
+import seedu.lovebook.logic.commands.Command;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
/**
* Represents a Parser that is able to parse user input into a {@code Command} of type {@code T}.
diff --git a/src/main/java/seedu/lovebook/logic/parser/ParserUtil.java b/src/main/java/seedu/lovebook/logic/parser/ParserUtil.java
new file mode 100644
index 00000000000..b11b82597c9
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/parser/ParserUtil.java
@@ -0,0 +1,125 @@
+package seedu.lovebook.logic.parser;
+
+import static java.util.Objects.requireNonNull;
+
+import seedu.lovebook.commons.core.index.Index;
+import seedu.lovebook.commons.util.StringUtil;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+import seedu.lovebook.model.date.Age;
+import seedu.lovebook.model.date.Gender;
+import seedu.lovebook.model.date.Height;
+import seedu.lovebook.model.date.Income;
+import seedu.lovebook.model.date.Name;
+import seedu.lovebook.model.date.horoscope.Horoscope;
+
+/**
+ * Contains utility methods used for parsing strings in the various *Parser classes.
+ */
+public class ParserUtil {
+
+ public static final String MESSAGE_INVALID_INDEX = "Index is not a non-zero unsigned integer.";
+
+ /**
+ * Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing whitespaces will be
+ * trimmed.
+ * @throws ParseException if the specified index is invalid (not non-zero unsigned integer).
+ */
+ public static Index parseIndex(String oneBasedIndex) throws ParseException {
+ String trimmedIndex = oneBasedIndex.trim();
+ if (!StringUtil.isNonZeroUnsignedInteger(trimmedIndex)) {
+ throw new ParseException(MESSAGE_INVALID_INDEX);
+ }
+ return Index.fromOneBased(Integer.parseInt(trimmedIndex));
+ }
+
+ /**
+ * Parses a {@code String name} into a {@code Name}.
+ * Leading and trailing whitespaces will be trimmed.
+ *
+ * @throws ParseException if the given {@code name} is invalid.
+ */
+ public static Name parseName(String name) throws ParseException {
+ requireNonNull(name);
+ String trimmedName = name.trim();
+ if (!Name.isValidName(trimmedName)) {
+ throw new ParseException(Name.MESSAGE_CONSTRAINTS);
+ }
+ return new Name(trimmedName);
+ }
+
+ /**
+ * Parses a {@code String age} into a {@code Age}.
+ * Leading and trailing whitespaces will be trimmed.
+ *
+ * @throws ParseException if the given {@code age} is invalid.
+ */
+ public static Age parseAge(String age) throws ParseException {
+ requireNonNull(age);
+ String trimmedAge = age.trim();
+ if (!Age.isValidAge(trimmedAge)) {
+ throw new ParseException(Age.MESSAGE_CONSTRAINTS);
+ }
+ return new Age(trimmedAge);
+ }
+
+ /**
+ * Parses a {@code String gender} into an {@code Gender}.
+ * Leading and trailing whitespaces will be trimmed.
+ *
+ * @throws ParseException if the given {@code gender} is invalid.
+ */
+ public static Gender parseGender(String gender) throws ParseException {
+ requireNonNull(gender);
+ String trimmedGender = gender.trim();
+ if (!Gender.isValidGender(trimmedGender)) {
+ throw new ParseException(Gender.MESSAGE_CONSTRAINTS);
+ }
+ return new Gender(trimmedGender);
+ }
+
+ /**
+ * Parses a {@code String height} into an {@code Height}.
+ * Leading and trailing whitespaces will be trimmed.
+ *
+ * @throws ParseException if the given {@code height} is invalid.
+ */
+ public static Height parseHeight(String height) throws ParseException {
+ requireNonNull(height);
+ String trimmedAddress = height.trim();
+ System.out.println("height: " + trimmedAddress);
+ if (!Height.isValidHeight(trimmedAddress)) {
+ throw new ParseException(Height.MESSAGE_CONSTRAINTS);
+ }
+ return new Height(trimmedAddress);
+ }
+
+ /**
+ * Parses a {@code String income} into an {@code Income}.
+ * Leading and trailing whitespaces will be trimmed.
+ *
+ * @throws ParseException if the given {@code income} is invalid.
+ */
+ public static Income parseIncome(String income) throws ParseException {
+ requireNonNull(income);
+ String trimmedIncome = income.trim();
+ if (!Income.isValidIncome(trimmedIncome)) {
+ throw new ParseException(Income.MESSAGE_CONSTRAINTS);
+ }
+ return new Income(income);
+ }
+
+ /**
+ * Parses a {@code String horoscope} into an {@code Horoscope}.
+ * Leading and trailing whitespaces will be trimmed.
+ *
+ * @throws ParseException if the given {@code horoscope} is invalid.
+ */
+ public static Horoscope parseHoroscope(String horoscope) throws ParseException {
+ requireNonNull(horoscope);
+ String upperHoroscope = horoscope.trim().toUpperCase();
+ if (!Horoscope.isValidHoroscope(upperHoroscope)) {
+ throw new ParseException(Horoscope.MESSAGE_CONSTRAINTS);
+ }
+ return new Horoscope(upperHoroscope);
+ }
+}
diff --git a/src/main/java/seedu/address/logic/parser/Prefix.java b/src/main/java/seedu/lovebook/logic/parser/Prefix.java
similarity index 95%
rename from src/main/java/seedu/address/logic/parser/Prefix.java
rename to src/main/java/seedu/lovebook/logic/parser/Prefix.java
index 348b7686c8a..eaf2acb7da5 100644
--- a/src/main/java/seedu/address/logic/parser/Prefix.java
+++ b/src/main/java/seedu/lovebook/logic/parser/Prefix.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.parser;
+package seedu.lovebook.logic.parser;
/**
* A prefix that marks the beginning of an argument in an arguments string.
diff --git a/src/main/java/seedu/lovebook/logic/parser/SetPrefCommandParser.java b/src/main/java/seedu/lovebook/logic/parser/SetPrefCommandParser.java
new file mode 100644
index 00000000000..5e78600301f
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/parser/SetPrefCommandParser.java
@@ -0,0 +1,51 @@
+package seedu.lovebook.logic.parser;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HOROSCOPE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_INCOME;
+
+import seedu.lovebook.logic.commands.SetPrefCommand;
+import seedu.lovebook.logic.commands.SetPrefCommand.SetPreferenceDescriptor;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+
+/**
+ * Parses input arguments and creates a new SetPrefCommand object
+ */
+public class SetPrefCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the SetPrefCommand
+ * and returns an SetPrefCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public SetPrefCommand parse(String args) throws ParseException {
+ requireNonNull(args);
+ ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(
+ args, PREFIX_AGE, PREFIX_HEIGHT, PREFIX_INCOME, PREFIX_HOROSCOPE);
+ argMultimap.verifyNoDuplicatePrefixesFor(
+ PREFIX_AGE, PREFIX_HEIGHT, PREFIX_INCOME, PREFIX_HOROSCOPE);
+
+ SetPreferenceDescriptor setPrefDescriptor = new SetPreferenceDescriptor();
+
+ if (argMultimap.getValue(PREFIX_AGE).isPresent()) {
+ setPrefDescriptor.setAge(ParserUtil.parseAge(argMultimap.getValue(PREFIX_AGE).get()));
+ }
+ if (argMultimap.getValue(PREFIX_HEIGHT).isPresent()) {
+ setPrefDescriptor.setHeight(ParserUtil.parseHeight(argMultimap.getValue(PREFIX_HEIGHT).get()));
+ }
+ if (argMultimap.getValue(PREFIX_INCOME).isPresent()) {
+ setPrefDescriptor.setIncome(ParserUtil.parseIncome(argMultimap.getValue(PREFIX_INCOME).get()));
+ }
+ if (argMultimap.getValue(PREFIX_HOROSCOPE).isPresent()) {
+ setPrefDescriptor.setHoroscope(ParserUtil.parseHoroscope(argMultimap.getValue(PREFIX_HOROSCOPE).get()));
+ }
+
+ if (!setPrefDescriptor.isAnyFieldEdited()) {
+ throw new ParseException(SetPrefCommand.MESSAGE_NOT_EDITED);
+ }
+
+ return new SetPrefCommand(setPrefDescriptor);
+ }
+}
diff --git a/src/main/java/seedu/lovebook/logic/parser/SortCommandParser.java b/src/main/java/seedu/lovebook/logic/parser/SortCommandParser.java
new file mode 100644
index 00000000000..b0107ba3443
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/parser/SortCommandParser.java
@@ -0,0 +1,95 @@
+package seedu.lovebook.logic.parser;
+
+import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_GENDER;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HOROSCOPE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_INCOME;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME;
+
+import seedu.lovebook.logic.commands.SortCommand;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+
+/**
+ * Parses input arguments and creates a new SortCommand object
+ */
+
+public class SortCommandParser implements Parser {
+
+ /**
+ * Parses the given {@code String} of arguments in the context of the SortCommand
+ * and returns a SortCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public SortCommand parse(String args) throws ParseException {
+ String trimmedArgs = args.trim();
+ if (trimmedArgs.isEmpty()) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, SortCommand.MESSAGE_USAGE));
+ }
+ ArgumentMultimap argumentMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_AGE,
+ PREFIX_HEIGHT, PREFIX_INCOME, PREFIX_HOROSCOPE, PREFIX_GENDER);
+ argumentMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_AGE, PREFIX_HEIGHT, PREFIX_INCOME,
+ PREFIX_HOROSCOPE);
+
+ String sequence = null;
+ Prefix metric = null;
+ int prefixCount = 0;
+ if (argumentMultimap.getValue(PREFIX_NAME).isPresent()) {
+ prefixCount++;
+ sequence = argumentMultimap.getValue(PREFIX_NAME).get();
+ metric = new Prefix("name/");
+ }
+ if (argumentMultimap.getValue(PREFIX_AGE).isPresent()) {
+ prefixCount++;
+ sequence = argumentMultimap.getValue(PREFIX_AGE).get();
+ metric = new Prefix("age/");
+ }
+ if (argumentMultimap.getValue(PREFIX_HEIGHT).isPresent()) {
+ prefixCount++;
+ sequence = argumentMultimap.getValue(PREFIX_HEIGHT).get();
+ metric = new Prefix("height/");
+ }
+ if (argumentMultimap.getValue(PREFIX_INCOME).isPresent()) {
+ prefixCount++;
+ sequence = argumentMultimap.getValue(PREFIX_INCOME).get();
+ metric = new Prefix("income/");
+ }
+ if (argumentMultimap.getValue(PREFIX_HOROSCOPE).isPresent()) {
+ prefixCount++;
+ sequence = argumentMultimap.getValue(PREFIX_HOROSCOPE).get();
+ metric = new Prefix("horoscope/");
+ }
+ if (argumentMultimap.getValue(PREFIX_GENDER).isPresent()) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, SortCommand.MESSAGE_USAGE));
+ }
+ if (metric == null || !sequence.equals(SortCommand.SEQUENCE_ASCENDING)
+ && !sequence.equals(SortCommand.SEQUENCE_DESCENDING)) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, SortCommand.MESSAGE_USAGE));
+ }
+ System.out.println("prefixCount: " + prefixCount);
+ if (prefixCount > 1) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, SortCommand.MESSAGE_USAGE));
+ }
+ return new SortCommand(metric, sequence);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof SortCommandParser)) {
+ return false;
+ }
+
+ SortCommandParser otherSortCommandParser = (SortCommandParser) other;
+ return true;
+ }
+}
diff --git a/src/main/java/seedu/lovebook/logic/parser/StarCommandParser.java b/src/main/java/seedu/lovebook/logic/parser/StarCommandParser.java
new file mode 100644
index 00000000000..bddc52d0170
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/parser/StarCommandParser.java
@@ -0,0 +1,28 @@
+package seedu.lovebook.logic.parser;
+import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+
+import seedu.lovebook.commons.core.index.Index;
+import seedu.lovebook.logic.commands.StarCommand;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+
+
+
+/**
+ * Parses input arguments and creates a new starCommand object
+ */
+public class StarCommandParser implements Parser {
+ /**
+ * Parses the given {@code String} of arguments in the context of the StarCommand
+ * and returns a StarCommand object for execution.
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public StarCommand parse(String args) throws ParseException {
+ try {
+ Index index = ParserUtil.parseIndex(args);
+ return new StarCommand(index);
+ } catch (ParseException pe) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, StarCommand.MESSAGE_USAGE), pe);
+ }
+ }
+}
diff --git a/src/main/java/seedu/lovebook/logic/parser/UnstarCommandParser.java b/src/main/java/seedu/lovebook/logic/parser/UnstarCommandParser.java
new file mode 100644
index 00000000000..cc1702f7e63
--- /dev/null
+++ b/src/main/java/seedu/lovebook/logic/parser/UnstarCommandParser.java
@@ -0,0 +1,28 @@
+package seedu.lovebook.logic.parser;
+import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
+
+import seedu.lovebook.commons.core.index.Index;
+import seedu.lovebook.logic.commands.UnstarCommand;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+
+
+/**
+ * Parses input arguments and creates a new starCommand object
+ */
+public class UnstarCommandParser implements Parser {
+ /**
+ * Parses the given {@code String} of arguments in the context of the StarCommand
+ * and returns a StarCommand object for execution.
+ *
+ * @throws ParseException if the user input does not conform the expected format
+ */
+ public UnstarCommand parse(String args) throws ParseException {
+ try {
+ Index index = ParserUtil.parseIndex(args);
+ return new UnstarCommand(index);
+ } catch (ParseException pe) {
+ throw new ParseException(
+ String.format(MESSAGE_INVALID_COMMAND_FORMAT, UnstarCommand.MESSAGE_USAGE), pe);
+ }
+ }
+}
diff --git a/src/main/java/seedu/address/logic/parser/exceptions/ParseException.java b/src/main/java/seedu/lovebook/logic/parser/exceptions/ParseException.java
similarity index 72%
rename from src/main/java/seedu/address/logic/parser/exceptions/ParseException.java
rename to src/main/java/seedu/lovebook/logic/parser/exceptions/ParseException.java
index 158a1a54c1c..5f5b552b800 100644
--- a/src/main/java/seedu/address/logic/parser/exceptions/ParseException.java
+++ b/src/main/java/seedu/lovebook/logic/parser/exceptions/ParseException.java
@@ -1,6 +1,6 @@
-package seedu.address.logic.parser.exceptions;
+package seedu.lovebook.logic.parser.exceptions;
-import seedu.address.commons.exceptions.IllegalValueException;
+import seedu.lovebook.commons.exceptions.IllegalValueException;
/**
* Represents a parse error encountered by a parser.
diff --git a/src/main/java/seedu/lovebook/model/DatePrefs.java b/src/main/java/seedu/lovebook/model/DatePrefs.java
new file mode 100644
index 00000000000..a6be19377e7
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/DatePrefs.java
@@ -0,0 +1,127 @@
+package seedu.lovebook.model;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.model.date.Age;
+import seedu.lovebook.model.date.Height;
+import seedu.lovebook.model.date.Income;
+import seedu.lovebook.model.date.horoscope.Horoscope;
+
+/**
+ * Represents the preferences of the user for a date.
+ */
+public class DatePrefs implements ReadOnlyDatePrefs {
+ private Age age;
+ private Height height;
+ private Income income;
+ private Horoscope horoscope;
+
+ /**
+ * Creates a {@code DatePrefs} with default values.
+ */
+ public DatePrefs() {
+ this.age = new Age("21");
+ this.height = new Height("170");
+ this.income = new Income("10000");
+ this.horoscope = new Horoscope("ARIES");
+ }
+
+ /**
+ * Creates a {@code DatePrefs} with the given values.
+ */
+ public DatePrefs(Age age, Height height, Income income, Horoscope horoscope) {
+ this.age = age;
+ this.height = height;
+ this.income = income;
+ this.horoscope = horoscope;
+ }
+
+ /**
+ * Creates a {@code DatePrefs} with the given values.
+ */
+ public DatePrefs(ReadOnlyDatePrefs toBeCopied) {
+ this();
+ resetData(toBeCopied);
+ }
+
+ /**
+ * Resets the existing data of this {@code LoveBook} with {@code newData}.
+ */
+ public void resetData(ReadOnlyDatePrefs newData) {
+ requireNonNull(newData);
+
+ setPreferences(newData.getPreferences().get(0));
+ }
+
+ /**
+ * Replaces the contents of the date list with {@code dates}.
+ * {@code dates} must not contain duplicate dates.
+ */
+ public void setPreferences(DatePrefs prefs) {
+ this.age = prefs.age;
+ this.height = prefs.height;
+ this.income = prefs.income;
+ this.horoscope = prefs.horoscope;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof DatePrefs)) {
+ return false;
+ }
+
+ DatePrefs otherPrefs = (DatePrefs) other;
+ return this.age.equals(otherPrefs.age)
+ && this.height.equals(otherPrefs.height)
+ && this.income.equals(otherPrefs.income)
+ && this.horoscope.equals(otherPrefs.horoscope);
+ }
+
+ public Age getAge() {
+ return age;
+ }
+
+ public Height getHeight() {
+ return height;
+ }
+
+ public Income getIncome() {
+ return income;
+ }
+
+ public Horoscope getHoroscope() {
+ return horoscope;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.age, this.height, this.income, this.horoscope);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("age", age)
+ .add("height", height)
+ .add("income", income)
+ .add("horoscope", horoscope)
+ .toString();
+ }
+
+ @Override
+ public List getPreferences() {
+ List prefs = new ArrayList<>();
+ prefs.add(this);
+ return prefs;
+ }
+}
diff --git a/src/main/java/seedu/lovebook/model/LoveBook.java b/src/main/java/seedu/lovebook/model/LoveBook.java
new file mode 100644
index 00000000000..e597bb1395f
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/LoveBook.java
@@ -0,0 +1,129 @@
+package seedu.lovebook.model;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.List;
+
+import javafx.collections.ObservableList;
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.model.date.UniqueDateList;
+
+/**
+ * Wraps all data at the lovebook-book level
+ * Duplicates are not allowed (by .isSamePerson comparison)
+ */
+public class LoveBook implements ReadOnlyLoveBook {
+
+ private final UniqueDateList dates;
+
+ /*
+ * The 'unusual' code block below is a non-static initialization block, sometimes used to avoid duplication
+ * between constructors. See https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
+ *
+ * Note that non-static init blocks are not recommended to use. There are other ways to avoid duplication
+ * among constructors.
+ */
+ {
+ dates = new UniqueDateList();
+ }
+
+ public LoveBook() {}
+
+ /**
+ * Creates an LoveBook using the Persons in the {@code toBeCopied}
+ */
+ public LoveBook(ReadOnlyLoveBook toBeCopied) {
+ this();
+ resetData(toBeCopied);
+ }
+
+ //// list overwrite operations
+
+ /**
+ * Replaces the contents of the date list with {@code dates}.
+ * {@code dates} must not contain duplicate dates.
+ */
+ public void setPersons(List dates) {
+ this.dates.setPersons(dates);
+ }
+
+ /**
+ * Resets the existing data of this {@code LoveBook} with {@code newData}.
+ */
+ public void resetData(ReadOnlyLoveBook newData) {
+ requireNonNull(newData);
+ setPersons(newData.getPersonList());
+ }
+
+ //// date-level operations
+
+ /**
+ * Returns true if a date with the same identity as {@code date} exists in the LoveBook.
+ */
+ public boolean hasDate(Date date) {
+ requireNonNull(date);
+ return dates.contains(date);
+ }
+
+ /**
+ * Adds a date to the LoveBook.
+ * The date must not already exist in the LoveBook.
+ */
+ public void addDate(Date p) {
+ dates.add(p);
+ }
+
+ /**
+ * Replaces the given date {@code target} in the list with {@code editedDate}.
+ * {@code target} must exist in the LoveBook.
+ * The date identity of {@code editedDate} must not be the same as another existing date in the LoveBook.
+ */
+ public void setDate(Date target, Date editedDate) {
+ requireNonNull(editedDate);
+ dates.setDate(target, editedDate);
+ }
+
+ /**
+ * Removes {@code key} from this {@code LoveBook}.
+ * {@code key} must exist in the LoveBook.
+ */
+ public void removePerson(Date key) {
+ dates.remove(key);
+ }
+
+ //// util methods
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("dates", dates)
+ .toString();
+ }
+
+ @Override
+ public ObservableList getPersonList() {
+ return dates.asUnmodifiableObservableList();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof LoveBook)) {
+ return false;
+ }
+
+ LoveBook otherLoveBook = (LoveBook) other;
+ return dates.equals(otherLoveBook.dates);
+ }
+
+ @Override
+ public int hashCode() {
+ return dates.hashCode();
+ }
+
+}
diff --git a/src/main/java/seedu/lovebook/model/Model.java b/src/main/java/seedu/lovebook/model/Model.java
new file mode 100644
index 00000000000..b3125d22727
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/Model.java
@@ -0,0 +1,110 @@
+package seedu.lovebook.model;
+
+import java.nio.file.Path;
+import java.util.Comparator;
+import java.util.function.Predicate;
+
+import javafx.collections.ObservableList;
+import seedu.lovebook.commons.core.GuiSettings;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.model.date.Date;
+
+/**
+ * The API of the Model component.
+ */
+public interface Model {
+ /** {@code Predicate} that always evaluate to true */
+ Predicate PREDICATE_SHOW_ALL_PERSONS = unused -> true;
+
+ /**
+ * Replaces user prefs data with the data in {@code userPrefs}.
+ */
+ void setUserPrefs(ReadOnlyUserPrefs userPrefs);
+
+ /**
+ * Returns the user prefs.
+ */
+ ReadOnlyUserPrefs getUserPrefs();
+
+ /**
+ * Returns the user prefs' GUI settings.
+ */
+ GuiSettings getGuiSettings();
+
+ /**
+ * Sets the user prefs' GUI settings.
+ */
+ void setGuiSettings(GuiSettings guiSettings);
+
+ /**
+ * Returns the user prefs' LoveBook file path.
+ */
+ Path getLoveBookFilePath();
+
+ /**
+ * Sets the user prefs' LoveBook file path.
+ */
+ void setLoveBookFilePath(Path loveBookFilePath);
+
+ /**
+ * Replaces LoveBook data with the data in {@code LoveBook}.
+ */
+ void setLoveBook(ReadOnlyLoveBook loveBook);
+
+ /** Returns the LoveBook */
+ ReadOnlyLoveBook getLoveBook();
+
+ /**
+ * Returns true if a date with the same identity as {@code date} exists in the LoveBook.
+ */
+ boolean hasDate(Date date);
+
+ /**
+ * Deletes the given date.
+ * The date must exist in the LoveBook.
+ */
+ void deleteDate(Date target);
+
+ /**
+ * Adds the given date.
+ * {@code date} must not already exist in the LoveBook.
+ */
+ void addDate(Date date);
+
+ /**
+ * Replaces the given date {@code target} with {@code editedDate}.
+ * {@code target} must exist in the LoveBook.
+ * The date identity of {@code editedDate} must not be the same as another existing date in the LoveBook.
+ */
+ void setDate(Date target, Date editedDate);
+
+ /** Returns an unmodifiable view of the filtered date list */
+ ObservableList getFilteredPersonList();
+
+ /**
+ * Returns a random date from the date list.
+ */
+ public void getBlindDate() throws CommandException;
+
+ /**
+ * Updates the filter of the filtered date list to filter by the given {@code predicate}.
+ * @throws NullPointerException if {@code predicate} is null.
+ */
+ void updateFilteredPersonList(Predicate predicate);
+
+ /**
+ * Greets the user with a welcome message upon initial launch of app.
+ * Returns a String of welcome message.
+ */
+ String getWelcomeMessage();
+
+ Path getDatePrefsFilePath();
+
+ void setDatePrefsFilePath(Path datePrefsFilePath);
+
+ void setDatePrefs(ReadOnlyDatePrefs datePrefs);
+
+ ReadOnlyDatePrefs getDatePrefs();
+ void updateSortedDateList(Comparator comparator);
+ void getBestDate() throws CommandException;
+}
diff --git a/src/main/java/seedu/lovebook/model/ModelManager.java b/src/main/java/seedu/lovebook/model/ModelManager.java
new file mode 100644
index 00000000000..e47b6bb0355
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/ModelManager.java
@@ -0,0 +1,214 @@
+package seedu.lovebook.model;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.commons.util.CollectionUtil.requireAllNonNull;
+
+import java.nio.file.Path;
+import java.util.Comparator;
+import java.util.Random;
+import java.util.function.Predicate;
+import java.util.logging.Logger;
+
+import javafx.collections.ObservableList;
+import javafx.collections.transformation.FilteredList;
+import javafx.collections.transformation.SortedList;
+import seedu.lovebook.commons.core.GuiSettings;
+import seedu.lovebook.commons.core.LogsCenter;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.model.date.RandomPredicate;
+
+/**
+ * Represents the in-memory model of the LoveBook data.
+ */
+public class ModelManager implements Model {
+ private static final Logger logger = LogsCenter.getLogger(ModelManager.class);
+
+ private final LoveBook loveBook;
+ private final UserPrefs userPrefs;
+ private final DatePrefs datePrefs;
+ private final FilteredList filteredDates;
+ private SortedList sortedList;
+
+ /**
+ * Initializes a ModelManager with the given LoveBook and userPrefs.
+ */
+ public ModelManager(ReadOnlyLoveBook loveBook, ReadOnlyUserPrefs userPrefs, ReadOnlyDatePrefs datePrefs) {
+ requireAllNonNull(loveBook, userPrefs, datePrefs);
+
+ logger.fine("Initializing with LoveBook: " + loveBook + " and user prefs " + userPrefs
+ + " and date prefs " + datePrefs);
+
+ this.loveBook = new LoveBook(loveBook);
+ this.userPrefs = new UserPrefs(userPrefs);
+ this.datePrefs = new DatePrefs(datePrefs);
+ filteredDates = new FilteredList<>(this.loveBook.getPersonList());
+ sortedList = new SortedList<>(filteredDates);
+ }
+
+ public ModelManager() {
+ this(new LoveBook(), new UserPrefs(), new DatePrefs());
+ }
+
+ //=========== UserPrefs ==================================================================================
+
+ @Override
+ public void setUserPrefs(ReadOnlyUserPrefs userPrefs) {
+ requireNonNull(userPrefs);
+ this.userPrefs.resetData(userPrefs);
+ }
+
+ @Override
+ public ReadOnlyUserPrefs getUserPrefs() {
+ return userPrefs;
+ }
+
+ @Override
+ public GuiSettings getGuiSettings() {
+ return userPrefs.getGuiSettings();
+ }
+
+ @Override
+ public void setGuiSettings(GuiSettings guiSettings) {
+ requireNonNull(guiSettings);
+ userPrefs.setGuiSettings(guiSettings);
+ }
+
+ @Override
+ public Path getLoveBookFilePath() {
+ return userPrefs.getLoveBookFilePath();
+ }
+
+ @Override
+ public void setLoveBookFilePath(Path loveBookFilePath) {
+ requireNonNull(loveBookFilePath);
+ userPrefs.setLoveBookFilePath(loveBookFilePath);
+ }
+
+ //=========== LoveBook ================================================================================
+
+ @Override
+ public void setLoveBook(ReadOnlyLoveBook loveBook) {
+ this.loveBook.resetData(loveBook);
+ }
+
+ @Override
+ public ReadOnlyLoveBook getLoveBook() {
+ return loveBook;
+ }
+
+ @Override
+ public boolean hasDate(Date date) {
+ requireNonNull(date);
+ return loveBook.hasDate(date);
+ }
+
+ @Override
+ public void deleteDate(Date target) {
+ loveBook.removePerson(target);
+ }
+
+ @Override
+ public void addDate(Date date) {
+ loveBook.addDate(date);
+ updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
+ }
+
+ @Override
+ public void setDate(Date target, Date editedDate) {
+ requireAllNonNull(target, editedDate);
+
+ loveBook.setDate(target, editedDate);
+ }
+
+ //=========== Filtered Date List Accessors =============================================================
+
+ /**
+ * Returns an unmodifiable view of the list of {@code Date} backed by the internal list of
+ * {@code versionedLoveBook}
+ */
+ @Override
+ public ObservableList getFilteredPersonList() {
+ return sortedList;
+ }
+
+ /**
+ * Returns a random date from the date list.
+ */
+ public void getBlindDate() throws CommandException {
+ if (loveBook.getPersonList().size() == 0) {
+ throw new CommandException("Initialise list with dates before calling blindDates");
+ }
+ Random randomGenerator = new Random();
+ int randomIndex = randomGenerator.nextInt(loveBook.getPersonList().size());
+ Date person = loveBook.getPersonList().get(randomIndex);
+ updateFilteredPersonList(new RandomPredicate(person));
+ }
+
+ @Override
+ public void updateSortedDateList(Comparator comparator) {
+ requireNonNull(comparator);
+ sortedList.setComparator(comparator);
+ }
+ @Override
+ public void updateFilteredPersonList(Predicate predicate) {
+ requireNonNull(predicate);
+ filteredDates.setPredicate(predicate);
+ }
+
+ @Override
+ public String getWelcomeMessage() {
+ return Messages.WELCOME_MESSAGE;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof ModelManager)) {
+ return false;
+ }
+
+ ModelManager otherModelManager = (ModelManager) other;
+ return loveBook.equals(otherModelManager.loveBook)
+ && userPrefs.equals(otherModelManager.userPrefs)
+ && filteredDates.equals(otherModelManager.filteredDates);
+ }
+
+ //=========== DatePrefs ==================================================================================
+ @Override
+ public void setDatePrefs(ReadOnlyDatePrefs prefs) {
+ this.datePrefs.resetData(prefs);
+ }
+
+ @Override
+ public ReadOnlyDatePrefs getDatePrefs() {
+ return this.datePrefs.getPreferences().get(0);
+ }
+
+
+ @Override
+ public Path getDatePrefsFilePath() {
+ return this.userPrefs.getDatePrefsFilePath();
+ }
+
+ @Override
+ public void setDatePrefsFilePath(Path datePrefsFilePath) {
+ this.userPrefs.setDatePrefsFilePath(datePrefsFilePath);
+ }
+
+ @Override
+ public void getBestDate() throws CommandException {
+ if (loveBook.getPersonList().size() == 0) {
+ throw new CommandException("Initialise list with dates before calling bestMatch");
+ }
+ ObservableList dateList = loveBook.getPersonList();
+ Date bestDate = dateList.stream().max(Comparator.comparing(date -> date.getScore(this.datePrefs))).orElse(null);
+ filteredDates.setPredicate(date -> date.equals(bestDate));
+ }
+
+}
diff --git a/src/main/java/seedu/lovebook/model/ReadOnlyDatePrefs.java b/src/main/java/seedu/lovebook/model/ReadOnlyDatePrefs.java
new file mode 100644
index 00000000000..cc383d64277
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/ReadOnlyDatePrefs.java
@@ -0,0 +1,10 @@
+package seedu.lovebook.model;
+
+import java.util.List;
+
+/**
+ * Unmodifiable view of date preferences.
+ */
+public interface ReadOnlyDatePrefs {
+ List getPreferences();
+}
diff --git a/src/main/java/seedu/lovebook/model/ReadOnlyLoveBook.java b/src/main/java/seedu/lovebook/model/ReadOnlyLoveBook.java
new file mode 100644
index 00000000000..b45e0b4c45d
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/ReadOnlyLoveBook.java
@@ -0,0 +1,17 @@
+package seedu.lovebook.model;
+
+import javafx.collections.ObservableList;
+import seedu.lovebook.model.date.Date;
+
+/**
+ * Unmodifiable view of the LoveBook.
+ */
+public interface ReadOnlyLoveBook {
+
+ /**
+ * Returns an unmodifiable view of the dates list.
+ * This list will not contain any duplicate dates.
+ */
+ ObservableList getPersonList();
+
+}
diff --git a/src/main/java/seedu/address/model/ReadOnlyUserPrefs.java b/src/main/java/seedu/lovebook/model/ReadOnlyUserPrefs.java
similarity index 57%
rename from src/main/java/seedu/address/model/ReadOnlyUserPrefs.java
rename to src/main/java/seedu/lovebook/model/ReadOnlyUserPrefs.java
index befd58a4c73..34ec73dc1e4 100644
--- a/src/main/java/seedu/address/model/ReadOnlyUserPrefs.java
+++ b/src/main/java/seedu/lovebook/model/ReadOnlyUserPrefs.java
@@ -1,8 +1,8 @@
-package seedu.address.model;
+package seedu.lovebook.model;
import java.nio.file.Path;
-import seedu.address.commons.core.GuiSettings;
+import seedu.lovebook.commons.core.GuiSettings;
/**
* Unmodifiable view of user prefs.
@@ -11,6 +11,6 @@ public interface ReadOnlyUserPrefs {
GuiSettings getGuiSettings();
- Path getAddressBookFilePath();
+ Path getLoveBookFilePath();
}
diff --git a/src/main/java/seedu/address/model/UserPrefs.java b/src/main/java/seedu/lovebook/model/UserPrefs.java
similarity index 63%
rename from src/main/java/seedu/address/model/UserPrefs.java
rename to src/main/java/seedu/lovebook/model/UserPrefs.java
index 6be655fb4c7..f7130db9e39 100644
--- a/src/main/java/seedu/address/model/UserPrefs.java
+++ b/src/main/java/seedu/lovebook/model/UserPrefs.java
@@ -1,4 +1,4 @@
-package seedu.address.model;
+package seedu.lovebook.model;
import static java.util.Objects.requireNonNull;
@@ -6,7 +6,7 @@
import java.nio.file.Paths;
import java.util.Objects;
-import seedu.address.commons.core.GuiSettings;
+import seedu.lovebook.commons.core.GuiSettings;
/**
* Represents User's preferences.
@@ -14,7 +14,8 @@
public class UserPrefs implements ReadOnlyUserPrefs {
private GuiSettings guiSettings = new GuiSettings();
- private Path addressBookFilePath = Paths.get("data" , "addressbook.json");
+ private Path loveBookFilePath = Paths.get("data" , "LoveBook.json");
+ private Path datePrefsFilePath = Paths.get("data", "Preferences.json");
/**
* Creates a {@code UserPrefs} with default values.
@@ -35,7 +36,7 @@ public UserPrefs(ReadOnlyUserPrefs userPrefs) {
public void resetData(ReadOnlyUserPrefs newUserPrefs) {
requireNonNull(newUserPrefs);
setGuiSettings(newUserPrefs.getGuiSettings());
- setAddressBookFilePath(newUserPrefs.getAddressBookFilePath());
+ setLoveBookFilePath(newUserPrefs.getLoveBookFilePath());
}
public GuiSettings getGuiSettings() {
@@ -47,13 +48,22 @@ public void setGuiSettings(GuiSettings guiSettings) {
this.guiSettings = guiSettings;
}
- public Path getAddressBookFilePath() {
- return addressBookFilePath;
+ public Path getLoveBookFilePath() {
+ return loveBookFilePath;
}
- public void setAddressBookFilePath(Path addressBookFilePath) {
- requireNonNull(addressBookFilePath);
- this.addressBookFilePath = addressBookFilePath;
+ public Path getDatePrefsFilePath() {
+ return datePrefsFilePath;
+ }
+
+ public void setLoveBookFilePath(Path loveBookFilePath) {
+ requireNonNull(loveBookFilePath);
+ this.loveBookFilePath = loveBookFilePath;
+ }
+
+ public void setDatePrefsFilePath(Path datePrefsFilePath) {
+ requireNonNull(datePrefsFilePath);
+ this.datePrefsFilePath = datePrefsFilePath;
}
@Override
@@ -69,19 +79,19 @@ public boolean equals(Object other) {
UserPrefs otherUserPrefs = (UserPrefs) other;
return guiSettings.equals(otherUserPrefs.guiSettings)
- && addressBookFilePath.equals(otherUserPrefs.addressBookFilePath);
+ && loveBookFilePath.equals(otherUserPrefs.loveBookFilePath);
}
@Override
public int hashCode() {
- return Objects.hash(guiSettings, addressBookFilePath);
+ return Objects.hash(guiSettings, loveBookFilePath);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Gui Settings : " + guiSettings);
- sb.append("\nLocal data file location : " + addressBookFilePath);
+ sb.append("\nLocal data file location : " + loveBookFilePath);
return sb.toString();
}
diff --git a/src/main/java/seedu/lovebook/model/date/Age.java b/src/main/java/seedu/lovebook/model/date/Age.java
new file mode 100644
index 00000000000..5b435b67b66
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/Age.java
@@ -0,0 +1,70 @@
+package seedu.lovebook.model.date;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.commons.util.AppUtil.checkArgument;
+
+/**
+ * Represents a Date's age in the lovebook.
+ * Guarantees: immutable; is valid as declared in {@link #isValidAge(String)}
+ */
+public class Age implements Comparable {
+ public static final String MESSAGE_CONSTRAINTS =
+ "Age should only contain positive numbers in the range 18-150 years.";
+ public static final String VALIDATION_REGEX = "^(1[89]|[2-9][0-9]|1[0-4][0-9]|150)$"; // 18-150 Age Accepted
+ public final String value;
+
+ /**
+ * Constructs a {@code Age}.
+ *
+ * @param age A valid age.
+ */
+ public Age(String age) {
+ requireNonNull(age);
+ checkArgument(isValidAge(age), MESSAGE_CONSTRAINTS);
+ value = age;
+ }
+
+ /**
+ * Returns true if a given string is a valid age.
+ */
+ public static boolean isValidAge(String test) {
+ return test.matches(VALIDATION_REGEX);
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof Age)) {
+ return false;
+ }
+
+ Age otherAge = (Age) other;
+ return value.equals(otherAge.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public int compareTo(Age o) {
+ int thisAge = Integer.parseInt(this.toString());
+ int otherAge = Integer.parseInt(o.toString());
+ if (thisAge > otherAge) {
+ return 1;
+ } else if (thisAge < otherAge) {
+ return -1;
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/seedu/lovebook/model/date/Avatar.java b/src/main/java/seedu/lovebook/model/date/Avatar.java
new file mode 100644
index 00000000000..45ea48edce4
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/Avatar.java
@@ -0,0 +1,76 @@
+package seedu.lovebook.model.date;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.commons.util.AppUtil.checkArgument;
+
+/**
+ * Represents a Date's avatar in the lovebook.
+ * Guarantees: immutable; is always valid
+ */
+public class Avatar {
+ public static final String MESSAGE_CONSTRAINTS = "Avatar should only contain numbers from 1 to 9.";
+ private static final int LOWER_BOUND = 1;
+ private static final int UPPER_BOUND = 10;
+
+ public final String value;
+
+ /**
+ * Constructor for the avatar class
+ * @param value the avatar number
+ */
+ public Avatar(String value) {
+ requireNonNull(value);
+ checkArgument(isValidAvatar(value), MESSAGE_CONSTRAINTS);
+ this.value = value;
+ }
+
+ /**
+ * Constructor for the avatar class with a random number
+ */
+ public Avatar() {
+ value = String.valueOf((int) (Math.random() * (UPPER_BOUND - LOWER_BOUND)) + LOWER_BOUND);
+ }
+
+ /**
+ * Returns the avatar number
+ * @return the avatar number
+ */
+ public String getAvatarNumber() {
+ return value;
+ }
+
+ /**
+ * Returns true if the avatar number is valid.
+ */
+ public static boolean isValidAvatar(String avatar) {
+ requireNonNull(avatar);
+
+ int avatarNumber = Integer.parseInt(avatar);
+ return avatarNumber >= LOWER_BOUND && avatarNumber < UPPER_BOUND;
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof Avatar)) {
+ return false;
+ }
+
+ Avatar otherAvatar = (Avatar) other;
+ return value.equals(otherAvatar.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+}
diff --git a/src/main/java/seedu/lovebook/model/date/Date.java b/src/main/java/seedu/lovebook/model/date/Date.java
new file mode 100644
index 00000000000..6c63ce4bd4e
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/Date.java
@@ -0,0 +1,221 @@
+package seedu.lovebook.model.date;
+
+import static seedu.lovebook.commons.util.CollectionUtil.requireAllNonNull;
+
+import java.util.Objects;
+
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.model.DatePrefs;
+import seedu.lovebook.model.date.horoscope.Horoscope;
+
+/**
+ * Represents a Date in the lovebook.
+ * Guarantees: details are present and not null, field values are validated, immutable.
+ */
+public class Date implements Comparable {
+
+ // Identity fields
+ private final Name name;
+ private final Age age;
+ private final Gender gender;
+
+ // Data fields
+ private final Height height;
+ private final Income income;
+ private final Horoscope horoscope;
+ private final Star star;
+ private final Avatar avatar;
+
+ /**
+ * Every field must be present and not null.
+ */
+ public Date(Name name, Age age, Gender gender, Height height, Income income, Horoscope horoscope) {
+ requireAllNonNull(name, age, gender, height);
+ this.name = name;
+ this.age = age;
+ this.gender = gender;
+ this.height = height;
+ this.income = income;
+ this.horoscope = horoscope;
+ this.star = new Star("false");
+ this.avatar = new Avatar();
+ }
+
+ /**
+ * Constructor for setting the value of star
+ */
+ public Date(Name name, Age age, Gender gender, Height height, Income income, Horoscope horoscope, Star star) {
+ requireAllNonNull(name, age, gender, height);
+ this.name = name;
+ this.age = age;
+ this.gender = gender;
+ this.height = height;
+ this.income = income;
+ this.horoscope = horoscope;
+ this.star = star;
+ this.avatar = new Avatar();
+ }
+
+ /**
+ * Constructor for setting the value of avatar without initialising star
+ */
+ public Date(Name name, Age age, Gender gender, Height height, Income income, Horoscope horoscope,
+ Avatar avatar) {
+ requireAllNonNull(name, age, gender, height);
+ this.name = name;
+ this.age = age;
+ this.gender = gender;
+ this.height = height;
+ this.income = income;
+ this.horoscope = horoscope;
+ this.star = new Star("false");
+ this.avatar = avatar;
+ }
+
+ /**
+ * Constructor for setting the value of avatar
+ */
+ public Date(Name name, Age age, Gender gender, Height height, Income income, Horoscope horoscope, Star star,
+ Avatar avatar) {
+ requireAllNonNull(name, age, gender, height);
+ this.name = name;
+ this.age = age;
+ this.gender = gender;
+ this.height = height;
+ this.income = income;
+ this.horoscope = horoscope;
+ this.star = star;
+ this.avatar = avatar;
+ }
+
+ public Name getName() {
+ return name;
+ }
+
+ public Age getAge() {
+ return age;
+ }
+
+ public Gender getGender() {
+ return gender;
+ }
+
+ public Height getHeight() {
+ return height;
+ }
+
+ public Income getIncome() {
+ return income;
+ }
+
+ public Horoscope getHoroscope() {
+ return horoscope;
+ }
+
+ public Star getStar() {
+ return star;
+ }
+
+ public Avatar getAvatar() {
+ return avatar;
+ }
+
+ /**
+ * Returns true if both dates have the same name.
+ * This defines a weaker notion of equality between two dates.
+ */
+ public boolean isSamePerson(Date otherDate) {
+ if (otherDate == this) {
+ return true;
+ }
+
+ return otherDate != null
+ && otherDate.getName().equals(getName());
+ }
+
+ /**
+ * Returns the score of the date based on how well it mactches the user preferences.
+ *
+ * @param prefs User's date preferences
+ * @return the score of the date based on how it matches user preferences.
+ */
+ public int getScore(DatePrefs prefs) {
+ int score = 0;
+ //height
+ int heightDiff = Integer.parseInt(prefs.getHeight().value)
+ - Integer.parseInt(this.height.value);
+ if (heightDiff < 0) {
+ score += Math.max(0, 10 + heightDiff);
+ } else {
+ score += Math.max(0, 10 - heightDiff);
+ }
+ //age
+ int ageDiff = Integer.parseInt(prefs.getAge().value)
+ - Integer.parseInt(this.age.value);
+ if (ageDiff < 0) {
+ score += Math.max(0, 10 + ageDiff * 2);
+ } else {
+ score += Math.max(0, 10 - ageDiff * 2);
+ }
+ //horoscope
+ if (this.horoscope.equals(prefs.getHoroscope())) {
+ score += 10;
+ }
+ //income
+ int incomeDiff = Integer.parseInt(prefs.getIncome().value)
+ - Integer.parseInt(this.income.value);
+ if (incomeDiff < 0) {
+ score += Math.max(0, 10 + incomeDiff / 250);
+ } else {
+ score += Math.max(0, 10 - incomeDiff / 250);
+ }
+ return score;
+ }
+
+ /**
+ * Returns true if both dates have the same identity and data fields.
+ * This defines a stronger notion of equality between two dates.
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof Date)) {
+ return false;
+ }
+
+ Date otherDate = (Date) other;
+ return name.equals(otherDate.name)
+ && age.equals(otherDate.age)
+ && gender.equals(otherDate.gender)
+ && height.equals(otherDate.height)
+ && income.equals(otherDate.income)
+ && horoscope.equals(otherDate.horoscope);
+ }
+
+ @Override
+ public int hashCode() {
+ // use this method for custom fields hashing instead of implementing :your own
+ return Objects.hash(name, age, gender, height, income, horoscope, avatar);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this)
+ .add("name", name)
+ .add("age", age)
+ .add("gender", gender)
+ .add("height", height)
+ .add("income", income)
+ .add("horoscope", horoscope)
+ .toString();
+ }
+
+ @Override
+ public int compareTo(Date o) {
+ return this.getName().toString().toLowerCase().compareTo(o.getName().toString().toLowerCase());
+ }
+}
diff --git a/src/main/java/seedu/lovebook/model/date/Gender.java b/src/main/java/seedu/lovebook/model/date/Gender.java
new file mode 100644
index 00000000000..747649c96ab
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/Gender.java
@@ -0,0 +1,57 @@
+package seedu.lovebook.model.date;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.commons.util.AppUtil.checkArgument;
+
+/**
+ * Represents the date's gender in the lovebook.
+ */
+public class Gender {
+ public static final String MESSAGE_CONSTRAINTS =
+ "Gender should be a single character, either M or F";
+ public static final String VALIDATION_REGEX = "[MF]{1}";
+ public final String value;
+
+ /**
+ * Constructs a {@code Age}.
+ *
+ * @param gender A valid gender.
+ */
+ public Gender(String gender) {
+ requireNonNull(gender);
+ checkArgument(isValidGender(gender), MESSAGE_CONSTRAINTS);
+ value = gender;
+ }
+
+ /**
+ * Returns true if a given string is a valid gender.
+ */
+ public static boolean isValidGender(String test) {
+ return test.matches(VALIDATION_REGEX);
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof Gender)) {
+ return false;
+ }
+
+ Gender otherAge = (Gender) other;
+ return value.equals(otherAge.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+}
diff --git a/src/main/java/seedu/lovebook/model/date/Height.java b/src/main/java/seedu/lovebook/model/date/Height.java
new file mode 100644
index 00000000000..5f291c07bae
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/Height.java
@@ -0,0 +1,76 @@
+package seedu.lovebook.model.date;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.commons.util.AppUtil.checkArgument;
+
+/**
+ * Represents a Date's lovebook in the lovebook.
+ * Guarantees: immutable; is valid as declared in {@link #isValidHeight(String)}
+ */
+public class Height implements Comparable {
+
+ public static final String MESSAGE_CONSTRAINTS = "Height can take any values between 1 and 250cm";
+
+ /*
+ * The first character of the Height must not be a whitespace,
+ * otherwise " " (a blank string) becomes a valid input.
+ */
+ public static final String VALIDATION_REGEX = "^(1\\d{2}|2[0-4]\\d|250)$";
+
+ public final String value;
+
+ /**
+ * Constructs an {@code Height}.
+ *
+ * @param height A valid lovebook.
+ */
+ public Height(String height) {
+ requireNonNull(height);
+ checkArgument(isValidHeight(height), MESSAGE_CONSTRAINTS);
+ value = height;
+ }
+
+ /**
+ * Returns true if a given string is a valid gender.
+ */
+ public static boolean isValidHeight(String test) {
+ return test.matches(VALIDATION_REGEX);
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof Height)) {
+ return false;
+ }
+
+ Height otherHeight = (Height) other;
+ return value.equals(otherHeight.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public int compareTo(Height o) {
+ int thisHeight = Integer.parseInt(this.toString());
+ int otherHeight = Integer.parseInt(o.toString());
+ if (thisHeight > otherHeight) {
+ return 1;
+ } else if (thisHeight < otherHeight) {
+ return -1;
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/seedu/lovebook/model/date/Income.java b/src/main/java/seedu/lovebook/model/date/Income.java
new file mode 100644
index 00000000000..5d1ccb8008b
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/Income.java
@@ -0,0 +1,78 @@
+package seedu.lovebook.model.date;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.commons.util.AppUtil.checkArgument;
+
+/**
+ * Represents the date's income in the LoveBook.
+ */
+public class Income implements Comparable {
+
+ public static final String MESSAGE_CONSTRAINTS = "Income can only take on positive integer values, "
+ + "less than or equal"
+ + " to a million"
+ + ", and it should not be blank";
+
+ /*
+ * The first character of the LoveBook must not be a whitespace,
+ * otherwise " " (a blank string) becomes a valid input.
+ */
+ public static final String VALIDATION_REGEX = "^([1-9]\\d{0,5}|[1-9]\\d{0,5}|1000000)$";
+
+ public final String value;
+
+ /**
+ * Constructs an {@code Income}.
+ *
+ * @param income A valid income that is a positive integer.
+ */
+ public Income(String income) {
+ requireNonNull(income);
+ checkArgument(isValidIncome(income), MESSAGE_CONSTRAINTS);
+ value = income;
+ }
+
+ /**
+ * Returns true if a given string is a valid income
+ */
+ public static boolean isValidIncome(String test) {
+ return test.matches(VALIDATION_REGEX);
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof Income)) {
+ return false;
+ }
+
+ Income otherIncome = (Income) other;
+ return value.equals(otherIncome.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public int compareTo(Income o) {
+ long thisIncome = Long.parseLong(this.toString());
+ long otherIncome = Long.parseLong(o.toString());
+ if (thisIncome > otherIncome) {
+ return 1;
+ } else if (thisIncome < otherIncome) {
+ return -1;
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/seedu/lovebook/model/date/MetricContainsKeywordPredicate.java b/src/main/java/seedu/lovebook/model/date/MetricContainsKeywordPredicate.java
new file mode 100644
index 00000000000..d9f14af9089
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/MetricContainsKeywordPredicate.java
@@ -0,0 +1,67 @@
+package seedu.lovebook.model.date;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_GENDER;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME;
+
+import java.util.function.Predicate;
+
+import seedu.lovebook.commons.util.StringUtil;
+import seedu.lovebook.commons.util.ToStringBuilder;
+import seedu.lovebook.logic.parser.Prefix;
+
+/**
+ * Tests that a {@code Date}'s {@code Name} matches any of the keywords given.
+ */
+public class MetricContainsKeywordPredicate implements Predicate {
+ private final String keyword;
+ private final Prefix metric;
+ /**
+ * Constructor that initialises the String keyword and Prefix metric
+ */
+ public MetricContainsKeywordPredicate(String keyword, Prefix metric) {
+ this.keyword = keyword;
+ this.metric = metric;
+ }
+
+ @Override
+ public boolean test(Date date) {
+ requireNonNull(date);
+ if (metric.equals(PREFIX_NAME)) {
+ return StringUtil.containsMultiWordIgnoreCase(date.getName().fullName, keyword);
+ }
+ if (metric.equals(PREFIX_AGE)) {
+ return StringUtil.containsWordIgnoreCase(date.getAge().value, keyword);
+ }
+ if (metric.equals(PREFIX_GENDER)) {
+ return StringUtil.containsWordIgnoreCase(date.getGender().value, keyword);
+ }
+ if (metric.equals(PREFIX_HEIGHT)) {
+ return StringUtil.containsWordIgnoreCase(date.getHeight().value, keyword);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof MetricContainsKeywordPredicate)) {
+ return false;
+ }
+
+ MetricContainsKeywordPredicate otherMetricContainsKeywordsPredicate = (MetricContainsKeywordPredicate) other;
+ return keyword.equals(otherMetricContainsKeywordsPredicate.keyword);
+ }
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).add("keyword", keyword).add("prefix", metric)
+ .toString();
+ }
+}
diff --git a/src/main/java/seedu/address/model/person/Name.java b/src/main/java/seedu/lovebook/model/date/Name.java
similarity index 77%
rename from src/main/java/seedu/address/model/person/Name.java
rename to src/main/java/seedu/lovebook/model/date/Name.java
index 173f15b9b00..d37c9a774af 100644
--- a/src/main/java/seedu/address/model/person/Name.java
+++ b/src/main/java/seedu/lovebook/model/date/Name.java
@@ -1,19 +1,19 @@
-package seedu.address.model.person;
+package seedu.lovebook.model.date;
import static java.util.Objects.requireNonNull;
-import static seedu.address.commons.util.AppUtil.checkArgument;
+import static seedu.lovebook.commons.util.AppUtil.checkArgument;
/**
- * Represents a Person's name in the address book.
+ * Represents a Date's name in the lovebook.
* Guarantees: immutable; is valid as declared in {@link #isValidName(String)}
*/
-public class Name {
+public class Name implements Comparable {
public static final String MESSAGE_CONSTRAINTS =
"Names should only contain alphanumeric characters and spaces, and it should not be blank";
/*
- * The first character of the address must not be a whitespace,
+ * The first character of the lovebook must not be a whitespace,
* otherwise " " (a blank string) becomes a valid input.
*/
public static final String VALIDATION_REGEX = "[\\p{Alnum}][\\p{Alnum} ]*";
@@ -64,4 +64,8 @@ public int hashCode() {
return fullName.hashCode();
}
+ @Override
+ public int compareTo(Name o) {
+ return this.toString().toLowerCase().compareTo(o.toString().toLowerCase());
+ }
}
diff --git a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java b/src/main/java/seedu/lovebook/model/date/NameContainsKeywordsPredicate.java
similarity index 76%
rename from src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java
rename to src/main/java/seedu/lovebook/model/date/NameContainsKeywordsPredicate.java
index 62d19be2977..15176acf9aa 100644
--- a/src/main/java/seedu/address/model/person/NameContainsKeywordsPredicate.java
+++ b/src/main/java/seedu/lovebook/model/date/NameContainsKeywordsPredicate.java
@@ -1,15 +1,15 @@
-package seedu.address.model.person;
+package seedu.lovebook.model.date;
import java.util.List;
import java.util.function.Predicate;
-import seedu.address.commons.util.StringUtil;
-import seedu.address.commons.util.ToStringBuilder;
+import seedu.lovebook.commons.util.StringUtil;
+import seedu.lovebook.commons.util.ToStringBuilder;
/**
- * Tests that a {@code Person}'s {@code Name} matches any of the keywords given.
+ * Tests that a {@code Date}'s {@code Name} matches any of the keywords given.
*/
-public class NameContainsKeywordsPredicate implements Predicate {
+public class NameContainsKeywordsPredicate implements Predicate {
private final List keywords;
public NameContainsKeywordsPredicate(List keywords) {
@@ -17,9 +17,9 @@ public NameContainsKeywordsPredicate(List keywords) {
}
@Override
- public boolean test(Person person) {
+ public boolean test(Date date) {
return keywords.stream()
- .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(person.getName().fullName, keyword));
+ .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(date.getName().fullName, keyword));
}
@Override
diff --git a/src/main/java/seedu/lovebook/model/date/RandomPredicate.java b/src/main/java/seedu/lovebook/model/date/RandomPredicate.java
new file mode 100644
index 00000000000..b0609556855
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/RandomPredicate.java
@@ -0,0 +1,53 @@
+package seedu.lovebook.model.date;
+
+import java.util.function.Predicate;
+
+import seedu.lovebook.commons.util.ToStringBuilder;
+
+/**
+ * Tests that a {@code Date}'s {@code Name} matches any of the keywords given.
+ */
+public class RandomPredicate implements Predicate {
+ private final Date random;
+
+ public RandomPredicate(Date random) {
+ this.random = random;
+ }
+
+ @Override
+ public boolean test(Date date) {
+ return date.equals(random);
+ }
+
+ /**
+ * Returns true if both random predicates have the same date object since two dates cannot have
+ * the same data fields.
+ *
+ * @param other
+ * @return
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof RandomPredicate)) {
+ return false;
+ }
+
+ RandomPredicate otherRandomPredicate = (RandomPredicate) other;
+ return random.equals(otherRandomPredicate.random);
+ }
+
+ /**
+ * Returns a string representation of this {@code RandomPredicate} object.
+ *
+ * @return a string
+ */
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).add("random person", random).toString();
+ }
+}
diff --git a/src/main/java/seedu/lovebook/model/date/Star.java b/src/main/java/seedu/lovebook/model/date/Star.java
new file mode 100644
index 00000000000..db4fac43e8b
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/Star.java
@@ -0,0 +1,36 @@
+package seedu.lovebook.model.date;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Represents a Date's starred status in the lovebook.
+ * Guarantees: immutable; is always valid
+ */
+public class Star {
+ public final String isStarred;
+
+ /**
+ * Constructor for the star class
+ */
+ public Star(String isStarred) {
+ requireNonNull(isStarred);
+ this.isStarred = isStarred;
+ }
+
+ @Override
+ public String toString() {
+ return isStarred;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other == this // short circuit if same object
+ || (other instanceof Star // instanceof handles nulls
+ && isStarred.equals(((Star) other).isStarred)); // state check
+ }
+
+ @Override
+ public int hashCode() {
+ return isStarred.hashCode();
+ }
+}
diff --git a/src/main/java/seedu/lovebook/model/date/UniqueDateList.java b/src/main/java/seedu/lovebook/model/date/UniqueDateList.java
new file mode 100644
index 00000000000..65764e21772
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/UniqueDateList.java
@@ -0,0 +1,150 @@
+package seedu.lovebook.model.date;
+
+import static java.util.Objects.requireNonNull;
+import static seedu.lovebook.commons.util.CollectionUtil.requireAllNonNull;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import seedu.lovebook.model.date.exceptions.DuplicatePersonException;
+import seedu.lovebook.model.date.exceptions.PersonNotFoundException;
+
+/**
+ * A list of dates that enforces uniqueness between its elements and does not allow nulls.
+ * A date is considered unique by comparing using {@code Date#isSamePerson(Date)}. As such, adding and updating of
+ * dates uses Date#isSamePerson(Date) for equality so as to ensure that the date being added or updated is
+ * unique in terms of identity in the UniqueDateList. However, the removal of a date uses Date#equals(Object) so
+ * as to ensure that the date with exactly the same fields will be removed.
+ *
+ * Supports a minimal set of list operations.
+ *
+ * @see Date#isSamePerson(Date)
+ */
+
+public class UniqueDateList implements Iterable {
+
+ private final ObservableList internalList = FXCollections.observableArrayList();
+ private final ObservableList internalUnmodifiableList =
+ FXCollections.unmodifiableObservableList(internalList);
+
+ /**
+ * Returns true if the list contains an equivalent date as the given argument.
+ */
+ public boolean contains(Date toCheck) {
+ requireNonNull(toCheck);
+ return internalList.stream().anyMatch(toCheck::isSamePerson);
+ }
+
+ /**
+ * Adds a date to the list.
+ * The date must not already exist in the list.
+ */
+ public void add(Date toAdd) {
+ requireNonNull(toAdd);
+ if (contains(toAdd)) {
+ throw new DuplicatePersonException();
+ }
+ internalList.add(toAdd);
+ }
+
+ /**
+ * Replaces the date {@code target} in the list with {@code editedDate}.
+ * {@code target} must exist in the list.
+ * The date identity of {@code editedDate} must not be the same as another existing date in the list.
+ */
+ public void setDate(Date target, Date editedDate) {
+ requireAllNonNull(target, editedDate);
+
+ int index = internalList.indexOf(target);
+ if (index == -1) {
+ throw new PersonNotFoundException();
+ }
+
+ if (!target.isSamePerson(editedDate) && contains(editedDate)) {
+ throw new DuplicatePersonException();
+ }
+ internalList.set(index, editedDate);
+ }
+
+ /**
+ * Removes the equivalent date from the list.
+ * The date must exist in the list.
+ */
+ public void remove(Date toRemove) {
+ requireNonNull(toRemove);
+ if (!internalList.remove(toRemove)) {
+ throw new PersonNotFoundException();
+ }
+ }
+
+ public void setPersons(UniqueDateList replacement) {
+ requireNonNull(replacement);
+ internalList.setAll(replacement.internalList);
+ }
+
+ /**
+ * Replaces the contents of this list with {@code dates}.
+ * {@code dates} must not contain duplicate dates.
+ */
+ public void setPersons(List dates) {
+ requireAllNonNull(dates);
+ if (!datesAreUnique(dates)) {
+ throw new DuplicatePersonException();
+ }
+
+ internalList.setAll(dates);
+ }
+
+ /**
+ * Returns the backing list as an unmodifiable {@code ObservableList}.
+ */
+ public ObservableList asUnmodifiableObservableList() {
+ return internalUnmodifiableList;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return internalList.iterator();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof UniqueDateList)) {
+ return false;
+ }
+
+ UniqueDateList otherUniqueDateList = (UniqueDateList) other;
+ return internalList.equals(otherUniqueDateList.internalList);
+ }
+
+ @Override
+ public int hashCode() {
+ return internalList.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return internalList.toString();
+ }
+
+ /**
+ * Returns true if {@code dates} contains only unique dates.
+ */
+ private boolean datesAreUnique(List dates) {
+ for (int i = 0; i < dates.size() - 1; i++) {
+ for (int j = i + 1; j < dates.size(); j++) {
+ if (dates.get(i).isSamePerson(dates.get(j))) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java b/src/main/java/seedu/lovebook/model/date/exceptions/DuplicatePersonException.java
similarity index 70%
rename from src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java
rename to src/main/java/seedu/lovebook/model/date/exceptions/DuplicatePersonException.java
index d7290f59442..991caf64d3f 100644
--- a/src/main/java/seedu/address/model/person/exceptions/DuplicatePersonException.java
+++ b/src/main/java/seedu/lovebook/model/date/exceptions/DuplicatePersonException.java
@@ -1,4 +1,4 @@
-package seedu.address.model.person.exceptions;
+package seedu.lovebook.model.date.exceptions;
/**
* Signals that the operation will result in duplicate Persons (Persons are considered duplicates if they have the same
@@ -6,6 +6,6 @@
*/
public class DuplicatePersonException extends RuntimeException {
public DuplicatePersonException() {
- super("Operation would result in duplicate persons");
+ super("Operation would result in duplicate dates");
}
}
diff --git a/src/main/java/seedu/lovebook/model/date/exceptions/PersonNotFoundException.java b/src/main/java/seedu/lovebook/model/date/exceptions/PersonNotFoundException.java
new file mode 100644
index 00000000000..a80c2f5e68c
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/exceptions/PersonNotFoundException.java
@@ -0,0 +1,6 @@
+package seedu.lovebook.model.date.exceptions;
+
+/**
+ * Signals that the operation is unable to find the specified date.
+ */
+public class PersonNotFoundException extends RuntimeException {}
diff --git a/src/main/java/seedu/lovebook/model/date/horoscope/Horoscope.java b/src/main/java/seedu/lovebook/model/date/horoscope/Horoscope.java
new file mode 100644
index 00000000000..e805a791ce2
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/horoscope/Horoscope.java
@@ -0,0 +1,77 @@
+package seedu.lovebook.model.date.horoscope;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Represents the date's horoscope in the LoveBook.
+ */
+public class Horoscope implements Comparable {
+ public static final String MESSAGE_CONSTRAINTS = "Horoscope should only contain valid horoscope signs.\n"
+ + "If you aren't aware of Horoscope signs, please refer to the following list\n"
+ + "ARIES\n"
+ + "TAURUS\n"
+ + "GEMINI\n"
+ + "CANCER\n"
+ + "LEO\n"
+ + "VIRGO\n"
+ + "LIBRA\n"
+ + "SCORPIO\n"
+ + "SAGITTARIUS\n"
+ + "CAPRICORN\n"
+ + "AQUARIUS\n"
+ + "PISCES\n"
+ + "Please try again!";
+ public final String value;
+
+ /**
+ * Constructs a {@code Horoscope}.
+ *
+ * @param horoscope A valid horoscope.
+ */
+ public Horoscope(String horoscope) {
+ requireNonNull(horoscope);
+ value = horoscope;
+ }
+
+ /**
+ * Returns true if a given string is a valid horoscope.
+ */
+ public static boolean isValidHoroscope(String test) {
+ try {
+ HoroscopeEnum.valueOf(test);
+ } catch (IllegalArgumentException e) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ // instanceof handles nulls
+ if (!(other instanceof Horoscope)) {
+ return false;
+ }
+
+ Horoscope otherHoroscope = (Horoscope) other;
+ return value.equals(otherHoroscope.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public int compareTo(Horoscope o) {
+ return this.toString().toLowerCase().compareTo(o.toString().toLowerCase());
+ }
+}
diff --git a/src/main/java/seedu/lovebook/model/date/horoscope/HoroscopeEnum.java b/src/main/java/seedu/lovebook/model/date/horoscope/HoroscopeEnum.java
new file mode 100644
index 00000000000..bbde01e91e0
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/date/horoscope/HoroscopeEnum.java
@@ -0,0 +1,19 @@
+package seedu.lovebook.model.date.horoscope;
+
+/**
+ * An enumeration representing the 12 zodiac signs.
+ */
+public enum HoroscopeEnum {
+ ARIES,
+ TAURUS,
+ GEMINI,
+ CANCER,
+ LEO,
+ VIRGO,
+ LIBRA,
+ SCORPIO,
+ SAGITTARIUS,
+ CAPRICORN,
+ AQUARIUS,
+ PISCES
+}
diff --git a/src/main/java/seedu/lovebook/model/util/SampleDataUtil.java b/src/main/java/seedu/lovebook/model/util/SampleDataUtil.java
new file mode 100644
index 00000000000..fe7658d50f2
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/util/SampleDataUtil.java
@@ -0,0 +1,22 @@
+package seedu.lovebook.model.util;
+
+import seedu.lovebook.model.LoveBook;
+import seedu.lovebook.model.ReadOnlyLoveBook;
+import seedu.lovebook.model.date.Date;
+
+/**
+ * Contains utility methods for populating {@code LoveBook} with sample data.
+ */
+public class SampleDataUtil {
+ public static Date[] getSamplePersons() {
+ return new Date[] {};
+ }
+
+ public static ReadOnlyLoveBook getSampleLoveBook() {
+ LoveBook sampleAb = new LoveBook();
+ for (Date sampleDate : getSamplePersons()) {
+ sampleAb.addDate(sampleDate);
+ }
+ return sampleAb;
+ }
+}
diff --git a/src/main/java/seedu/lovebook/model/util/SampleDatePrefUtil.java b/src/main/java/seedu/lovebook/model/util/SampleDatePrefUtil.java
new file mode 100644
index 00000000000..00ec43d1c4b
--- /dev/null
+++ b/src/main/java/seedu/lovebook/model/util/SampleDatePrefUtil.java
@@ -0,0 +1,20 @@
+package seedu.lovebook.model.util;
+
+import seedu.lovebook.model.DatePrefs;
+import seedu.lovebook.model.date.Age;
+import seedu.lovebook.model.date.Height;
+import seedu.lovebook.model.date.Income;
+import seedu.lovebook.model.date.horoscope.Horoscope;
+
+/**
+ * A utility class containing a sample {@code DatePrefs} to be used in tests.
+ */
+public class SampleDatePrefUtil {
+ public static DatePrefs getSamplePreferences() {
+ Age age = new Age("20");
+ Height height = new Height("180");
+ Income income = new Income("10000");
+ Horoscope horoscope = new Horoscope("Aries");
+ return new DatePrefs(age, height, income, horoscope);
+ }
+}
diff --git a/src/main/java/seedu/lovebook/storage/DatePrefsStorage.java b/src/main/java/seedu/lovebook/storage/DatePrefsStorage.java
new file mode 100644
index 00000000000..45876d48e3e
--- /dev/null
+++ b/src/main/java/seedu/lovebook/storage/DatePrefsStorage.java
@@ -0,0 +1,43 @@
+package seedu.lovebook.storage;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+
+import seedu.lovebook.commons.exceptions.DataLoadingException;
+import seedu.lovebook.model.ReadOnlyDatePrefs;
+
+/**
+ * Represents a storage for {@link seedu.lovebook.model.DatePrefs}.
+ */
+public interface DatePrefsStorage {
+ /**
+ * Returns the file path of the data file.
+ */
+ Path getDatePrefsFilePath();
+
+ /**
+ * Returns LoveBook data as a {@link ReadOnlyDatePrefs}.
+ * Returns {@code Optional.empty()} if storage file is not found.
+ *
+ * @throws DataLoadingException if loading the data from storage failed.
+ */
+ Optional readDatePrefs() throws DataLoadingException;
+
+ /**
+ * @see #getDatePrefsFilePath()
+ */
+ Optional readDatePrefs(Path filePath) throws DataLoadingException;
+
+ /**
+ * Saves the given {@link ReadOnlyDatePrefs} to the storage.
+ * @param prefs cannot be null.
+ * @throws IOException if there was any problem writing to the file.
+ */
+ void saveDatePrefs(ReadOnlyDatePrefs prefs) throws IOException;
+
+ /**
+ * @see #saveDatePrefs(ReadOnlyDatePrefs)
+ */
+ void saveDatePrefs(ReadOnlyDatePrefs prefs, Path filePath) throws IOException;
+}
diff --git a/src/main/java/seedu/lovebook/storage/JsonAdaptedDate.java b/src/main/java/seedu/lovebook/storage/JsonAdaptedDate.java
new file mode 100644
index 00000000000..8562fca6dd9
--- /dev/null
+++ b/src/main/java/seedu/lovebook/storage/JsonAdaptedDate.java
@@ -0,0 +1,134 @@
+package seedu.lovebook.storage;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import seedu.lovebook.commons.exceptions.IllegalValueException;
+import seedu.lovebook.model.date.Age;
+import seedu.lovebook.model.date.Avatar;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.model.date.Gender;
+import seedu.lovebook.model.date.Height;
+import seedu.lovebook.model.date.Income;
+import seedu.lovebook.model.date.Name;
+import seedu.lovebook.model.date.Star;
+import seedu.lovebook.model.date.horoscope.Horoscope;
+
+/**
+ * Jackson-friendly version of {@link Date}.
+ */
+class JsonAdaptedDate {
+
+ public static final String MISSING_FIELD_MESSAGE_FORMAT = "Date's %s field is missing!";
+ public static final String INVALID_AVATAR = "Date's avatar is invalid!";
+
+ private final String name;
+ private final String age;
+ private final String gender;
+ private final String height;
+ private final String income;
+ private final String horoscope;
+ private final String star;
+ private final String avatar;
+
+ /**
+ * Constructs a {@code JsonAdaptedDate} with the given date details.
+ */
+ @JsonCreator
+ public JsonAdaptedDate(@JsonProperty("name") String name, @JsonProperty("age") String age,
+ @JsonProperty("gender") String gender, @JsonProperty("height") String height,
+ @JsonProperty("income") String income, @JsonProperty("horoscope") String horoscope,
+ @JsonProperty("avatar") String avatar) {
+ this.name = name;
+ this.age = age;
+ this.gender = gender;
+ this.height = height;
+ this.income = income;
+ this.horoscope = horoscope;
+ this.star = "false";
+ this.avatar = avatar;
+ }
+
+ /**
+ * Converts a given {@code Date} into this class for Jackson use.
+ */
+ public JsonAdaptedDate(Date source) {
+ name = source.getName().fullName;
+ age = source.getAge().value;
+ gender = source.getGender().value;
+ height = source.getHeight().value;
+ income = source.getIncome().value;
+ horoscope = source.getHoroscope().value;
+ star = source.getStar().isStarred;
+ avatar = source.getAvatar().value;
+ }
+
+ /**
+ * Converts this Jackson-friendly adapted date object into the model's {@code Date} object.
+ *
+ * @throws IllegalValueException if there were any data constraints violated in the adapted date.
+ */
+ public Date toModelType() throws IllegalValueException {
+ if (name == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName()));
+ }
+ if (!Name.isValidName(name)) {
+ throw new IllegalValueException(Name.MESSAGE_CONSTRAINTS);
+ }
+ final Name modelName = new Name(name);
+
+ if (age == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Age.class.getSimpleName()));
+ }
+ if (!Age.isValidAge(age)) {
+ throw new IllegalValueException(Age.MESSAGE_CONSTRAINTS);
+ }
+ final Age modelAge = new Age(age);
+
+ if (gender == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Gender.class.getSimpleName()));
+ }
+ if (!Gender.isValidGender(gender)) {
+ throw new IllegalValueException(Gender.MESSAGE_CONSTRAINTS);
+ }
+ final Gender modelGender = new Gender(gender);
+
+ if (height == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Height.class.getSimpleName()));
+ }
+ if (!Height.isValidHeight(height)) {
+ throw new IllegalValueException(Height.MESSAGE_CONSTRAINTS);
+ }
+ final Height modelHeight = new Height(height);
+
+ if (income == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Income.class.getSimpleName()));
+ }
+ if (!Income.isValidIncome(income)) {
+ throw new IllegalValueException(Income.MESSAGE_CONSTRAINTS);
+ }
+ final Income modelIncome = new Income(income);
+
+ if (horoscope == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT,
+ Horoscope.class.getSimpleName()));
+ }
+ if (!Horoscope.isValidHoroscope(horoscope)) {
+ throw new IllegalValueException(Horoscope.MESSAGE_CONSTRAINTS);
+ }
+ final Horoscope modelHoroscope = new Horoscope(horoscope);
+
+ if (avatar == null) {
+ throw new IllegalValueException(INVALID_AVATAR);
+ }
+ if (!Avatar.isValidAvatar(avatar)) {
+ throw new IllegalValueException(Avatar.MESSAGE_CONSTRAINTS);
+ }
+ final Avatar modelAvatar = new Avatar(avatar);
+ final Star modelStar = new Star(star);
+
+ return new Date(modelName, modelAge, modelGender, modelHeight,
+ modelIncome, modelHoroscope, modelStar, modelAvatar);
+ }
+
+}
diff --git a/src/main/java/seedu/lovebook/storage/JsonAdaptedDatePrefs.java b/src/main/java/seedu/lovebook/storage/JsonAdaptedDatePrefs.java
new file mode 100644
index 00000000000..d035e016a8b
--- /dev/null
+++ b/src/main/java/seedu/lovebook/storage/JsonAdaptedDatePrefs.java
@@ -0,0 +1,88 @@
+package seedu.lovebook.storage;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import seedu.lovebook.commons.exceptions.IllegalValueException;
+import seedu.lovebook.model.DatePrefs;
+import seedu.lovebook.model.date.Age;
+import seedu.lovebook.model.date.Height;
+import seedu.lovebook.model.date.Income;
+import seedu.lovebook.model.date.horoscope.Horoscope;
+
+/**
+ * Jackson-friendly version of {@link DatePrefs}.
+ */
+public class JsonAdaptedDatePrefs {
+ public static final String MISSING_FIELD_MESSAGE_FORMAT = "Date's %s field is missing!";
+ private String age;
+ private String height;
+ private String income;
+ private String horoscope;
+
+ /**
+ * Constructs a {@code JsonAdaptedDate} with the given date details.
+ */
+ @JsonCreator
+ public JsonAdaptedDatePrefs(@JsonProperty("age") String age, @JsonProperty("height") String height,
+ @JsonProperty("income") String income,
+ @JsonProperty("horoscope") String horoscope) {
+ this.age = age;
+ this.height = height;
+ this.income = income;
+ this.horoscope = horoscope;
+ }
+
+ /**
+ * Converts a given {@code Date} into this class for Jackson use.
+ */
+ public JsonAdaptedDatePrefs(DatePrefs source) {
+ age = source.getAge().value;
+ height = source.getHeight().value;
+ income = source.getIncome().value;
+ horoscope = source.getHoroscope().value;
+ }
+
+ /**
+ * Converts this Jackson-friendly adapted date object into the model's {@code DatePrefs} object.
+ *
+ * @throws IllegalValueException if there were any data constraints violated in the adapted date.
+ */
+ public DatePrefs toModelType() throws IllegalValueException {
+ if (age == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Age.class.getSimpleName()));
+ }
+ if (!Age.isValidAge(age)) {
+ throw new IllegalValueException(Age.MESSAGE_CONSTRAINTS);
+ }
+ final Age modelAge = new Age(age);
+
+ if (height == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Height.class.getSimpleName()));
+ }
+ if (!Height.isValidHeight(height)) {
+ throw new IllegalValueException(Height.MESSAGE_CONSTRAINTS);
+ }
+ final Height modelHeight = new Height(height);
+
+ if (income == null) {
+ throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Income.class.getSimpleName()));
+ }
+ if (!Income.isValidIncome(income)) {
+ throw new IllegalValueException(Income.MESSAGE_CONSTRAINTS);
+ }
+ final Income modelIncome = new Income(income);
+
+ if (horoscope == null) {
+ throw new IllegalValueException(
+ String.format(MISSING_FIELD_MESSAGE_FORMAT, Horoscope.class.getSimpleName()));
+ }
+ if (!Horoscope.isValidHoroscope(horoscope)) {
+ throw new IllegalValueException(Horoscope.MESSAGE_CONSTRAINTS);
+ }
+ final Horoscope modelHoroscope = new Horoscope(horoscope);
+
+ return new DatePrefs(modelAge, modelHeight, modelIncome, modelHoroscope);
+ }
+
+}
diff --git a/src/main/java/seedu/lovebook/storage/JsonDatePrefsStorage.java b/src/main/java/seedu/lovebook/storage/JsonDatePrefsStorage.java
new file mode 100644
index 00000000000..0e446965fa2
--- /dev/null
+++ b/src/main/java/seedu/lovebook/storage/JsonDatePrefsStorage.java
@@ -0,0 +1,78 @@
+package seedu.lovebook.storage;
+
+import static java.util.Objects.requireNonNull;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+import seedu.lovebook.commons.core.LogsCenter;
+import seedu.lovebook.commons.exceptions.DataLoadingException;
+import seedu.lovebook.commons.exceptions.IllegalValueException;
+import seedu.lovebook.commons.util.FileUtil;
+import seedu.lovebook.commons.util.JsonUtil;
+import seedu.lovebook.model.ReadOnlyDatePrefs;
+
+/**
+ * A class to access DatePrefs data stored as a json file on the hard disk.
+ */
+public class JsonDatePrefsStorage implements DatePrefsStorage {
+ private static final Logger logger = LogsCenter.getLogger(JsonDatePrefsStorage.class);
+
+ private Path filePath;
+
+ public JsonDatePrefsStorage(Path filePath) {
+ this.filePath = filePath;
+ }
+
+ public Path getDatePrefsFilePath() {
+ return filePath;
+ }
+
+ @Override
+ public Optional readDatePrefs() throws DataLoadingException {
+ return readDatePrefs(filePath);
+ }
+
+ /**
+ * Similar to {@link #readDatePrefs()}.
+ *
+ * @param filePath location of the data. Cannot be null.
+ * @throws DataLoadingException if loading the data from storage failed.
+ */
+ public Optional readDatePrefs(Path filePath) throws DataLoadingException {
+ requireNonNull(filePath);
+
+ Optional jsonDatePrefs = JsonUtil.readJsonFile(
+ filePath, JsonSerializableDatePrefs.class);
+ if (!jsonDatePrefs.isPresent()) {
+ return Optional.empty();
+ }
+
+ try {
+ return Optional.of(jsonDatePrefs.get().toModelType());
+ } catch (IllegalValueException ive) {
+ logger.info("Illegal values found in " + filePath + ": " + ive.getMessage());
+ throw new DataLoadingException(ive);
+ }
+ }
+
+ @Override
+ public void saveDatePrefs(ReadOnlyDatePrefs prefs) throws IOException {
+ saveDatePrefs(prefs, filePath);
+ }
+
+ /**
+ * Similar to {@link #saveDatePrefs(ReadOnlyDatePrefs, Path)}.
+ *
+ * @param filePath location of the data. Cannot be null.
+ */
+ public void saveDatePrefs(ReadOnlyDatePrefs prefs, Path filePath) throws IOException {
+ requireNonNull(prefs);
+ requireNonNull(filePath);
+
+ FileUtil.createIfMissing(filePath);
+ JsonUtil.saveJsonFile(new JsonSerializableDatePrefs(prefs), filePath);
+ }
+}
diff --git a/src/main/java/seedu/lovebook/storage/JsonLoveBookStorage.java b/src/main/java/seedu/lovebook/storage/JsonLoveBookStorage.java
new file mode 100644
index 00000000000..aed4ede57d3
--- /dev/null
+++ b/src/main/java/seedu/lovebook/storage/JsonLoveBookStorage.java
@@ -0,0 +1,80 @@
+package seedu.lovebook.storage;
+
+import static java.util.Objects.requireNonNull;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+import seedu.lovebook.commons.core.LogsCenter;
+import seedu.lovebook.commons.exceptions.DataLoadingException;
+import seedu.lovebook.commons.exceptions.IllegalValueException;
+import seedu.lovebook.commons.util.FileUtil;
+import seedu.lovebook.commons.util.JsonUtil;
+import seedu.lovebook.model.ReadOnlyLoveBook;
+
+/**
+ * A class to access LoveBook data stored as a json file on the hard disk.
+ */
+public class JsonLoveBookStorage implements LoveBookStorage {
+
+ private static final Logger logger = LogsCenter.getLogger(JsonLoveBookStorage.class);
+
+ private Path filePath;
+
+ public JsonLoveBookStorage(Path filePath) {
+ this.filePath = filePath;
+ }
+
+ public Path getLoveBookFilePath() {
+ return filePath;
+ }
+
+ @Override
+ public Optional readLoveBook() throws DataLoadingException {
+ return readLoveBook(filePath);
+ }
+
+ /**
+ * Similar to {@link #readLoveBook()}.
+ *
+ * @param filePath location of the data. Cannot be null.
+ * @throws DataLoadingException if loading the data from storage failed.
+ */
+ public Optional readLoveBook(Path filePath) throws DataLoadingException {
+ requireNonNull(filePath);
+
+ Optional jsonLoveBook = JsonUtil.readJsonFile(
+ filePath, JsonSerializableLoveBook.class);
+ if (!jsonLoveBook.isPresent()) {
+ return Optional.empty();
+ }
+
+ try {
+ return Optional.of(jsonLoveBook.get().toModelType());
+ } catch (IllegalValueException ive) {
+ logger.info("Illegal values found in " + filePath + ": " + ive.getMessage());
+ throw new DataLoadingException(ive);
+ }
+ }
+
+ @Override
+ public void saveLoveBook(ReadOnlyLoveBook loveBook) throws IOException {
+ saveLoveBook(loveBook, filePath);
+ }
+
+ /**
+ * Similar to {@link #saveLoveBook(ReadOnlyLoveBook)}.
+ *
+ * @param filePath location of the data. Cannot be null.
+ */
+ public void saveLoveBook(ReadOnlyLoveBook loveBook, Path filePath) throws IOException {
+ requireNonNull(loveBook);
+ requireNonNull(filePath);
+
+ FileUtil.createIfMissing(filePath);
+ JsonUtil.saveJsonFile(new JsonSerializableLoveBook(loveBook), filePath);
+ }
+
+}
diff --git a/src/main/java/seedu/lovebook/storage/JsonSerializableDatePrefs.java b/src/main/java/seedu/lovebook/storage/JsonSerializableDatePrefs.java
new file mode 100644
index 00000000000..9b675d5a22d
--- /dev/null
+++ b/src/main/java/seedu/lovebook/storage/JsonSerializableDatePrefs.java
@@ -0,0 +1,51 @@
+package seedu.lovebook.storage;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonRootName;
+
+import seedu.lovebook.commons.exceptions.IllegalValueException;
+import seedu.lovebook.model.DatePrefs;
+import seedu.lovebook.model.ReadOnlyDatePrefs;
+
+/**
+ * An Immutable DatePrefs that is serializable to JSON format.
+ */
+@JsonRootName(value = "DatePrefs")
+public class JsonSerializableDatePrefs {
+ private final List prefs = new ArrayList<>();
+
+ /**
+ * Constructs a {@code JsonSerializableDatePrefs} with the given preferences.
+ */
+ @JsonCreator
+ public JsonSerializableDatePrefs(@JsonProperty("prefs") List prefs) {
+ this.prefs.addAll(prefs);
+ }
+
+ /**
+ * Converts a given {@code ReadyOnlyDatePrefs} into this class for Jackson use.
+ *
+ * @param source future changes to this will not affect the created {@code JsonSerializableDatePrefs}.
+ */
+ public JsonSerializableDatePrefs(ReadOnlyDatePrefs source) {
+ prefs.addAll(source.getPreferences().stream().map(JsonAdaptedDatePrefs::new).collect(Collectors.toList()));
+ }
+
+ /**
+ * Converts these preferences into the model's {@code Preferences} object.
+ *
+ * @throws IllegalValueException if there were any data constraints violated.
+ */
+ public DatePrefs toModelType() throws IllegalValueException {
+ DatePrefs preferences = new DatePrefs();
+ for (JsonAdaptedDatePrefs jsonAdaptedDatePrefs : prefs) {
+ preferences = jsonAdaptedDatePrefs.toModelType();
+ }
+ return preferences;
+ }
+}
diff --git a/src/main/java/seedu/lovebook/storage/JsonSerializableLoveBook.java b/src/main/java/seedu/lovebook/storage/JsonSerializableLoveBook.java
new file mode 100644
index 00000000000..49ff8a3fb50
--- /dev/null
+++ b/src/main/java/seedu/lovebook/storage/JsonSerializableLoveBook.java
@@ -0,0 +1,60 @@
+package seedu.lovebook.storage;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonRootName;
+
+import seedu.lovebook.commons.exceptions.IllegalValueException;
+import seedu.lovebook.model.LoveBook;
+import seedu.lovebook.model.ReadOnlyLoveBook;
+import seedu.lovebook.model.date.Date;
+
+/**
+ * An Immutable LoveBook that is serializable to JSON format.
+ */
+@JsonRootName(value = "LoveBook")
+class JsonSerializableLoveBook {
+
+ public static final String MESSAGE_DUPLICATE_PERSON = "Persons list contains duplicate date(s).";
+
+ private final List dates = new ArrayList<>();
+
+ /**
+ * Constructs a {@code JsonSerializableLoveBook} with the given dates.
+ */
+ @JsonCreator
+ public JsonSerializableLoveBook(@JsonProperty("dates") List dates) {
+ this.dates.addAll(dates);
+ }
+
+ /**
+ * Converts a given {@code ReadOnlyLoveBook} into this class for Jackson use.
+ *
+ * @param source future changes to this will not affect the created {@code JsonSerializableLoveBook}.
+ */
+ public JsonSerializableLoveBook(ReadOnlyLoveBook source) {
+ dates.addAll(source.getPersonList().stream().map(JsonAdaptedDate::new).collect(Collectors.toList()));
+ }
+
+ /**
+ * Converts this LoveBook into the model's {@code LoveBook} object.
+ *
+ * @throws IllegalValueException if there were any data constraints violated.
+ */
+ public LoveBook toModelType() throws IllegalValueException {
+ LoveBook loveBook = new LoveBook();
+ for (JsonAdaptedDate jsonAdaptedDate : dates) {
+ Date date = jsonAdaptedDate.toModelType();
+ if (loveBook.hasDate(date)) {
+ throw new IllegalValueException(MESSAGE_DUPLICATE_PERSON);
+ }
+ loveBook.addDate(date);
+ }
+ return loveBook;
+ }
+
+}
diff --git a/src/main/java/seedu/address/storage/JsonUserPrefsStorage.java b/src/main/java/seedu/lovebook/storage/JsonUserPrefsStorage.java
similarity index 82%
rename from src/main/java/seedu/address/storage/JsonUserPrefsStorage.java
rename to src/main/java/seedu/lovebook/storage/JsonUserPrefsStorage.java
index 48a9754807d..43bbf5774d9 100644
--- a/src/main/java/seedu/address/storage/JsonUserPrefsStorage.java
+++ b/src/main/java/seedu/lovebook/storage/JsonUserPrefsStorage.java
@@ -1,13 +1,13 @@
-package seedu.address.storage;
+package seedu.lovebook.storage;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.commons.util.JsonUtil;
-import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.UserPrefs;
+import seedu.lovebook.commons.exceptions.DataLoadingException;
+import seedu.lovebook.commons.util.JsonUtil;
+import seedu.lovebook.model.ReadOnlyUserPrefs;
+import seedu.lovebook.model.UserPrefs;
/**
* A class to access UserPrefs stored in the hard disk as a json file
diff --git a/src/main/java/seedu/lovebook/storage/LoveBookStorage.java b/src/main/java/seedu/lovebook/storage/LoveBookStorage.java
new file mode 100644
index 00000000000..aca08e5a19c
--- /dev/null
+++ b/src/main/java/seedu/lovebook/storage/LoveBookStorage.java
@@ -0,0 +1,45 @@
+package seedu.lovebook.storage;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+
+import seedu.lovebook.commons.exceptions.DataLoadingException;
+import seedu.lovebook.model.ReadOnlyLoveBook;
+
+/**
+ * Represents a storage for {@link seedu.lovebook.model.LoveBook}.
+ */
+public interface LoveBookStorage {
+
+ /**
+ * Returns the file path of the data file.
+ */
+ Path getLoveBookFilePath();
+
+ /**
+ * Returns LoveBook data as a {@link ReadOnlyLoveBook}.
+ * Returns {@code Optional.empty()} if storage file is not found.
+ *
+ * @throws DataLoadingException if loading the data from storage failed.
+ */
+ Optional readLoveBook() throws DataLoadingException;
+
+ /**
+ * @see #getLoveBookFilePath()
+ */
+ Optional readLoveBook(Path filePath) throws DataLoadingException;
+
+ /**
+ * Saves the given {@link ReadOnlyLoveBook} to the storage.
+ * @param loveBook cannot be null.
+ * @throws IOException if there was any problem writing to the file.
+ */
+ void saveLoveBook(ReadOnlyLoveBook loveBook) throws IOException;
+
+ /**
+ * @see #saveLoveBook(ReadOnlyLoveBook)
+ */
+ void saveLoveBook(ReadOnlyLoveBook loveBook, Path filePath) throws IOException;
+
+}
diff --git a/src/main/java/seedu/lovebook/storage/Storage.java b/src/main/java/seedu/lovebook/storage/Storage.java
new file mode 100644
index 00000000000..fc2bf6613d5
--- /dev/null
+++ b/src/main/java/seedu/lovebook/storage/Storage.java
@@ -0,0 +1,47 @@
+package seedu.lovebook.storage;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+
+import seedu.lovebook.commons.exceptions.DataLoadingException;
+import seedu.lovebook.model.ReadOnlyDatePrefs;
+import seedu.lovebook.model.ReadOnlyLoveBook;
+import seedu.lovebook.model.ReadOnlyUserPrefs;
+import seedu.lovebook.model.UserPrefs;
+
+/**
+ * API of the Storage component
+ */
+public interface Storage extends LoveBookStorage, UserPrefsStorage, DatePrefsStorage {
+
+ @Override
+ Optional readUserPrefs() throws DataLoadingException;
+
+ @Override
+ void saveUserPrefs(ReadOnlyUserPrefs userPrefs) throws IOException;
+
+ @Override
+ Path getLoveBookFilePath();
+
+ @Override
+ Optional readLoveBook() throws DataLoadingException;
+
+ @Override
+ void saveLoveBook(ReadOnlyLoveBook loveBook) throws IOException;
+
+ @Override
+ Path getUserPrefsFilePath();
+
+ @Override
+ Path getDatePrefsFilePath();
+
+ @Override
+ Optional readDatePrefs(Path filePath) throws DataLoadingException;
+
+ @Override
+ void saveDatePrefs(ReadOnlyDatePrefs loveBook) throws IOException;
+
+
+
+}
diff --git a/src/main/java/seedu/lovebook/storage/StorageManager.java b/src/main/java/seedu/lovebook/storage/StorageManager.java
new file mode 100644
index 00000000000..db3d5cbb721
--- /dev/null
+++ b/src/main/java/seedu/lovebook/storage/StorageManager.java
@@ -0,0 +1,118 @@
+package seedu.lovebook.storage;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+import seedu.lovebook.commons.core.LogsCenter;
+import seedu.lovebook.commons.exceptions.DataLoadingException;
+import seedu.lovebook.model.ReadOnlyDatePrefs;
+import seedu.lovebook.model.ReadOnlyLoveBook;
+import seedu.lovebook.model.ReadOnlyUserPrefs;
+import seedu.lovebook.model.UserPrefs;
+
+/**
+ * Manages storage of LoveBook data in local storage.
+ */
+public class StorageManager implements Storage {
+
+ private static final Logger logger = LogsCenter.getLogger(StorageManager.class);
+ private LoveBookStorage loveBookStorage;
+ private UserPrefsStorage userPrefsStorage;
+ private DatePrefsStorage datePrefsStorage;
+
+ /**
+ * Creates a {@code StorageManager} with the given {@code LoveBookStorage} and {@code UserPrefStorage}
+ * and {@code DatePrefsStorage}.
+ */
+ public StorageManager(LoveBookStorage loveBookStorage, UserPrefsStorage userPrefsStorage,
+ DatePrefsStorage datePrefsStorage) {
+ this.loveBookStorage = loveBookStorage;
+ this.userPrefsStorage = userPrefsStorage;
+ this.datePrefsStorage = datePrefsStorage;
+ }
+
+ /**
+ * Creates a {@code StorageManager} with the given {@code LoveBookStorage} and {@code UserPrefStorage}.
+ */
+ public StorageManager(LoveBookStorage loveBookStorage, UserPrefsStorage userPrefsStorage) {
+ this.loveBookStorage = loveBookStorage;
+ this.userPrefsStorage = userPrefsStorage;
+ }
+
+ // ================ UserPrefs methods ==============================
+
+ @Override
+ public Path getUserPrefsFilePath() {
+ return userPrefsStorage.getUserPrefsFilePath();
+ }
+
+ @Override
+ public Optional readUserPrefs() throws DataLoadingException {
+ return userPrefsStorage.readUserPrefs();
+ }
+
+ @Override
+ public void saveUserPrefs(ReadOnlyUserPrefs userPrefs) throws IOException {
+ userPrefsStorage.saveUserPrefs(userPrefs);
+ }
+
+
+ // ================ LoveBook methods ==============================
+
+ @Override
+ public Path getLoveBookFilePath() {
+ return loveBookStorage.getLoveBookFilePath();
+ }
+
+ @Override
+ public Optional readLoveBook() throws DataLoadingException {
+ return readLoveBook(loveBookStorage.getLoveBookFilePath());
+ }
+
+ @Override
+ public Optional readLoveBook(Path filePath) throws DataLoadingException {
+ logger.fine("Attempting to read data from file: " + filePath);
+ return loveBookStorage.readLoveBook(filePath);
+ }
+
+ @Override
+ public void saveLoveBook(ReadOnlyLoveBook loveBook) throws IOException {
+ saveLoveBook(loveBook, loveBookStorage.getLoveBookFilePath());
+ }
+
+ @Override
+ public void saveLoveBook(ReadOnlyLoveBook loveBook, Path filePath) throws IOException {
+ logger.fine("Attempting to write to data file: " + filePath);
+ loveBookStorage.saveLoveBook(loveBook, filePath);
+ }
+
+ // ================ DatePrefs Methods ==============================
+ @Override
+ public Path getDatePrefsFilePath() {
+ return datePrefsStorage.getDatePrefsFilePath();
+ }
+
+ @Override
+ public Optional readDatePrefs() throws DataLoadingException {
+ return readDatePrefs(datePrefsStorage.getDatePrefsFilePath());
+ }
+
+ @Override
+ public Optional readDatePrefs(Path filePath) throws DataLoadingException {
+ logger.fine("Attempting to read data from file: " + filePath);
+ return datePrefsStorage.readDatePrefs(filePath);
+ }
+
+ @Override
+ public void saveDatePrefs(ReadOnlyDatePrefs loveBook) throws IOException {
+ saveDatePrefs(loveBook, getDatePrefsFilePath());
+ }
+
+ @Override
+ public void saveDatePrefs(ReadOnlyDatePrefs loveBook, Path filePath) throws IOException {
+ logger.fine("Attempting to write to data file: " + filePath);
+ datePrefsStorage.saveDatePrefs(loveBook, filePath);
+ }
+}
diff --git a/src/main/java/seedu/address/storage/UserPrefsStorage.java b/src/main/java/seedu/lovebook/storage/UserPrefsStorage.java
similarity index 68%
rename from src/main/java/seedu/address/storage/UserPrefsStorage.java
rename to src/main/java/seedu/lovebook/storage/UserPrefsStorage.java
index e94ca422ea8..70b02378eea 100644
--- a/src/main/java/seedu/address/storage/UserPrefsStorage.java
+++ b/src/main/java/seedu/lovebook/storage/UserPrefsStorage.java
@@ -1,15 +1,15 @@
-package seedu.address.storage;
+package seedu.lovebook.storage;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.UserPrefs;
+import seedu.lovebook.commons.exceptions.DataLoadingException;
+import seedu.lovebook.model.ReadOnlyUserPrefs;
+import seedu.lovebook.model.UserPrefs;
/**
- * Represents a storage for {@link seedu.address.model.UserPrefs}.
+ * Represents a storage for {@link seedu.lovebook.model.UserPrefs}.
*/
public interface UserPrefsStorage {
@@ -27,7 +27,7 @@ public interface UserPrefsStorage {
Optional readUserPrefs() throws DataLoadingException;
/**
- * Saves the given {@link seedu.address.model.ReadOnlyUserPrefs} to the storage.
+ * Saves the given {@link seedu.lovebook.model.ReadOnlyUserPrefs} to the storage.
* @param userPrefs cannot be null.
* @throws IOException if there was any problem writing to the file.
*/
diff --git a/src/main/java/seedu/address/ui/CommandBox.java b/src/main/java/seedu/lovebook/ui/CommandBox.java
similarity index 81%
rename from src/main/java/seedu/address/ui/CommandBox.java
rename to src/main/java/seedu/lovebook/ui/CommandBox.java
index 9e75478664b..cee37a6fca3 100644
--- a/src/main/java/seedu/address/ui/CommandBox.java
+++ b/src/main/java/seedu/lovebook/ui/CommandBox.java
@@ -1,12 +1,12 @@
-package seedu.address.ui;
+package seedu.lovebook.ui;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import javafx.scene.layout.Region;
-import seedu.address.logic.commands.CommandResult;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.logic.parser.exceptions.ParseException;
+import seedu.lovebook.logic.commands.CommandResult;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
/**
* The UI component that is responsible for receiving user command inputs.
@@ -31,11 +31,18 @@ public CommandBox(CommandExecutor commandExecutor) {
commandTextField.textProperty().addListener((unused1, unused2, unused3) -> setStyleToDefault());
}
+ public void setCommandTextField(String text) {
+ commandTextField.setText(text);
+ }
+ public String getCommandTextField() {
+ return commandTextField.getText();
+ }
+
/**
* Handles the Enter button pressed event.
*/
@FXML
- private void handleCommandEntered() {
+ public void handleCommandEntered() {
String commandText = commandTextField.getText();
if (commandText.equals("")) {
return;
@@ -77,7 +84,7 @@ public interface CommandExecutor {
/**
* Executes the command and returns the result.
*
- * @see seedu.address.logic.Logic#execute(String)
+ * @see seedu.lovebook.logic.Logic#execute(String)
*/
CommandResult execute(String commandText) throws CommandException, ParseException;
}
diff --git a/src/main/java/seedu/lovebook/ui/DateCard.java b/src/main/java/seedu/lovebook/ui/DateCard.java
new file mode 100644
index 00000000000..f8e47f32350
--- /dev/null
+++ b/src/main/java/seedu/lovebook/ui/DateCard.java
@@ -0,0 +1,113 @@
+package seedu.lovebook.ui;
+
+import javafx.fxml.FXML;
+import javafx.scene.control.Label;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.Region;
+import seedu.lovebook.model.date.Date;
+
+/**
+ * An UI component that displays information of a {@code Date}.
+ */
+public class DateCard extends UiPart {
+
+ private static final String FXML = "DateListCard.fxml";
+
+ /**
+ * Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX.
+ * As a consequence, UI elements' variable names cannot be set to such keywords
+ * or an exception will be thrown by JavaFX during runtime.
+ *
+ * @see The issue on LoveBook level 4
+ */
+
+ public final Date date;
+ @FXML
+ private Label name;
+ @FXML
+ private Label id;
+ @FXML
+ private Label aboutInfo;
+ @FXML
+ private ImageView starImage;
+ @FXML
+ private ImageView genderImage;
+ @FXML
+ private ImageView horoscopeImage;
+ @FXML
+ private ImageView avatarImage;
+
+
+ /**
+ * Creates a {@code PersonCode} with the given {@code Date} and index to display.
+ */
+ public DateCard(Date date, int displayedIndex) {
+ super(FXML);
+ this.date = date;
+ id.setText(displayedIndex + ". ");
+ name.setText(date.getName().fullName);
+ aboutInfo.setText(date.getAge().value + " years old, with a height of " + date.getHeight().value + "cm, and "
+ + "an income of $" + date.getIncome().value + " per month.");
+ displayIcons();
+ }
+ private void displayIcons() {
+ try {
+ horoscopeImage.setImage(new Image("images/horoscopes/" + date.getHoroscope().value.toLowerCase()
+ + ".png"));
+ if (date.getGender().value.equals("M")) {
+ genderImage.setImage(new Image("images/genders/male.png"));
+ avatarImage.setImage(new Image("images/avatars/male/" + date.getAvatar().value + ".png"));
+ } else {
+ genderImage.setImage(new Image("images/genders/female.png"));
+ avatarImage.setImage(new Image("images/avatars/female/" + date.getAvatar().value + ".png"));
+ }
+ if (date.getStar().isStarred.equals("true")) {
+ starImage.setImage(new Image("images/star.png"));
+ }
+ } catch (IllegalArgumentException e) {
+ horoscopeImage.setImage(new Image("images/bot.png"));
+ }
+ }
+
+ /**
+ * Returns the name of the date.
+ * @return name of the date
+ */
+ public String getName() {
+ return name.getText();
+ }
+
+ /**
+ * Returns information about the date.
+ * @return information about the date
+ */
+ public String getAboutInfo() {
+ return aboutInfo.getText();
+ }
+
+ /**
+ * Returns the ID of the date.
+ * @return ID of the date
+ */
+ public String getID() {
+ return id.getText();
+ }
+
+ /**
+ * Returns the image url of the gender of the date.
+ * @return url of the gender image
+ */
+ public String getGenderImage() {
+ return genderImage.getImage().getUrl();
+ }
+
+ /**
+ * Returns the image url of the horoscope of the date.
+ * @return url of the horoscope image
+ */
+ public String getHoroscopeImage() {
+ return horoscopeImage.getImage().getUrl();
+ }
+
+}
diff --git a/src/main/java/seedu/lovebook/ui/DateListPanel.java b/src/main/java/seedu/lovebook/ui/DateListPanel.java
new file mode 100644
index 00000000000..804d0c1eab4
--- /dev/null
+++ b/src/main/java/seedu/lovebook/ui/DateListPanel.java
@@ -0,0 +1,49 @@
+package seedu.lovebook.ui;
+
+import java.util.logging.Logger;
+
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.layout.Region;
+import seedu.lovebook.commons.core.LogsCenter;
+import seedu.lovebook.model.date.Date;
+
+/**
+ * Panel containing the list of dates.
+ */
+public class DateListPanel extends UiPart {
+ private static final String FXML = "DateListPanel.fxml";
+ private final Logger logger = LogsCenter.getLogger(DateListPanel.class);
+
+ @FXML
+ private ListView personListView;
+
+ /**
+ * Creates a {@code DateListPanel} with the given {@code ObservableList}.
+ */
+ public DateListPanel(ObservableList dateList) {
+ super(FXML);
+ personListView.setItems(dateList);
+ personListView.setCellFactory(listView -> new PersonListViewCell());
+ personListView.setSelectionModel(new NoSelectionModel());
+ }
+
+ /**
+ * Custom {@code ListCell} that displays the graphics of a {@code Date} using a {@code DateCard}.
+ */
+ class PersonListViewCell extends ListCell {
+ @Override
+ protected void updateItem(Date date, boolean empty) {
+ super.updateItem(date, empty);
+ if (empty || date == null) {
+ setGraphic(null);
+ setText(null);
+ } else {
+ setGraphic(new DateCard(date, getIndex() + 1).getRoot());
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/seedu/address/ui/HelpWindow.java b/src/main/java/seedu/lovebook/ui/HelpWindow.java
similarity index 93%
rename from src/main/java/seedu/address/ui/HelpWindow.java
rename to src/main/java/seedu/lovebook/ui/HelpWindow.java
index 3f16b2fcf26..6bea62cebf7 100644
--- a/src/main/java/seedu/address/ui/HelpWindow.java
+++ b/src/main/java/seedu/lovebook/ui/HelpWindow.java
@@ -1,4 +1,4 @@
-package seedu.address.ui;
+package seedu.lovebook.ui;
import java.util.logging.Logger;
@@ -8,14 +8,14 @@
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.stage.Stage;
-import seedu.address.commons.core.LogsCenter;
+import seedu.lovebook.commons.core.LogsCenter;
/**
* Controller for a help page
*/
public class HelpWindow extends UiPart {
- public static final String USERGUIDE_URL = "https://se-education.org/addressbook-level3/UserGuide.html";
+ public static final String USERGUIDE_URL = "https://ay2324s1-cs2103t-f10-2.github.io/tp/UserGuide.html";
public static final String HELP_MESSAGE = "Refer to the user guide: " + USERGUIDE_URL;
private static final Logger logger = LogsCenter.getLogger(HelpWindow.class);
diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/lovebook/ui/MainWindow.java
similarity index 86%
rename from src/main/java/seedu/address/ui/MainWindow.java
rename to src/main/java/seedu/lovebook/ui/MainWindow.java
index 79e74ef37c0..2da6cba6038 100644
--- a/src/main/java/seedu/address/ui/MainWindow.java
+++ b/src/main/java/seedu/lovebook/ui/MainWindow.java
@@ -1,4 +1,4 @@
-package seedu.address.ui;
+package seedu.lovebook.ui;
import java.util.logging.Logger;
@@ -10,12 +10,12 @@
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.logic.Logic;
-import seedu.address.logic.commands.CommandResult;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.logic.parser.exceptions.ParseException;
+import seedu.lovebook.commons.core.GuiSettings;
+import seedu.lovebook.commons.core.LogsCenter;
+import seedu.lovebook.logic.Logic;
+import seedu.lovebook.logic.commands.CommandResult;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
/**
* The Main Window. Provides the basic application layout containing
@@ -31,9 +31,10 @@ public class MainWindow extends UiPart {
private Logic logic;
// Independent Ui parts residing in this Ui container
- private PersonListPanel personListPanel;
+ private DateListPanel personListPanel;
private ResultDisplay resultDisplay;
private HelpWindow helpWindow;
+ private PresetsBar presetsBar;
@FXML
private StackPane commandBoxPlaceholder;
@@ -41,6 +42,9 @@ public class MainWindow extends UiPart {
@FXML
private MenuItem helpMenuItem;
+ @FXML
+ private StackPane presetsBarPlaceholder;
+
@FXML
private StackPane personListPanelPlaceholder;
@@ -110,17 +114,22 @@ private void setAccelerator(MenuItem menuItem, KeyCombination keyCombination) {
* Fills up all the placeholders of this window.
*/
void fillInnerParts() {
- personListPanel = new PersonListPanel(logic.getFilteredPersonList());
+ personListPanel = new DateListPanel(logic.getFilteredPersonList());
personListPanelPlaceholder.getChildren().add(personListPanel.getRoot());
resultDisplay = new ResultDisplay();
+ resultDisplay.setWelcomeMessage(logic.getWelcomeMessage());
resultDisplayPlaceholder.getChildren().add(resultDisplay.getRoot());
- StatusBarFooter statusBarFooter = new StatusBarFooter(logic.getAddressBookFilePath());
+ StatusBarFooter statusBarFooter = new StatusBarFooter(logic.getLoveBookFilePath());
statusbarPlaceholder.getChildren().add(statusBarFooter.getRoot());
CommandBox commandBox = new CommandBox(this::executeCommand);
commandBoxPlaceholder.getChildren().add(commandBox.getRoot());
+
+ presetsBar = new PresetsBar(commandBox);
+ presetsBarPlaceholder.getChildren().add(presetsBar.getRoot());
+
}
/**
@@ -163,14 +172,14 @@ private void handleExit() {
primaryStage.hide();
}
- public PersonListPanel getPersonListPanel() {
+ public DateListPanel getPersonListPanel() {
return personListPanel;
}
/**
* Executes the command and returns the result.
*
- * @see seedu.address.logic.Logic#execute(String)
+ * @see seedu.lovebook.logic.Logic#execute(String)
*/
private CommandResult executeCommand(String commandText) throws CommandException, ParseException {
try {
diff --git a/src/main/java/seedu/lovebook/ui/NoSelectionModel.java b/src/main/java/seedu/lovebook/ui/NoSelectionModel.java
new file mode 100644
index 00000000000..edd547ee7ca
--- /dev/null
+++ b/src/main/java/seedu/lovebook/ui/NoSelectionModel.java
@@ -0,0 +1,78 @@
+package seedu.lovebook.ui;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.scene.control.MultipleSelectionModel;
+
+/**
+ * A selection model that does not allow for selection.
+ * Created to remove the flickering bug when selecting a date.
+ *
+ * Taken from: https://stackoverflow.com/questions/20621752/javafx-make-listview-not-selectable-via-mouse
+ */
+public class NoSelectionModel extends MultipleSelectionModel {
+
+ @Override
+ public ObservableList getSelectedIndices() {
+ return FXCollections.emptyObservableList();
+ }
+
+ @Override
+ public ObservableList getSelectedItems() {
+ return FXCollections.emptyObservableList();
+ }
+
+ @Override
+ public void selectIndices(int index, int... indices) {
+ }
+
+ @Override
+ public void selectAll() {
+ }
+
+ @Override
+ public void selectFirst() {
+ }
+
+ @Override
+ public void selectLast() {
+ }
+
+ @Override
+ public void clearAndSelect(int index) {
+ }
+
+ @Override
+ public void select(int index) {
+ }
+
+ @Override
+ public void select(T obj) {
+ }
+
+ @Override
+ public void clearSelection(int index) {
+ }
+
+ @Override
+ public void clearSelection() {
+ }
+
+ @Override
+ public boolean isSelected(int index) {
+ return false;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return true;
+ }
+
+ @Override
+ public void selectPrevious() {
+ }
+
+ @Override
+ public void selectNext() {
+ }
+}
diff --git a/src/main/java/seedu/lovebook/ui/PresetsBar.java b/src/main/java/seedu/lovebook/ui/PresetsBar.java
new file mode 100644
index 00000000000..145e926e63b
--- /dev/null
+++ b/src/main/java/seedu/lovebook/ui/PresetsBar.java
@@ -0,0 +1,94 @@
+package seedu.lovebook.ui;
+
+import javafx.fxml.FXML;
+import javafx.scene.layout.Region;
+
+/**
+ * The UI component responsible for helping the user with preset commands.
+ */
+public class PresetsBar extends UiPart {
+ private static final String FXML = "PresetsBar.fxml";
+
+ private CommandBox commandBox;
+
+ /**
+ * Creates a {@code PresetsBar} with the given {@code CommandBox}.
+ * @param commandBox The command box to be used.
+ */
+ public PresetsBar(CommandBox commandBox) {
+ super(FXML);
+ this.commandBox = commandBox;
+ }
+
+
+ /**
+ * Handles the Add button pressed event.
+ */
+ @FXML
+ public void handleClear() {
+ commandBox.setCommandTextField("");
+ }
+
+ /**
+ * Handles the Add button pressed event.
+ */
+ @FXML
+ public void handleAddD() {
+ commandBox.setCommandTextField("add name/NAME age/AGE gender/GENDER "
+ + "height/HEIGHT income/INCOME horoscope/HOROSCOPE");
+ }
+
+ /**
+ * Handles the Delete button pressed event.
+ */
+ @FXML
+ public void handleDeleteD() {
+ commandBox.setCommandTextField("delete INDEX");
+ }
+
+ /**
+ * Handles the Edit button pressed event.
+ */
+ @FXML
+ public void handleEditD() {
+ commandBox.setCommandTextField("edit INDEX name/NAME age/AGE gender/GENDER "
+ + "height/HEIGHT income/INCOME horoscope/HOROSCOPE");
+ }
+
+ /**
+ * Handles the Set Preferences button pressed event.
+ */
+ @FXML
+ public void handleSetPref() {
+ commandBox.setCommandTextField("setP age/AGE "
+ + "height/HEIGHT income/INCOME horoscope/HOROSCOPE");
+ }
+
+ /**
+ * Handles the Show Preferences button pressed event.
+ */
+ @FXML
+ public void handleShowPref() {
+ commandBox.setCommandTextField("showP");
+ }
+
+ /**
+ * Gets the text in the command box.
+ * @return the text in the command box.
+ */
+ public String getCommandBoxTest() {
+ return commandBox.getCommandTextField();
+ }
+
+ /**
+ * Gets the Command Box.
+ * @return the Command Box.
+ */
+ public CommandBox getCommandBox() {
+ return commandBox;
+ }
+
+}
+
+
+
diff --git a/src/main/java/seedu/address/ui/ResultDisplay.java b/src/main/java/seedu/lovebook/ui/ResultDisplay.java
similarity index 58%
rename from src/main/java/seedu/address/ui/ResultDisplay.java
rename to src/main/java/seedu/lovebook/ui/ResultDisplay.java
index 7d98e84eedf..4017f044ddc 100644
--- a/src/main/java/seedu/address/ui/ResultDisplay.java
+++ b/src/main/java/seedu/lovebook/ui/ResultDisplay.java
@@ -1,9 +1,11 @@
-package seedu.address.ui;
+package seedu.lovebook.ui;
import static java.util.Objects.requireNonNull;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
import javafx.scene.layout.Region;
/**
@@ -16,6 +18,9 @@ public class ResultDisplay extends UiPart {
@FXML
private TextArea resultDisplay;
+ @FXML
+ private ImageView bot;
+
public ResultDisplay() {
super(FXML);
}
@@ -23,6 +28,16 @@ public ResultDisplay() {
public void setFeedbackToUser(String feedbackToUser) {
requireNonNull(feedbackToUser);
resultDisplay.setText(feedbackToUser);
+ bot.setImage(new Image("/images/bot.png"));
+ }
+
+ public void setWelcomeMessage(String welcomeMessage) {
+ resultDisplay.setText(welcomeMessage);
+ bot.setImage(new Image("/images/bot.png"));
+ }
+
+ public String getText() {
+ return resultDisplay.getText();
}
}
diff --git a/src/main/java/seedu/address/ui/StatusBarFooter.java b/src/main/java/seedu/lovebook/ui/StatusBarFooter.java
similarity index 96%
rename from src/main/java/seedu/address/ui/StatusBarFooter.java
rename to src/main/java/seedu/lovebook/ui/StatusBarFooter.java
index b577f829423..51d20671338 100644
--- a/src/main/java/seedu/address/ui/StatusBarFooter.java
+++ b/src/main/java/seedu/lovebook/ui/StatusBarFooter.java
@@ -1,4 +1,4 @@
-package seedu.address.ui;
+package seedu.lovebook.ui;
import java.nio.file.Path;
import java.nio.file.Paths;
diff --git a/src/main/java/seedu/address/ui/Ui.java b/src/main/java/seedu/lovebook/ui/Ui.java
similarity index 85%
rename from src/main/java/seedu/address/ui/Ui.java
rename to src/main/java/seedu/lovebook/ui/Ui.java
index 17aa0b494fe..533f82574b6 100644
--- a/src/main/java/seedu/address/ui/Ui.java
+++ b/src/main/java/seedu/lovebook/ui/Ui.java
@@ -1,4 +1,4 @@
-package seedu.address.ui;
+package seedu.lovebook.ui;
import javafx.stage.Stage;
diff --git a/src/main/java/seedu/address/ui/UiManager.java b/src/main/java/seedu/lovebook/ui/UiManager.java
similarity index 91%
rename from src/main/java/seedu/address/ui/UiManager.java
rename to src/main/java/seedu/lovebook/ui/UiManager.java
index fdf024138bc..e427e7b6e0d 100644
--- a/src/main/java/seedu/address/ui/UiManager.java
+++ b/src/main/java/seedu/lovebook/ui/UiManager.java
@@ -1,4 +1,4 @@
-package seedu.address.ui;
+package seedu.lovebook.ui;
import java.util.logging.Logger;
@@ -7,10 +7,10 @@
import javafx.scene.control.Alert.AlertType;
import javafx.scene.image.Image;
import javafx.stage.Stage;
-import seedu.address.MainApp;
-import seedu.address.commons.core.LogsCenter;
-import seedu.address.commons.util.StringUtil;
-import seedu.address.logic.Logic;
+import seedu.lovebook.MainApp;
+import seedu.lovebook.commons.core.LogsCenter;
+import seedu.lovebook.commons.util.StringUtil;
+import seedu.lovebook.logic.Logic;
/**
* The manager of the UI component.
@@ -20,7 +20,7 @@ public class UiManager implements Ui {
public static final String ALERT_DIALOG_PANE_FIELD_ID = "alertDialogPane";
private static final Logger logger = LogsCenter.getLogger(UiManager.class);
- private static final String ICON_APPLICATION = "/images/address_book_32.png";
+ private static final String ICON_APPLICATION = "/images/bot.png";
private Logic logic;
private MainWindow mainWindow;
diff --git a/src/main/java/seedu/address/ui/UiPart.java b/src/main/java/seedu/lovebook/ui/UiPart.java
similarity index 97%
rename from src/main/java/seedu/address/ui/UiPart.java
rename to src/main/java/seedu/lovebook/ui/UiPart.java
index fc820e01a9c..2df35e61df0 100644
--- a/src/main/java/seedu/address/ui/UiPart.java
+++ b/src/main/java/seedu/lovebook/ui/UiPart.java
@@ -1,4 +1,4 @@
-package seedu.address.ui;
+package seedu.lovebook.ui;
import static java.util.Objects.requireNonNull;
@@ -6,7 +6,7 @@
import java.net.URL;
import javafx.fxml.FXMLLoader;
-import seedu.address.MainApp;
+import seedu.lovebook.MainApp;
/**
* Represents a distinct part of the UI. e.g. Windows, dialogs, panels, status bars, etc.
diff --git a/src/main/resources/images/avatars/female/1.png b/src/main/resources/images/avatars/female/1.png
new file mode 100644
index 00000000000..bdc1e0b723c
Binary files /dev/null and b/src/main/resources/images/avatars/female/1.png differ
diff --git a/src/main/resources/images/avatars/female/2.png b/src/main/resources/images/avatars/female/2.png
new file mode 100644
index 00000000000..08d3473f0e7
Binary files /dev/null and b/src/main/resources/images/avatars/female/2.png differ
diff --git a/src/main/resources/images/avatars/female/3.png b/src/main/resources/images/avatars/female/3.png
new file mode 100644
index 00000000000..1a971c2cc71
Binary files /dev/null and b/src/main/resources/images/avatars/female/3.png differ
diff --git a/src/main/resources/images/avatars/female/4.png b/src/main/resources/images/avatars/female/4.png
new file mode 100644
index 00000000000..88ba4453eb7
Binary files /dev/null and b/src/main/resources/images/avatars/female/4.png differ
diff --git a/src/main/resources/images/avatars/female/5.png b/src/main/resources/images/avatars/female/5.png
new file mode 100644
index 00000000000..39c0b5eb35d
Binary files /dev/null and b/src/main/resources/images/avatars/female/5.png differ
diff --git a/src/main/resources/images/avatars/female/6.png b/src/main/resources/images/avatars/female/6.png
new file mode 100644
index 00000000000..3462eef7665
Binary files /dev/null and b/src/main/resources/images/avatars/female/6.png differ
diff --git a/src/main/resources/images/avatars/female/7.png b/src/main/resources/images/avatars/female/7.png
new file mode 100644
index 00000000000..9e83f576d9d
Binary files /dev/null and b/src/main/resources/images/avatars/female/7.png differ
diff --git a/src/main/resources/images/avatars/female/8.png b/src/main/resources/images/avatars/female/8.png
new file mode 100644
index 00000000000..e44f4d1aa06
Binary files /dev/null and b/src/main/resources/images/avatars/female/8.png differ
diff --git a/src/main/resources/images/avatars/female/9.png b/src/main/resources/images/avatars/female/9.png
new file mode 100644
index 00000000000..be4ab8b5d30
Binary files /dev/null and b/src/main/resources/images/avatars/female/9.png differ
diff --git a/src/main/resources/images/avatars/male/1.png b/src/main/resources/images/avatars/male/1.png
new file mode 100644
index 00000000000..d09615e11b9
Binary files /dev/null and b/src/main/resources/images/avatars/male/1.png differ
diff --git a/src/main/resources/images/avatars/male/2.png b/src/main/resources/images/avatars/male/2.png
new file mode 100644
index 00000000000..d83432172c8
Binary files /dev/null and b/src/main/resources/images/avatars/male/2.png differ
diff --git a/src/main/resources/images/avatars/male/3.png b/src/main/resources/images/avatars/male/3.png
new file mode 100644
index 00000000000..5062515ff87
Binary files /dev/null and b/src/main/resources/images/avatars/male/3.png differ
diff --git a/src/main/resources/images/avatars/male/4.png b/src/main/resources/images/avatars/male/4.png
new file mode 100644
index 00000000000..b53322c03b2
Binary files /dev/null and b/src/main/resources/images/avatars/male/4.png differ
diff --git a/src/main/resources/images/avatars/male/5.png b/src/main/resources/images/avatars/male/5.png
new file mode 100644
index 00000000000..5bdfb4f07c5
Binary files /dev/null and b/src/main/resources/images/avatars/male/5.png differ
diff --git a/src/main/resources/images/avatars/male/6.png b/src/main/resources/images/avatars/male/6.png
new file mode 100644
index 00000000000..e5cf1f7a3f2
Binary files /dev/null and b/src/main/resources/images/avatars/male/6.png differ
diff --git a/src/main/resources/images/avatars/male/7.png b/src/main/resources/images/avatars/male/7.png
new file mode 100644
index 00000000000..538a464e1f8
Binary files /dev/null and b/src/main/resources/images/avatars/male/7.png differ
diff --git a/src/main/resources/images/avatars/male/8.png b/src/main/resources/images/avatars/male/8.png
new file mode 100644
index 00000000000..29a07d2fc04
Binary files /dev/null and b/src/main/resources/images/avatars/male/8.png differ
diff --git a/src/main/resources/images/avatars/male/9.png b/src/main/resources/images/avatars/male/9.png
new file mode 100644
index 00000000000..232d3b48195
Binary files /dev/null and b/src/main/resources/images/avatars/male/9.png differ
diff --git a/src/main/resources/images/bot.png b/src/main/resources/images/bot.png
new file mode 100644
index 00000000000..c2560d15386
Binary files /dev/null and b/src/main/resources/images/bot.png differ
diff --git a/src/main/resources/images/genders/female.png b/src/main/resources/images/genders/female.png
new file mode 100644
index 00000000000..dba9030724f
Binary files /dev/null and b/src/main/resources/images/genders/female.png differ
diff --git a/src/main/resources/images/genders/male.png b/src/main/resources/images/genders/male.png
new file mode 100644
index 00000000000..d961579f28d
Binary files /dev/null and b/src/main/resources/images/genders/male.png differ
diff --git a/src/main/resources/images/horoscopes/aquarius.png b/src/main/resources/images/horoscopes/aquarius.png
new file mode 100644
index 00000000000..c57ab196b0f
Binary files /dev/null and b/src/main/resources/images/horoscopes/aquarius.png differ
diff --git a/src/main/resources/images/horoscopes/aries.png b/src/main/resources/images/horoscopes/aries.png
new file mode 100644
index 00000000000..ef17a1e8e6d
Binary files /dev/null and b/src/main/resources/images/horoscopes/aries.png differ
diff --git a/src/main/resources/images/horoscopes/cancer.png b/src/main/resources/images/horoscopes/cancer.png
new file mode 100644
index 00000000000..1ec55163076
Binary files /dev/null and b/src/main/resources/images/horoscopes/cancer.png differ
diff --git a/src/main/resources/images/horoscopes/capricorn.png b/src/main/resources/images/horoscopes/capricorn.png
new file mode 100644
index 00000000000..33a7fe898e7
Binary files /dev/null and b/src/main/resources/images/horoscopes/capricorn.png differ
diff --git a/src/main/resources/images/horoscopes/gemini.png b/src/main/resources/images/horoscopes/gemini.png
new file mode 100644
index 00000000000..2431d43577f
Binary files /dev/null and b/src/main/resources/images/horoscopes/gemini.png differ
diff --git a/src/main/resources/images/horoscopes/leo.png b/src/main/resources/images/horoscopes/leo.png
new file mode 100644
index 00000000000..f71193f175e
Binary files /dev/null and b/src/main/resources/images/horoscopes/leo.png differ
diff --git a/src/main/resources/images/horoscopes/libra.png b/src/main/resources/images/horoscopes/libra.png
new file mode 100644
index 00000000000..b942121fb6f
Binary files /dev/null and b/src/main/resources/images/horoscopes/libra.png differ
diff --git a/src/main/resources/images/horoscopes/pisces.png b/src/main/resources/images/horoscopes/pisces.png
new file mode 100644
index 00000000000..7ac9335cfb3
Binary files /dev/null and b/src/main/resources/images/horoscopes/pisces.png differ
diff --git a/src/main/resources/images/horoscopes/sagittarius.png b/src/main/resources/images/horoscopes/sagittarius.png
new file mode 100644
index 00000000000..00c34323bca
Binary files /dev/null and b/src/main/resources/images/horoscopes/sagittarius.png differ
diff --git a/src/main/resources/images/horoscopes/scorpio.png b/src/main/resources/images/horoscopes/scorpio.png
new file mode 100644
index 00000000000..51e2402ac6d
Binary files /dev/null and b/src/main/resources/images/horoscopes/scorpio.png differ
diff --git a/src/main/resources/images/horoscopes/taurus.png b/src/main/resources/images/horoscopes/taurus.png
new file mode 100644
index 00000000000..113c78f4005
Binary files /dev/null and b/src/main/resources/images/horoscopes/taurus.png differ
diff --git a/src/main/resources/images/horoscopes/virgo.png b/src/main/resources/images/horoscopes/virgo.png
new file mode 100644
index 00000000000..80c926a950b
Binary files /dev/null and b/src/main/resources/images/horoscopes/virgo.png differ
diff --git a/src/main/resources/images/pink-gradient.jpg b/src/main/resources/images/pink-gradient.jpg
new file mode 100644
index 00000000000..e0256084ea5
Binary files /dev/null and b/src/main/resources/images/pink-gradient.jpg differ
diff --git a/src/main/resources/images/star.png b/src/main/resources/images/star.png
new file mode 100644
index 00000000000..b203dc72b8a
Binary files /dev/null and b/src/main/resources/images/star.png differ
diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css
index 36e6b001cd8..5920eabdd49 100644
--- a/src/main/resources/view/DarkTheme.css
+++ b/src/main/resources/view/DarkTheme.css
@@ -1,210 +1,205 @@
.background {
- -fx-background-color: derive(#1d1d1d, 20%);
- background-color: #383838; /* Used in the default.html file */
+ -fx-background-image: url("../images/pink-gradient.jpg");
+ -fx-background-repeat: no-repeat;
+ -fx-background-size: cover;
}
.label {
- -fx-font-size: 11pt;
- -fx-font-family: "Segoe UI Semibold";
- -fx-text-fill: #555555;
- -fx-opacity: 0.9;
+ -fx-font-size: 11pt;
+ -fx-font-family: "Segoe UI Semibold";
+ -fx-text-fill: black;
+ -fx-opacity: 0.9;
}
.label-bright {
- -fx-font-size: 11pt;
- -fx-font-family: "Segoe UI Semibold";
- -fx-text-fill: white;
- -fx-opacity: 1;
+ -fx-font-size: 11pt;
+ -fx-font-family: "Segoe UI Semibold";
+ -fx-text-fill: black;
+ -fx-opacity: 1;
}
.label-header {
- -fx-font-size: 32pt;
- -fx-font-family: "Segoe UI Light";
- -fx-text-fill: white;
- -fx-opacity: 1;
+ -fx-font-size: 32pt;
+ -fx-font-family: "Segoe UI Light";
+ -fx-text-fill: black;
+ -fx-opacity: 1;
+}
+
+.label-about {
+ -fx-font-size: 10pt;
+ -fx-font-family: "Segoe UI Light";
+ -fx-text-fill: black;
+ -fx-opacity: 1;
}
.text-field {
- -fx-font-size: 12pt;
- -fx-font-family: "Segoe UI Semibold";
+ -fx-font-size: 12pt;
+ -fx-font-family: "Segoe UI Semibold";
}
.tab-pane {
- -fx-padding: 0 0 0 1;
+ -fx-padding: 0 0 0 1;
}
.tab-pane .tab-header-area {
- -fx-padding: 0 0 0 0;
- -fx-min-height: 0;
- -fx-max-height: 0;
+ -fx-padding: 0 0 0 0;
+ -fx-min-height: 0;
+ -fx-max-height: 0;
}
.table-view {
- -fx-base: #1d1d1d;
- -fx-control-inner-background: #1d1d1d;
- -fx-background-color: #1d1d1d;
- -fx-table-cell-border-color: transparent;
- -fx-table-header-border-color: transparent;
- -fx-padding: 5;
+ -fx-base: #1d1d1d;
+ -fx-control-inner-background: #1d1d1d;
+ -fx-background-color: #1d1d1d;
+ -fx-table-cell-border-color: transparent;
+ -fx-table-header-border-color: transparent;
+ -fx-padding: 5;
}
.table-view .column-header-background {
- -fx-background-color: transparent;
+ -fx-background-color: transparent;
}
-.table-view .column-header, .table-view .filler {
- -fx-size: 35;
- -fx-border-width: 0 0 1 0;
- -fx-background-color: transparent;
- -fx-border-color:
- transparent
- transparent
- derive(-fx-base, 80%)
- transparent;
- -fx-border-insets: 0 10 1 0;
+.table-view .column-header,
+.table-view .filler {
+ -fx-size: 35;
+ -fx-background-color: transparent;
+ -fx-border-insets: 0 10 1 0;
}
.table-view .column-header .label {
- -fx-font-size: 20pt;
- -fx-font-family: "Segoe UI Light";
- -fx-text-fill: white;
- -fx-alignment: center-left;
- -fx-opacity: 1;
+ -fx-font-size: 20pt;
+ -fx-font-family: "Segoe UI Light";
+ -fx-text-fill: black;
+ -fx-alignment: center-left;
+ -fx-opacity: 1;
}
.table-view:focused .table-row-cell:filled:focused:selected {
- -fx-background-color: -fx-focus-color;
+ -fx-background-color: transparent;
}
.split-pane:horizontal .split-pane-divider {
- -fx-background-color: derive(#1d1d1d, 20%);
- -fx-border-color: transparent transparent transparent #4d4d4d;
+ -fx-background-color: transparent;
}
.split-pane {
- -fx-border-radius: 1;
- -fx-border-width: 1;
- -fx-background-color: derive(#1d1d1d, 20%);
+ -fx-border-radius: 1;
+ -fx-border-width: 1;
+ -fx-background-color: transparent;
}
.list-view {
- -fx-background-insets: 0;
- -fx-padding: 0;
- -fx-background-color: derive(#1d1d1d, 20%);
+ -fx-background-insets: 0;
+ -fx-padding: 0;
+ -fx-background-color: transparent;
}
.list-cell {
- -fx-label-padding: 0 0 0 0;
- -fx-graphic-text-gap : 0;
- -fx-padding: 0 0 0 0;
-}
-
-.list-cell:filled:even {
- -fx-background-color: #3c3e3f;
-}
-
-.list-cell:filled:odd {
- -fx-background-color: #515658;
-}
-
-.list-cell:filled:selected {
- -fx-background-color: #424d5f;
-}
-
-.list-cell:filled:selected #cardPane {
- -fx-border-color: #3e7b91;
- -fx-border-width: 1;
+ -fx-label-padding: 0 0 0 0;
+ -fx-graphic-text-gap: 0;
+ -fx-padding: 0 0 0 0;
+ -fx-background-color: transparent;
}
.list-cell .label {
- -fx-text-fill: white;
+ -fx-text-fill: black;
}
.cell_big_label {
- -fx-font-family: "Segoe UI Semibold";
- -fx-font-size: 16px;
- -fx-text-fill: #010504;
+ -fx-font-family: "Segoe UI Semibold";
+ -fx-font-size: 16px;
+ -fx-text-fill: black;
}
.cell_small_label {
- -fx-font-family: "Segoe UI";
- -fx-font-size: 13px;
- -fx-text-fill: #010504;
+ -fx-font-family: "Segoe UI";
+ -fx-font-size: 13px;
+ -fx-text-fill: #010504;
}
.stack-pane {
- -fx-background-color: derive(#1d1d1d, 20%);
+ -fx-border-color: transparent;
}
.pane-with-border {
- -fx-background-color: derive(#1d1d1d, 20%);
- -fx-border-color: derive(#1d1d1d, 10%);
- -fx-border-top-width: 1px;
+ -fx-background-image: url("../images/pink-gradient.jpg");
+ -fx-background-repeat: no-repeat;
+ -fx-background-size: cover;
+ -fx-border-top-width: 1px;
}
+/* File Location Display (At Bottom) */
.status-bar {
- -fx-background-color: derive(#1d1d1d, 30%);
+ -fx-background-image: url("../images/pink-gradient.jpg");
+ -fx-background-repeat: no-repeat;
+ -fx-background-size: cover;
}
.result-display {
- -fx-background-color: transparent;
- -fx-font-family: "Segoe UI Light";
- -fx-font-size: 13pt;
- -fx-text-fill: white;
+ -fx-background-color: transparent;
+ -fx-font-family: "Segoe UI Light";
+ -fx-font-size: 13pt;
+ -fx-text-fill: black;
}
.result-display .label {
- -fx-text-fill: black !important;
+ -fx-text-fill: black !important;
}
.status-bar .label {
- -fx-font-family: "Segoe UI Light";
- -fx-text-fill: white;
- -fx-padding: 4px;
- -fx-pref-height: 30px;
+ -fx-font-family: "Segoe UI Light";
+ -fx-text-fill: black;
+ -fx-padding: 4px;
+ -fx-pref-height: 30px;
}
.status-bar-with-border {
- -fx-background-color: derive(#1d1d1d, 30%);
- -fx-border-color: derive(#1d1d1d, 25%);
- -fx-border-width: 1px;
+ -fx-background-image: url("../images/pink-gradient.jpg");
+ -fx-background-repeat: no-repeat;
+ -fx-background-size: cover;
}
.status-bar-with-border .label {
- -fx-text-fill: white;
+ -fx-text-fill: black;
}
.grid-pane {
- -fx-background-color: derive(#1d1d1d, 30%);
- -fx-border-color: derive(#1d1d1d, 30%);
- -fx-border-width: 1px;
+ -fx-background-image: url("../images/pink-gradient.jpg");
+ -fx-background-repeat: no-repeat;
+ -fx-background-size: cover;
+ -fx-border-width: 1px;
}
.grid-pane .stack-pane {
- -fx-background-color: derive(#1d1d1d, 30%);
+ -fx-background-image: url("../images/pink-gradient.jpg");
+ -fx-background-repeat: no-repeat;
+ -fx-background-size: cover;
}
.context-menu {
- -fx-background-color: derive(#1d1d1d, 50%);
+ -fx-background-color: #ffffff;
}
.context-menu .label {
- -fx-text-fill: white;
+ -fx-text-fill: black;
}
.menu-bar {
- -fx-background-color: derive(#1d1d1d, 20%);
+ -fx-background-image: url("../images/pink-gradient.jpg");
+ -fx-background-repeat: no-repeat;
+ -fx-background-size: cover;
}
.menu-bar .label {
- -fx-font-size: 14pt;
- -fx-font-family: "Segoe UI Light";
- -fx-text-fill: white;
- -fx-opacity: 0.9;
+ -fx-font-size: 14pt;
+ -fx-font-family: "Segoe UI Light";
+ -fx-text-fill: black;
+ -fx-opacity: 0.9;
}
.menu .left-container {
- -fx-background-color: black;
+ -fx-background-color: black;
}
/*
@@ -213,140 +208,144 @@
* http://pixelduke.wordpress.com/2012/10/23/jmetro-windows-8-controls-on-java/
*/
.button {
- -fx-padding: 5 22 5 22;
- -fx-border-color: #e2e2e2;
- -fx-border-width: 2;
- -fx-background-radius: 0;
- -fx-background-color: #1d1d1d;
- -fx-font-family: "Segoe UI", Helvetica, Arial, sans-serif;
- -fx-font-size: 11pt;
- -fx-text-fill: #d8d8d8;
- -fx-background-insets: 0 0 0 0, 0, 1, 2;
-}
-
-.button:hover {
- -fx-background-color: #3a3a3a;
-}
-
-.button:pressed, .button:default:hover:pressed {
+ -fx-padding: 5 22 5 22;
+ -fx-border-color: #e2e2e2;
+ -fx-border-width: 2;
+ /* -fx-background-radius: 120; */
+ -fx-background-color: transparent;
+ -fx-font-family: "Segoe UI", Helvetica, Arial, sans-serif;
+ -fx-font-size: 11pt;
+ -fx-text-fill: #000000;
+ -fx-border-radius: 12;
+ -fx-background-insets: 0 0 0 0, 0, 1, 2;
+}
+
+.button:pressed,
+.button:default:hover:pressed {
-fx-background-color: white;
-fx-text-fill: #1d1d1d;
}
.button:focused {
- -fx-border-color: white, white;
- -fx-border-width: 1, 1;
- -fx-border-style: solid, segments(1, 1);
- -fx-border-radius: 0, 0;
- -fx-border-insets: 1 1 1 1, 0;
+ -fx-border-color: white, white;
+ -fx-border-width: 1, 1;
+ -fx-border-style: solid, segments(1, 1);
+ -fx-border-radius: 0, 0;
+ -fx-border-insets: 1 1 1 1, 0;
}
-.button:disabled, .button:default:disabled {
- -fx-opacity: 0.4;
- -fx-background-color: #1d1d1d;
- -fx-text-fill: white;
+.button:disabled,
+.button:default:disabled {
+ -fx-opacity: 0.4;
+ /*-fx-background-color: #1d1d1d;*/
+ -fx-text-fill: black;
}
.button:default {
- -fx-background-color: -fx-focus-color;
- -fx-text-fill: #ffffff;
+ -fx-background-color: -fx-focus-color;
+ -fx-text-fill: #ffffff;
}
.button:default:hover {
- -fx-background-color: derive(-fx-focus-color, 30%);
+ -fx-background-color: derive(-fx-focus-color, 30%);
}
.dialog-pane {
- -fx-background-color: #1d1d1d;
+ /*-fx-background-color: #1d1d1d;*/
+ -fx-background-color: transparent;
}
.dialog-pane > *.button-bar > *.container {
- -fx-background-color: #1d1d1d;
+ /*-fx-background-color: #1d1d1d;*/
+ -fx-background-color: transparent;
}
.dialog-pane > *.label.content {
- -fx-font-size: 14px;
- -fx-font-weight: bold;
- -fx-text-fill: white;
+ -fx-font-size: 14px;
+ -fx-font-weight: bold;
+ -fx-text-fill: black;
}
.dialog-pane:header *.header-panel {
- -fx-background-color: derive(#1d1d1d, 25%);
+ -fx-background-color: derive(#1d1d1d, 25%);
}
.dialog-pane:header *.header-panel *.label {
- -fx-font-size: 18px;
- -fx-font-style: italic;
- -fx-fill: white;
- -fx-text-fill: white;
+ -fx-font-size: 18px;
+ -fx-font-style: italic;
+ -fx-fill: white;
+ -fx-text-fill: black;
}
.scroll-bar {
- -fx-background-color: derive(#1d1d1d, 20%);
+ -fx-background-color: white;
}
.scroll-bar .thumb {
- -fx-background-color: derive(#1d1d1d, 50%);
- -fx-background-insets: 3;
+ -fx-background-color: #ffc1cc;
+ -fx-background-insets: 3;
+}
+
+.scroll-bar .increment-button,
+.scroll-bar .decrement-button {
+ -fx-background-color: transparent;
+ -fx-padding: 0 0 0 0;
}
-.scroll-bar .increment-button, .scroll-bar .decrement-button {
- -fx-background-color: transparent;
- -fx-padding: 0 0 0 0;
+.scroll-bar .increment-arrow,
+.scroll-bar .decrement-arrow {
+ -fx-shape: " ";
}
-.scroll-bar .increment-arrow, .scroll-bar .decrement-arrow {
- -fx-shape: " ";
+.scroll-bar:vertical .increment-arrow,
+.scroll-bar:vertical .decrement-arrow {
+ -fx-padding: 1 8 1 8;
}
-.scroll-bar:vertical .increment-arrow, .scroll-bar:vertical .decrement-arrow {
- -fx-padding: 1 8 1 8;
+.scroll-bar:horizontal .increment-arrow,
+.scroll-bar:horizontal .decrement-arrow {
+ -fx-padding: 8 1 8 1;
}
-.scroll-bar:horizontal .increment-arrow, .scroll-bar:horizontal .decrement-arrow {
- -fx-padding: 8 1 8 1;
+.result-message {
+ -fx-background-color: transparent;
+ -fx-border-color: transparent;
}
#cardPane {
- -fx-background-color: transparent;
- -fx-border-width: 0;
+ -fx-background-color: white;
+ -fx-border-width: 0;
+ -fx-background-radius: 20;
+ -fx-padding: 5px;
+ -fx-border-insets: 5px;
+ -fx-background-insets: 5px;
}
#commandTypeLabel {
- -fx-font-size: 11px;
- -fx-text-fill: #F70D1A;
+ -fx-font-size: 11px;
+ -fx-text-fill: #f70d1a;
}
#commandTextField {
- -fx-background-color: transparent #383838 transparent #383838;
- -fx-background-insets: 0;
- -fx-border-color: #383838 #383838 #ffffff #383838;
- -fx-border-insets: 0;
- -fx-border-width: 1;
- -fx-font-family: "Segoe UI Light";
- -fx-font-size: 13pt;
- -fx-text-fill: white;
+ -fx-background-color: #ffffff;
+ -fx-background-insets: 0;
+ -fx-border-insets: 0;
+ -fx-font-family: "Segoe UI Light";
+ -fx-font-size: 13pt;
+ -fx-text-fill: black;
}
-#filterField, #personListPanel, #personWebpage {
- -fx-effect: innershadow(gaussian, black, 10, 0, 0, 0);
+#filterField,
+#personListPanel,
+#personWebpage {
+ -fx-effect: innershadow(gaussian, black, 10, 0, 0, 0);
}
+/* Box showing the replies to the commands entered. */
#resultDisplay .content {
- -fx-background-color: transparent, #383838, transparent, #383838;
- -fx-background-radius: 0;
-}
-
-#tags {
- -fx-hgap: 7;
- -fx-vgap: 3;
-}
-
-#tags .label {
- -fx-text-fill: white;
- -fx-background-color: #3e7b91;
- -fx-padding: 1 3 1 3;
- -fx-border-radius: 2;
- -fx-background-radius: 2;
- -fx-font-size: 11;
+ -fx-background-radius: 20;
+ -fx-border-radius: 10;
+ -fx-background-color: #ffffff;
+ -fx-text-fill: black;
+ -fx-font-family: "Segoe UI Light";
}
diff --git a/src/main/resources/view/DateListCard.fxml b/src/main/resources/view/DateListCard.fxml
new file mode 100644
index 00000000000..45764d1206b
--- /dev/null
+++ b/src/main/resources/view/DateListCard.fxml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/DateListPanel.fxml b/src/main/resources/view/DateListPanel.fxml
new file mode 100644
index 00000000000..a1bb6bbace8
--- /dev/null
+++ b/src/main/resources/view/DateListPanel.fxml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/Extensions.css b/src/main/resources/view/Extensions.css
index bfe82a85964..1da8393e69d 100644
--- a/src/main/resources/view/Extensions.css
+++ b/src/main/resources/view/Extensions.css
@@ -5,7 +5,9 @@
.list-cell:empty {
/* Empty cells will not have alternating colours */
- -fx-background: #383838;
+ -fx-background-image: url("../images/pink-gradient.jpg");
+ -fx-background-repeat: no-repeat;
+ -fx-background-size: cover;
}
.tag-selector {
diff --git a/src/main/resources/view/HelpWindow.css b/src/main/resources/view/HelpWindow.css
index 17e8a8722cd..fe3114c9542 100644
--- a/src/main/resources/view/HelpWindow.css
+++ b/src/main/resources/view/HelpWindow.css
@@ -1,19 +1,19 @@
#copyButton, #helpMessage {
- -fx-text-fill: white;
+ -fx-text-fill: black;
}
#copyButton {
- -fx-background-color: dimgray;
+ -fx-background-image: url("../images/pink-gradient.jpg");
}
#copyButton:hover {
- -fx-background-color: gray;
+ -fx-opacity: 0.8;
}
#copyButton:armed {
- -fx-background-color: darkgray;
+ -fx-background-color: white;
}
#helpMessageContainer {
- -fx-background-color: derive(#1d1d1d, 20%);
+ -fx-background-color: white;
}
diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml
index 7778f666a0a..0993459c40f 100644
--- a/src/main/resources/view/MainWindow.fxml
+++ b/src/main/resources/view/MainWindow.fxml
@@ -6,15 +6,14 @@
-
+
-
+
-
+
@@ -33,24 +32,28 @@
-
+
-
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
diff --git a/src/main/resources/view/PresetsBar.fxml b/src/main/resources/view/PresetsBar.fxml
new file mode 100644
index 00000000000..ef40eeff680
--- /dev/null
+++ b/src/main/resources/view/PresetsBar.fxml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/ResultDisplay.fxml b/src/main/resources/view/ResultDisplay.fxml
index 01b691792a9..b88ac1ccb33 100644
--- a/src/main/resources/view/ResultDisplay.fxml
+++ b/src/main/resources/view/ResultDisplay.fxml
@@ -1,9 +1,24 @@
+
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json b/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json
deleted file mode 100644
index 6a4d2b7181c..00000000000
--- a/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "persons": [ {
- "name": "Valid Person",
- "phone": "9482424",
- "email": "hans@example.com",
- "address": "4th street"
- }, {
- "name": "Person With Invalid Phone Field",
- "phone": "948asdf2424",
- "email": "hans@example.com",
- "address": "4th street"
- } ]
-}
diff --git a/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json b/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json
deleted file mode 100644
index ccd21f7d1a9..00000000000
--- a/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "persons": [ {
- "name": "Person with invalid name field: Ha!ns Mu@ster",
- "phone": "9482424",
- "email": "hans@example.com",
- "address": "4th street"
- } ]
-}
diff --git a/src/test/data/JsonDatePrefsStorageTest/invalidDatePrefs.json b/src/test/data/JsonDatePrefsStorageTest/invalidDatePrefs.json
new file mode 100644
index 00000000000..ed9b57c3866
--- /dev/null
+++ b/src/test/data/JsonDatePrefsStorageTest/invalidDatePrefs.json
@@ -0,0 +1,8 @@
+{
+ "prefs" : [ {
+ "age" : "11",
+ "height" : "-120",
+ "income" : "invaliddd",
+ "horoscope" : "Lmao"
+ } ]
+}
diff --git a/src/test/data/JsonAddressBookStorageTest/notJsonFormatAddressBook.json b/src/test/data/JsonDatePrefsStorageTest/notJsonFormatDatePrefs.json
similarity index 100%
rename from src/test/data/JsonAddressBookStorageTest/notJsonFormatAddressBook.json
rename to src/test/data/JsonDatePrefsStorageTest/notJsonFormatDatePrefs.json
diff --git a/src/test/data/JsonLoveBookStorageTest/invalidAndValidDateLoveBook.json b/src/test/data/JsonLoveBookStorageTest/invalidAndValidDateLoveBook.json
new file mode 100644
index 00000000000..0c86c6eae9e
--- /dev/null
+++ b/src/test/data/JsonLoveBookStorageTest/invalidAndValidDateLoveBook.json
@@ -0,0 +1,13 @@
+{
+ "dates": [ {
+ "name": "Valid Person",
+ "age": "33",
+ "gender": "M",
+ "height": "120"
+ }, {
+ "name": "Person With Invalid Age Field",
+ "age": "948asdf2424",
+ "gender": "F",
+ "height": "123"
+ } ]
+}
diff --git a/src/test/data/JsonLoveBookStorageTest/invalidDateLoveBook.json b/src/test/data/JsonLoveBookStorageTest/invalidDateLoveBook.json
new file mode 100644
index 00000000000..9ce251493c0
--- /dev/null
+++ b/src/test/data/JsonLoveBookStorageTest/invalidDateLoveBook.json
@@ -0,0 +1,8 @@
+{
+ "dates": [ {
+ "name": "Person with invalid name field: Ha!ns Mu@ster",
+ "age": "94",
+ "gender": "F",
+ "height": "23245"
+ } ]
+}
diff --git a/src/test/data/JsonLoveBookStorageTest/notJsonFormatLoveBook.json b/src/test/data/JsonLoveBookStorageTest/notJsonFormatLoveBook.json
new file mode 100644
index 00000000000..a1097343b5d
--- /dev/null
+++ b/src/test/data/JsonLoveBookStorageTest/notJsonFormatLoveBook.json
@@ -0,0 +1 @@
+not json format!
diff --git a/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json
deleted file mode 100644
index a7427fe7aa2..00000000000
--- a/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "persons": [ {
- "name": "Alice Pauline",
- "phone": "94351253",
- "email": "alice@example.com",
- "address": "123, Jurong West Ave 6, #08-111",
- "tags": [ "friends" ]
- }, {
- "name": "Alice Pauline",
- "phone": "94351253",
- "email": "pauline@example.com",
- "address": "4th street"
- } ]
-}
diff --git a/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json
deleted file mode 100644
index ad3f135ae42..00000000000
--- a/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "persons": [ {
- "name": "Hans Muster",
- "phone": "9482424",
- "email": "invalid@email!3e",
- "address": "4th street"
- } ]
-}
diff --git a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json
deleted file mode 100644
index 72262099d35..00000000000
--- a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "_comment": "AddressBook save file which contains the same Person values as in TypicalPersons#getTypicalAddressBook()",
- "persons" : [ {
- "name" : "Alice Pauline",
- "phone" : "94351253",
- "email" : "alice@example.com",
- "address" : "123, Jurong West Ave 6, #08-111",
- "tags" : [ "friends" ]
- }, {
- "name" : "Benson Meier",
- "phone" : "98765432",
- "email" : "johnd@example.com",
- "address" : "311, Clementi Ave 2, #02-25",
- "tags" : [ "owesMoney", "friends" ]
- }, {
- "name" : "Carl Kurz",
- "phone" : "95352563",
- "email" : "heinz@example.com",
- "address" : "wall street",
- "tags" : [ ]
- }, {
- "name" : "Daniel Meier",
- "phone" : "87652533",
- "email" : "cornelia@example.com",
- "address" : "10th street",
- "tags" : [ "friends" ]
- }, {
- "name" : "Elle Meyer",
- "phone" : "9482224",
- "email" : "werner@example.com",
- "address" : "michegan ave",
- "tags" : [ ]
- }, {
- "name" : "Fiona Kunz",
- "phone" : "9482427",
- "email" : "lydia@example.com",
- "address" : "little tokyo",
- "tags" : [ ]
- }, {
- "name" : "George Best",
- "phone" : "9482442",
- "email" : "anna@example.com",
- "address" : "4th street",
- "tags" : [ ]
- } ]
-}
diff --git a/src/test/data/JsonSerializableDatePrefsTest/invalidDatePrefs.json b/src/test/data/JsonSerializableDatePrefsTest/invalidDatePrefs.json
new file mode 100644
index 00000000000..ed9b57c3866
--- /dev/null
+++ b/src/test/data/JsonSerializableDatePrefsTest/invalidDatePrefs.json
@@ -0,0 +1,8 @@
+{
+ "prefs" : [ {
+ "age" : "11",
+ "height" : "-120",
+ "income" : "invaliddd",
+ "horoscope" : "Lmao"
+ } ]
+}
diff --git a/src/test/data/JsonSerializableDatePrefsTest/typicalDatePrefs.json b/src/test/data/JsonSerializableDatePrefsTest/typicalDatePrefs.json
new file mode 100644
index 00000000000..683ff89b0f7
--- /dev/null
+++ b/src/test/data/JsonSerializableDatePrefsTest/typicalDatePrefs.json
@@ -0,0 +1,8 @@
+{
+ "prefs" : [ {
+ "age" : "21",
+ "height" : "170",
+ "income" : "10000",
+ "horoscope" : "ARIES"
+ } ]
+}
diff --git a/src/test/data/JsonSerializableLoveBookTest/duplicateDateLoveBook.json b/src/test/data/JsonSerializableLoveBookTest/duplicateDateLoveBook.json
new file mode 100644
index 00000000000..545ca9d3e35
--- /dev/null
+++ b/src/test/data/JsonSerializableLoveBookTest/duplicateDateLoveBook.json
@@ -0,0 +1,21 @@
+{
+ "dates": [ {
+ "name": "Alice Pauline",
+ "age": "31",
+ "gender": "F",
+ "height": "123",
+ "income": "2000",
+ "horoscope": "TAURUS",
+ "star": "false",
+ "avatar": "4"
+ }, {
+ "name": "Alice Pauline",
+ "age": "31",
+ "gender": "F",
+ "height": "123",
+ "income": "2000",
+ "horoscope": "TAURUS",
+ "star": "false",
+ "avatar": "4"
+ } ]
+}
diff --git a/src/test/data/JsonSerializableLoveBookTest/invalidDateLoveBook.json b/src/test/data/JsonSerializableLoveBookTest/invalidDateLoveBook.json
new file mode 100644
index 00000000000..a33f84fbc80
--- /dev/null
+++ b/src/test/data/JsonSerializableLoveBookTest/invalidDateLoveBook.json
@@ -0,0 +1,10 @@
+{
+ "dates": [ {
+ "name": "Hans Muster",
+ "age": "24",
+ "gender": "Transgender",
+ "height": "232",
+ "star": "false",
+ "avatar": "4"
+ } ]
+}
diff --git a/src/test/data/JsonSerializableLoveBookTest/typicalDatesLoveBook.json b/src/test/data/JsonSerializableLoveBookTest/typicalDatesLoveBook.json
new file mode 100644
index 00000000000..50ed85e9043
--- /dev/null
+++ b/src/test/data/JsonSerializableLoveBookTest/typicalDatesLoveBook.json
@@ -0,0 +1,67 @@
+{
+ "_comment": "LoveBook save file which contains the same Person values as in TypicalDates#getTypicalLoveBook()",
+ "dates" : [ {
+ "name" : "Alice Pauline",
+ "age" : "31",
+ "gender" : "F",
+ "height" : "126",
+ "income" : "1000",
+ "horoscope": "TAURUS",
+ "star": "false",
+ "avatar": "4"
+ }, {
+ "name" : "Benson Meier",
+ "age" : "22",
+ "gender" : "M",
+ "height" : "234",
+ "income" : "2000",
+ "horoscope" : "LIBRA",
+ "star": "false",
+ "avatar": "4"
+ }, {
+ "name" : "Carl Kurz",
+ "age" : "23",
+ "gender" : "M",
+ "height" : "123",
+ "income" : "3000",
+ "horoscope" : "ARIES",
+ "star": "false",
+ "avatar": "4"
+ }, {
+ "name" : "Daniel Meier",
+ "age" : "25",
+ "gender" : "M",
+ "height" : "101",
+ "income" : "4000",
+ "horoscope" : "LIBRA",
+ "star": "false",
+ "avatar": "4"
+ }, {
+ "name" : "Elle Meyer",
+ "age" : "34",
+ "gender" : "F",
+ "height" : "123",
+ "income" : "5000",
+ "horoscope" : "GEMINI",
+ "star": "false",
+ "avatar": "4"
+ }, {
+ "name" : "Fiona Kunz",
+ "age" : "24",
+ "gender" : "F",
+ "height" : "124",
+ "income" : "6000",
+ "horoscope" : "GEMINI",
+ "star": "false",
+ "avatar": "4"
+ }, {
+ "name" : "George Best",
+ "age" : "94",
+ "gender" : "M",
+ "height" : "245",
+ "income" : "7000",
+ "horoscope" : "TAURUS",
+ "star": "false",
+ "avatar": "4"
+ } ]
+}
diff --git a/src/test/data/JsonUserPrefsStorageTest/ExtraValuesUserPref.json b/src/test/data/JsonUserPrefsStorageTest/ExtraValuesUserPref.json
index 1037548a9cd..4a8256aacac 100644
--- a/src/test/data/JsonUserPrefsStorageTest/ExtraValuesUserPref.json
+++ b/src/test/data/JsonUserPrefsStorageTest/ExtraValuesUserPref.json
@@ -9,5 +9,5 @@
"z" : 99
}
},
- "addressBookFilePath" : "addressbook.json"
+ "LoveBookFilePath" : "LoveBook.json"
}
diff --git a/src/test/data/JsonUserPrefsStorageTest/TypicalUserPref.json b/src/test/data/JsonUserPrefsStorageTest/TypicalUserPref.json
index b819bed900a..63de142152b 100644
--- a/src/test/data/JsonUserPrefsStorageTest/TypicalUserPref.json
+++ b/src/test/data/JsonUserPrefsStorageTest/TypicalUserPref.json
@@ -7,5 +7,5 @@
"y" : 100
}
},
- "addressBookFilePath" : "addressbook.json"
+ "LoveBookFilePath" : "LoveBook.json"
}
diff --git a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java b/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java
deleted file mode 100644
index 162a0c86031..00000000000
--- a/src/test/java/seedu/address/logic/commands/AddCommandIntegrationTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package seedu.address.logic.commands;
-
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import seedu.address.logic.Messages;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.UserPrefs;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.PersonBuilder;
-
-/**
- * Contains integration tests (interaction with the Model) for {@code AddCommand}.
- */
-public class AddCommandIntegrationTest {
-
- private Model model;
-
- @BeforeEach
- public void setUp() {
- model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- }
-
- @Test
- public void execute_newPerson_success() {
- Person validPerson = new PersonBuilder().build();
-
- Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
- expectedModel.addPerson(validPerson);
-
- assertCommandSuccess(new AddCommand(validPerson), model,
- String.format(AddCommand.MESSAGE_SUCCESS, Messages.format(validPerson)),
- expectedModel);
- }
-
- @Test
- public void execute_duplicatePerson_throwsCommandException() {
- Person personInList = model.getAddressBook().getPersonList().get(0);
- assertCommandFailure(new AddCommand(personInList), model,
- AddCommand.MESSAGE_DUPLICATE_PERSON);
- }
-
-}
diff --git a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java b/src/test/java/seedu/address/logic/commands/ClearCommandTest.java
deleted file mode 100644
index 80d9110c03a..00000000000
--- a/src/test/java/seedu/address/logic/commands/ClearCommandTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package seedu.address.logic.commands;
-
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.model.AddressBook;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.UserPrefs;
-
-public class ClearCommandTest {
-
- @Test
- public void execute_emptyAddressBook_success() {
- Model model = new ModelManager();
- Model expectedModel = new ModelManager();
-
- assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel);
- }
-
- @Test
- public void execute_nonEmptyAddressBook_success() {
- Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- expectedModel.setAddressBook(new AddressBook());
-
- assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel);
- }
-
-}
diff --git a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java b/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
deleted file mode 100644
index 643a1d08069..00000000000
--- a/src/test/java/seedu/address/logic/commands/CommandTestUtil.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package seedu.address.logic.commands;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-import static seedu.address.testutil.Assert.assertThrows;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import seedu.address.commons.core.index.Index;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.model.AddressBook;
-import seedu.address.model.Model;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
-
-/**
- * Contains helper methods for testing commands.
- */
-public class CommandTestUtil {
-
- public static final String VALID_NAME_AMY = "Amy Bee";
- public static final String VALID_NAME_BOB = "Bob Choo";
- public static final String VALID_PHONE_AMY = "11111111";
- public static final String VALID_PHONE_BOB = "22222222";
- public static final String VALID_EMAIL_AMY = "amy@example.com";
- public static final String VALID_EMAIL_BOB = "bob@example.com";
- public static final String VALID_ADDRESS_AMY = "Block 312, Amy Street 1";
- public static final String VALID_ADDRESS_BOB = "Block 123, Bobby Street 3";
- public static final String VALID_TAG_HUSBAND = "husband";
- public static final String VALID_TAG_FRIEND = "friend";
-
- public static final String NAME_DESC_AMY = " " + PREFIX_NAME + VALID_NAME_AMY;
- public static final String NAME_DESC_BOB = " " + PREFIX_NAME + VALID_NAME_BOB;
- public static final String PHONE_DESC_AMY = " " + PREFIX_PHONE + VALID_PHONE_AMY;
- public static final String PHONE_DESC_BOB = " " + PREFIX_PHONE + VALID_PHONE_BOB;
- public static final String EMAIL_DESC_AMY = " " + PREFIX_EMAIL + VALID_EMAIL_AMY;
- public static final String EMAIL_DESC_BOB = " " + PREFIX_EMAIL + VALID_EMAIL_BOB;
- public static final String ADDRESS_DESC_AMY = " " + PREFIX_ADDRESS + VALID_ADDRESS_AMY;
- public static final String ADDRESS_DESC_BOB = " " + PREFIX_ADDRESS + VALID_ADDRESS_BOB;
- public static final String TAG_DESC_FRIEND = " " + PREFIX_TAG + VALID_TAG_FRIEND;
- public static final String TAG_DESC_HUSBAND = " " + PREFIX_TAG + VALID_TAG_HUSBAND;
-
- public static final String INVALID_NAME_DESC = " " + PREFIX_NAME + "James&"; // '&' not allowed in names
- public static final String INVALID_PHONE_DESC = " " + PREFIX_PHONE + "911a"; // 'a' not allowed in phones
- public static final String INVALID_EMAIL_DESC = " " + PREFIX_EMAIL + "bob!yahoo"; // missing '@' symbol
- public static final String INVALID_ADDRESS_DESC = " " + PREFIX_ADDRESS; // empty string not allowed for addresses
- public static final String INVALID_TAG_DESC = " " + PREFIX_TAG + "hubby*"; // '*' not allowed in tags
-
- public static final String PREAMBLE_WHITESPACE = "\t \r \n";
- public static final String PREAMBLE_NON_EMPTY = "NonEmptyPreamble";
-
- public static final EditCommand.EditPersonDescriptor DESC_AMY;
- public static final EditCommand.EditPersonDescriptor DESC_BOB;
-
- static {
- DESC_AMY = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY)
- .withPhone(VALID_PHONE_AMY).withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY)
- .withTags(VALID_TAG_FRIEND).build();
- DESC_BOB = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB)
- .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB)
- .withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND).build();
- }
-
- /**
- * Executes the given {@code command}, confirms that
- * - the returned {@link CommandResult} matches {@code expectedCommandResult}
- * - the {@code actualModel} matches {@code expectedModel}
- */
- public static void assertCommandSuccess(Command command, Model actualModel, CommandResult expectedCommandResult,
- Model expectedModel) {
- try {
- CommandResult result = command.execute(actualModel);
- assertEquals(expectedCommandResult, result);
- assertEquals(expectedModel, actualModel);
- } catch (CommandException ce) {
- throw new AssertionError("Execution of command should not fail.", ce);
- }
- }
-
- /**
- * Convenience wrapper to {@link #assertCommandSuccess(Command, Model, CommandResult, Model)}
- * that takes a string {@code expectedMessage}.
- */
- public static void assertCommandSuccess(Command command, Model actualModel, String expectedMessage,
- Model expectedModel) {
- CommandResult expectedCommandResult = new CommandResult(expectedMessage);
- assertCommandSuccess(command, actualModel, expectedCommandResult, expectedModel);
- }
-
- /**
- * Executes the given {@code command}, confirms that
- * - a {@code CommandException} is thrown
- * - the CommandException message matches {@code expectedMessage}
- * - the address book, filtered person list and selected person in {@code actualModel} remain unchanged
- */
- public static void assertCommandFailure(Command command, Model actualModel, String expectedMessage) {
- // we are unable to defensively copy the model for comparison later, so we can
- // only do so by copying its components.
- AddressBook expectedAddressBook = new AddressBook(actualModel.getAddressBook());
- List expectedFilteredList = new ArrayList<>(actualModel.getFilteredPersonList());
-
- assertThrows(CommandException.class, expectedMessage, () -> command.execute(actualModel));
- assertEquals(expectedAddressBook, actualModel.getAddressBook());
- assertEquals(expectedFilteredList, actualModel.getFilteredPersonList());
- }
- /**
- * Updates {@code model}'s filtered list to show only the person at the given {@code targetIndex} in the
- * {@code model}'s address book.
- */
- public static void showPersonAtIndex(Model model, Index targetIndex) {
- assertTrue(targetIndex.getZeroBased() < model.getFilteredPersonList().size());
-
- Person person = model.getFilteredPersonList().get(targetIndex.getZeroBased());
- final String[] splitName = person.getName().fullName.split("\\s+");
- model.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(splitName[0])));
-
- assertEquals(1, model.getFilteredPersonList().size());
- }
-
-}
diff --git a/src/test/java/seedu/address/logic/commands/ListCommandTest.java b/src/test/java/seedu/address/logic/commands/ListCommandTest.java
deleted file mode 100644
index 435ff1f7275..00000000000
--- a/src/test/java/seedu/address/logic/commands/ListCommandTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package seedu.address.logic.commands;
-
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.UserPrefs;
-
-/**
- * Contains integration tests (interaction with the Model) and unit tests for ListCommand.
- */
-public class ListCommandTest {
-
- private Model model;
- private Model expectedModel;
-
- @BeforeEach
- public void setUp() {
- model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
- }
-
- @Test
- public void execute_listIsNotFiltered_showsSameList() {
- assertCommandSuccess(new ListCommand(), model, ListCommand.MESSAGE_SUCCESS, expectedModel);
- }
-
- @Test
- public void execute_listIsFiltered_showsEverything() {
- showPersonAtIndex(model, INDEX_FIRST_PERSON);
- assertCommandSuccess(new ListCommand(), model, ListCommand.MESSAGE_SUCCESS, expectedModel);
- }
-}
diff --git a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java b/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java
deleted file mode 100644
index 5bc11d3cdaa..00000000000
--- a/src/test/java/seedu/address/logic/parser/AddCommandParserTest.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package seedu.address.logic.parser;
-
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_ADDRESS_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_EMAIL_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_NAME_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_PHONE_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_TAG_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.PREAMBLE_NON_EMPTY;
-import static seedu.address.logic.commands.CommandTestUtil.PREAMBLE_WHITESPACE;
-import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_HUSBAND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
-import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
-import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
-import static seedu.address.testutil.TypicalPersons.AMY;
-import static seedu.address.testutil.TypicalPersons.BOB;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.logic.Messages;
-import seedu.address.logic.commands.AddCommand;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-import seedu.address.testutil.PersonBuilder;
-
-public class AddCommandParserTest {
- private AddCommandParser parser = new AddCommandParser();
-
- @Test
- public void parse_allFieldsPresent_success() {
- Person expectedPerson = new PersonBuilder(BOB).withTags(VALID_TAG_FRIEND).build();
-
- // whitespace only preamble
- assertParseSuccess(parser, PREAMBLE_WHITESPACE + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB
- + ADDRESS_DESC_BOB + TAG_DESC_FRIEND, new AddCommand(expectedPerson));
-
-
- // multiple tags - all accepted
- Person expectedPersonMultipleTags = new PersonBuilder(BOB).withTags(VALID_TAG_FRIEND, VALID_TAG_HUSBAND)
- .build();
- assertParseSuccess(parser,
- NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB + TAG_DESC_HUSBAND + TAG_DESC_FRIEND,
- new AddCommand(expectedPersonMultipleTags));
- }
-
- @Test
- public void parse_repeatedNonTagValue_failure() {
- String validExpectedPersonString = NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB
- + ADDRESS_DESC_BOB + TAG_DESC_FRIEND;
-
- // multiple names
- assertParseFailure(parser, NAME_DESC_AMY + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NAME));
-
- // multiple phones
- assertParseFailure(parser, PHONE_DESC_AMY + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE));
-
- // multiple emails
- assertParseFailure(parser, EMAIL_DESC_AMY + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_EMAIL));
-
- // multiple addresses
- assertParseFailure(parser, ADDRESS_DESC_AMY + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_ADDRESS));
-
- // multiple fields repeated
- assertParseFailure(parser,
- validExpectedPersonString + PHONE_DESC_AMY + EMAIL_DESC_AMY + NAME_DESC_AMY + ADDRESS_DESC_AMY
- + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NAME, PREFIX_ADDRESS, PREFIX_EMAIL, PREFIX_PHONE));
-
- // invalid value followed by valid value
-
- // invalid name
- assertParseFailure(parser, INVALID_NAME_DESC + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NAME));
-
- // invalid email
- assertParseFailure(parser, INVALID_EMAIL_DESC + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_EMAIL));
-
- // invalid phone
- assertParseFailure(parser, INVALID_PHONE_DESC + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE));
-
- // invalid address
- assertParseFailure(parser, INVALID_ADDRESS_DESC + validExpectedPersonString,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_ADDRESS));
-
- // valid value followed by invalid value
-
- // invalid name
- assertParseFailure(parser, validExpectedPersonString + INVALID_NAME_DESC,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_NAME));
-
- // invalid email
- assertParseFailure(parser, validExpectedPersonString + INVALID_EMAIL_DESC,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_EMAIL));
-
- // invalid phone
- assertParseFailure(parser, validExpectedPersonString + INVALID_PHONE_DESC,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE));
-
- // invalid address
- assertParseFailure(parser, validExpectedPersonString + INVALID_ADDRESS_DESC,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_ADDRESS));
- }
-
- @Test
- public void parse_optionalFieldsMissing_success() {
- // zero tags
- Person expectedPerson = new PersonBuilder(AMY).withTags().build();
- assertParseSuccess(parser, NAME_DESC_AMY + PHONE_DESC_AMY + EMAIL_DESC_AMY + ADDRESS_DESC_AMY,
- new AddCommand(expectedPerson));
- }
-
- @Test
- public void parse_compulsoryFieldMissing_failure() {
- String expectedMessage = String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE);
-
- // missing name prefix
- assertParseFailure(parser, VALID_NAME_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB,
- expectedMessage);
-
- // missing phone prefix
- assertParseFailure(parser, NAME_DESC_BOB + VALID_PHONE_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB,
- expectedMessage);
-
- // missing email prefix
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + VALID_EMAIL_BOB + ADDRESS_DESC_BOB,
- expectedMessage);
-
- // missing address prefix
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + VALID_ADDRESS_BOB,
- expectedMessage);
-
- // all prefixes missing
- assertParseFailure(parser, VALID_NAME_BOB + VALID_PHONE_BOB + VALID_EMAIL_BOB + VALID_ADDRESS_BOB,
- expectedMessage);
- }
-
- @Test
- public void parse_invalidValue_failure() {
- // invalid name
- assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Name.MESSAGE_CONSTRAINTS);
-
- // invalid phone
- assertParseFailure(parser, NAME_DESC_BOB + INVALID_PHONE_DESC + EMAIL_DESC_BOB + ADDRESS_DESC_BOB
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Phone.MESSAGE_CONSTRAINTS);
-
- // invalid email
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + INVALID_EMAIL_DESC + ADDRESS_DESC_BOB
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Email.MESSAGE_CONSTRAINTS);
-
- // invalid address
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + INVALID_ADDRESS_DESC
- + TAG_DESC_HUSBAND + TAG_DESC_FRIEND, Address.MESSAGE_CONSTRAINTS);
-
- // invalid tag
- assertParseFailure(parser, NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB + ADDRESS_DESC_BOB
- + INVALID_TAG_DESC + VALID_TAG_FRIEND, Tag.MESSAGE_CONSTRAINTS);
-
- // two invalid values, only first invalid value reported
- assertParseFailure(parser, INVALID_NAME_DESC + PHONE_DESC_BOB + EMAIL_DESC_BOB + INVALID_ADDRESS_DESC,
- Name.MESSAGE_CONSTRAINTS);
-
- // non-empty preamble
- assertParseFailure(parser, PREAMBLE_NON_EMPTY + NAME_DESC_BOB + PHONE_DESC_BOB + EMAIL_DESC_BOB
- + ADDRESS_DESC_BOB + TAG_DESC_HUSBAND + TAG_DESC_FRIEND,
- String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
- }
-}
diff --git a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java b/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java
deleted file mode 100644
index cc7175172d4..00000000000
--- a/src/test/java/seedu/address/logic/parser/EditCommandParserTest.java
+++ /dev/null
@@ -1,208 +0,0 @@
-package seedu.address.logic.parser;
-
-import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_ADDRESS_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_EMAIL_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_NAME_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_PHONE_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.INVALID_TAG_DESC;
-import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.TAG_DESC_HUSBAND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-import static seedu.address.logic.parser.CommandParserTestUtil.assertParseFailure;
-import static seedu.address.logic.parser.CommandParserTestUtil.assertParseSuccess;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
-import static seedu.address.testutil.TypicalIndexes.INDEX_THIRD_PERSON;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.commons.core.index.Index;
-import seedu.address.logic.Messages;
-import seedu.address.logic.commands.EditCommand;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
-
-public class EditCommandParserTest {
-
- private static final String TAG_EMPTY = " " + PREFIX_TAG;
-
- private static final String MESSAGE_INVALID_FORMAT =
- String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE);
-
- private EditCommandParser parser = new EditCommandParser();
-
- @Test
- public void parse_missingParts_failure() {
- // no index specified
- assertParseFailure(parser, VALID_NAME_AMY, MESSAGE_INVALID_FORMAT);
-
- // no field specified
- assertParseFailure(parser, "1", EditCommand.MESSAGE_NOT_EDITED);
-
- // no index and no field specified
- assertParseFailure(parser, "", MESSAGE_INVALID_FORMAT);
- }
-
- @Test
- public void parse_invalidPreamble_failure() {
- // negative index
- assertParseFailure(parser, "-5" + NAME_DESC_AMY, MESSAGE_INVALID_FORMAT);
-
- // zero index
- assertParseFailure(parser, "0" + NAME_DESC_AMY, MESSAGE_INVALID_FORMAT);
-
- // invalid arguments being parsed as preamble
- assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_FORMAT);
-
- // invalid prefix being parsed as preamble
- assertParseFailure(parser, "1 i/ string", MESSAGE_INVALID_FORMAT);
- }
-
- @Test
- public void parse_invalidValue_failure() {
- assertParseFailure(parser, "1" + INVALID_NAME_DESC, Name.MESSAGE_CONSTRAINTS); // invalid name
- assertParseFailure(parser, "1" + INVALID_PHONE_DESC, Phone.MESSAGE_CONSTRAINTS); // invalid phone
- assertParseFailure(parser, "1" + INVALID_EMAIL_DESC, Email.MESSAGE_CONSTRAINTS); // invalid email
- assertParseFailure(parser, "1" + INVALID_ADDRESS_DESC, Address.MESSAGE_CONSTRAINTS); // invalid address
- assertParseFailure(parser, "1" + INVALID_TAG_DESC, Tag.MESSAGE_CONSTRAINTS); // invalid tag
-
- // invalid phone followed by valid email
- assertParseFailure(parser, "1" + INVALID_PHONE_DESC + EMAIL_DESC_AMY, Phone.MESSAGE_CONSTRAINTS);
-
- // while parsing {@code PREFIX_TAG} alone will reset the tags of the {@code Person} being edited,
- // parsing it together with a valid tag results in error
- assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_DESC_HUSBAND + TAG_EMPTY, Tag.MESSAGE_CONSTRAINTS);
- assertParseFailure(parser, "1" + TAG_DESC_FRIEND + TAG_EMPTY + TAG_DESC_HUSBAND, Tag.MESSAGE_CONSTRAINTS);
- assertParseFailure(parser, "1" + TAG_EMPTY + TAG_DESC_FRIEND + TAG_DESC_HUSBAND, Tag.MESSAGE_CONSTRAINTS);
-
- // multiple invalid values, but only the first invalid value is captured
- assertParseFailure(parser, "1" + INVALID_NAME_DESC + INVALID_EMAIL_DESC + VALID_ADDRESS_AMY + VALID_PHONE_AMY,
- Name.MESSAGE_CONSTRAINTS);
- }
-
- @Test
- public void parse_allFieldsSpecified_success() {
- Index targetIndex = INDEX_SECOND_PERSON;
- String userInput = targetIndex.getOneBased() + PHONE_DESC_BOB + TAG_DESC_HUSBAND
- + EMAIL_DESC_AMY + ADDRESS_DESC_AMY + NAME_DESC_AMY + TAG_DESC_FRIEND;
-
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY)
- .withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY)
- .withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND).build();
- EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
-
- assertParseSuccess(parser, userInput, expectedCommand);
- }
-
- @Test
- public void parse_someFieldsSpecified_success() {
- Index targetIndex = INDEX_FIRST_PERSON;
- String userInput = targetIndex.getOneBased() + PHONE_DESC_BOB + EMAIL_DESC_AMY;
-
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_BOB)
- .withEmail(VALID_EMAIL_AMY).build();
- EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
-
- assertParseSuccess(parser, userInput, expectedCommand);
- }
-
- @Test
- public void parse_oneFieldSpecified_success() {
- // name
- Index targetIndex = INDEX_THIRD_PERSON;
- String userInput = targetIndex.getOneBased() + NAME_DESC_AMY;
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY).build();
- EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
- assertParseSuccess(parser, userInput, expectedCommand);
-
- // phone
- userInput = targetIndex.getOneBased() + PHONE_DESC_AMY;
- descriptor = new EditPersonDescriptorBuilder().withPhone(VALID_PHONE_AMY).build();
- expectedCommand = new EditCommand(targetIndex, descriptor);
- assertParseSuccess(parser, userInput, expectedCommand);
-
- // email
- userInput = targetIndex.getOneBased() + EMAIL_DESC_AMY;
- descriptor = new EditPersonDescriptorBuilder().withEmail(VALID_EMAIL_AMY).build();
- expectedCommand = new EditCommand(targetIndex, descriptor);
- assertParseSuccess(parser, userInput, expectedCommand);
-
- // address
- userInput = targetIndex.getOneBased() + ADDRESS_DESC_AMY;
- descriptor = new EditPersonDescriptorBuilder().withAddress(VALID_ADDRESS_AMY).build();
- expectedCommand = new EditCommand(targetIndex, descriptor);
- assertParseSuccess(parser, userInput, expectedCommand);
-
- // tags
- userInput = targetIndex.getOneBased() + TAG_DESC_FRIEND;
- descriptor = new EditPersonDescriptorBuilder().withTags(VALID_TAG_FRIEND).build();
- expectedCommand = new EditCommand(targetIndex, descriptor);
- assertParseSuccess(parser, userInput, expectedCommand);
- }
-
- @Test
- public void parse_multipleRepeatedFields_failure() {
- // More extensive testing of duplicate parameter detections is done in
- // AddCommandParserTest#parse_repeatedNonTagValue_failure()
-
- // valid followed by invalid
- Index targetIndex = INDEX_FIRST_PERSON;
- String userInput = targetIndex.getOneBased() + INVALID_PHONE_DESC + PHONE_DESC_BOB;
-
- assertParseFailure(parser, userInput, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE));
-
- // invalid followed by valid
- userInput = targetIndex.getOneBased() + PHONE_DESC_BOB + INVALID_PHONE_DESC;
-
- assertParseFailure(parser, userInput, Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE));
-
- // mulltiple valid fields repeated
- userInput = targetIndex.getOneBased() + PHONE_DESC_AMY + ADDRESS_DESC_AMY + EMAIL_DESC_AMY
- + TAG_DESC_FRIEND + PHONE_DESC_AMY + ADDRESS_DESC_AMY + EMAIL_DESC_AMY + TAG_DESC_FRIEND
- + PHONE_DESC_BOB + ADDRESS_DESC_BOB + EMAIL_DESC_BOB + TAG_DESC_HUSBAND;
-
- assertParseFailure(parser, userInput,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS));
-
- // multiple invalid values
- userInput = targetIndex.getOneBased() + INVALID_PHONE_DESC + INVALID_ADDRESS_DESC + INVALID_EMAIL_DESC
- + INVALID_PHONE_DESC + INVALID_ADDRESS_DESC + INVALID_EMAIL_DESC;
-
- assertParseFailure(parser, userInput,
- Messages.getErrorMessageForDuplicatePrefixes(PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS));
- }
-
- @Test
- public void parse_resetTags_success() {
- Index targetIndex = INDEX_THIRD_PERSON;
- String userInput = targetIndex.getOneBased() + TAG_EMPTY;
-
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withTags().build();
- EditCommand expectedCommand = new EditCommand(targetIndex, descriptor);
-
- assertParseSuccess(parser, userInput, expectedCommand);
- }
-}
diff --git a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java b/src/test/java/seedu/address/logic/parser/ParserUtilTest.java
deleted file mode 100644
index 4256788b1a7..00000000000
--- a/src/test/java/seedu/address/logic/parser/ParserUtilTest.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package seedu.address.logic.parser;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.parser.ParserUtil.MESSAGE_INVALID_INDEX;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-
-public class ParserUtilTest {
- private static final String INVALID_NAME = "R@chel";
- private static final String INVALID_PHONE = "+651234";
- private static final String INVALID_ADDRESS = " ";
- private static final String INVALID_EMAIL = "example.com";
- private static final String INVALID_TAG = "#friend";
-
- private static final String VALID_NAME = "Rachel Walker";
- private static final String VALID_PHONE = "123456";
- private static final String VALID_ADDRESS = "123 Main Street #0505";
- private static final String VALID_EMAIL = "rachel@example.com";
- private static final String VALID_TAG_1 = "friend";
- private static final String VALID_TAG_2 = "neighbour";
-
- private static final String WHITESPACE = " \t\r\n";
-
- @Test
- public void parseIndex_invalidInput_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseIndex("10 a"));
- }
-
- @Test
- public void parseIndex_outOfRangeInput_throwsParseException() {
- assertThrows(ParseException.class, MESSAGE_INVALID_INDEX, ()
- -> ParserUtil.parseIndex(Long.toString(Integer.MAX_VALUE + 1)));
- }
-
- @Test
- public void parseIndex_validInput_success() throws Exception {
- // No whitespaces
- assertEquals(INDEX_FIRST_PERSON, ParserUtil.parseIndex("1"));
-
- // Leading and trailing whitespaces
- assertEquals(INDEX_FIRST_PERSON, ParserUtil.parseIndex(" 1 "));
- }
-
- @Test
- public void parseName_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parseName((String) null));
- }
-
- @Test
- public void parseName_invalidValue_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseName(INVALID_NAME));
- }
-
- @Test
- public void parseName_validValueWithoutWhitespace_returnsName() throws Exception {
- Name expectedName = new Name(VALID_NAME);
- assertEquals(expectedName, ParserUtil.parseName(VALID_NAME));
- }
-
- @Test
- public void parseName_validValueWithWhitespace_returnsTrimmedName() throws Exception {
- String nameWithWhitespace = WHITESPACE + VALID_NAME + WHITESPACE;
- Name expectedName = new Name(VALID_NAME);
- assertEquals(expectedName, ParserUtil.parseName(nameWithWhitespace));
- }
-
- @Test
- public void parsePhone_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parsePhone((String) null));
- }
-
- @Test
- public void parsePhone_invalidValue_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parsePhone(INVALID_PHONE));
- }
-
- @Test
- public void parsePhone_validValueWithoutWhitespace_returnsPhone() throws Exception {
- Phone expectedPhone = new Phone(VALID_PHONE);
- assertEquals(expectedPhone, ParserUtil.parsePhone(VALID_PHONE));
- }
-
- @Test
- public void parsePhone_validValueWithWhitespace_returnsTrimmedPhone() throws Exception {
- String phoneWithWhitespace = WHITESPACE + VALID_PHONE + WHITESPACE;
- Phone expectedPhone = new Phone(VALID_PHONE);
- assertEquals(expectedPhone, ParserUtil.parsePhone(phoneWithWhitespace));
- }
-
- @Test
- public void parseAddress_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parseAddress((String) null));
- }
-
- @Test
- public void parseAddress_invalidValue_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseAddress(INVALID_ADDRESS));
- }
-
- @Test
- public void parseAddress_validValueWithoutWhitespace_returnsAddress() throws Exception {
- Address expectedAddress = new Address(VALID_ADDRESS);
- assertEquals(expectedAddress, ParserUtil.parseAddress(VALID_ADDRESS));
- }
-
- @Test
- public void parseAddress_validValueWithWhitespace_returnsTrimmedAddress() throws Exception {
- String addressWithWhitespace = WHITESPACE + VALID_ADDRESS + WHITESPACE;
- Address expectedAddress = new Address(VALID_ADDRESS);
- assertEquals(expectedAddress, ParserUtil.parseAddress(addressWithWhitespace));
- }
-
- @Test
- public void parseEmail_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parseEmail((String) null));
- }
-
- @Test
- public void parseEmail_invalidValue_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseEmail(INVALID_EMAIL));
- }
-
- @Test
- public void parseEmail_validValueWithoutWhitespace_returnsEmail() throws Exception {
- Email expectedEmail = new Email(VALID_EMAIL);
- assertEquals(expectedEmail, ParserUtil.parseEmail(VALID_EMAIL));
- }
-
- @Test
- public void parseEmail_validValueWithWhitespace_returnsTrimmedEmail() throws Exception {
- String emailWithWhitespace = WHITESPACE + VALID_EMAIL + WHITESPACE;
- Email expectedEmail = new Email(VALID_EMAIL);
- assertEquals(expectedEmail, ParserUtil.parseEmail(emailWithWhitespace));
- }
-
- @Test
- public void parseTag_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parseTag(null));
- }
-
- @Test
- public void parseTag_invalidValue_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseTag(INVALID_TAG));
- }
-
- @Test
- public void parseTag_validValueWithoutWhitespace_returnsTag() throws Exception {
- Tag expectedTag = new Tag(VALID_TAG_1);
- assertEquals(expectedTag, ParserUtil.parseTag(VALID_TAG_1));
- }
-
- @Test
- public void parseTag_validValueWithWhitespace_returnsTrimmedTag() throws Exception {
- String tagWithWhitespace = WHITESPACE + VALID_TAG_1 + WHITESPACE;
- Tag expectedTag = new Tag(VALID_TAG_1);
- assertEquals(expectedTag, ParserUtil.parseTag(tagWithWhitespace));
- }
-
- @Test
- public void parseTags_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> ParserUtil.parseTags(null));
- }
-
- @Test
- public void parseTags_collectionWithInvalidTags_throwsParseException() {
- assertThrows(ParseException.class, () -> ParserUtil.parseTags(Arrays.asList(VALID_TAG_1, INVALID_TAG)));
- }
-
- @Test
- public void parseTags_emptyCollection_returnsEmptySet() throws Exception {
- assertTrue(ParserUtil.parseTags(Collections.emptyList()).isEmpty());
- }
-
- @Test
- public void parseTags_collectionWithValidTags_returnsTagSet() throws Exception {
- Set actualTagSet = ParserUtil.parseTags(Arrays.asList(VALID_TAG_1, VALID_TAG_2));
- Set expectedTagSet = new HashSet(Arrays.asList(new Tag(VALID_TAG_1), new Tag(VALID_TAG_2)));
-
- assertEquals(expectedTagSet, actualTagSet);
- }
-}
diff --git a/src/test/java/seedu/address/model/AddressBookTest.java b/src/test/java/seedu/address/model/AddressBookTest.java
deleted file mode 100644
index 68c8c5ba4d5..00000000000
--- a/src/test/java/seedu/address/model/AddressBookTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package seedu.address.model;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.junit.jupiter.api.Test;
-
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.exceptions.DuplicatePersonException;
-import seedu.address.testutil.PersonBuilder;
-
-public class AddressBookTest {
-
- private final AddressBook addressBook = new AddressBook();
-
- @Test
- public void constructor() {
- assertEquals(Collections.emptyList(), addressBook.getPersonList());
- }
-
- @Test
- public void resetData_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> addressBook.resetData(null));
- }
-
- @Test
- public void resetData_withValidReadOnlyAddressBook_replacesData() {
- AddressBook newData = getTypicalAddressBook();
- addressBook.resetData(newData);
- assertEquals(newData, addressBook);
- }
-
- @Test
- public void resetData_withDuplicatePersons_throwsDuplicatePersonException() {
- // Two persons with the same identity fields
- Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND)
- .build();
- List newPersons = Arrays.asList(ALICE, editedAlice);
- AddressBookStub newData = new AddressBookStub(newPersons);
-
- assertThrows(DuplicatePersonException.class, () -> addressBook.resetData(newData));
- }
-
- @Test
- public void hasPerson_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> addressBook.hasPerson(null));
- }
-
- @Test
- public void hasPerson_personNotInAddressBook_returnsFalse() {
- assertFalse(addressBook.hasPerson(ALICE));
- }
-
- @Test
- public void hasPerson_personInAddressBook_returnsTrue() {
- addressBook.addPerson(ALICE);
- assertTrue(addressBook.hasPerson(ALICE));
- }
-
- @Test
- public void hasPerson_personWithSameIdentityFieldsInAddressBook_returnsTrue() {
- addressBook.addPerson(ALICE);
- Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND)
- .build();
- assertTrue(addressBook.hasPerson(editedAlice));
- }
-
- @Test
- public void getPersonList_modifyList_throwsUnsupportedOperationException() {
- assertThrows(UnsupportedOperationException.class, () -> addressBook.getPersonList().remove(0));
- }
-
- @Test
- public void toStringMethod() {
- String expected = AddressBook.class.getCanonicalName() + "{persons=" + addressBook.getPersonList() + "}";
- assertEquals(expected, addressBook.toString());
- }
-
- /**
- * A stub ReadOnlyAddressBook whose persons list can violate interface constraints.
- */
- private static class AddressBookStub implements ReadOnlyAddressBook {
- private final ObservableList persons = FXCollections.observableArrayList();
-
- AddressBookStub(Collection persons) {
- this.persons.setAll(persons);
- }
-
- @Override
- public ObservableList getPersonList() {
- return persons;
- }
- }
-
-}
diff --git a/src/test/java/seedu/address/model/person/AddressTest.java b/src/test/java/seedu/address/model/person/AddressTest.java
deleted file mode 100644
index 314885eca26..00000000000
--- a/src/test/java/seedu/address/model/person/AddressTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package seedu.address.model.person;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
-
-import org.junit.jupiter.api.Test;
-
-public class AddressTest {
-
- @Test
- public void constructor_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new Address(null));
- }
-
- @Test
- public void constructor_invalidAddress_throwsIllegalArgumentException() {
- String invalidAddress = "";
- assertThrows(IllegalArgumentException.class, () -> new Address(invalidAddress));
- }
-
- @Test
- public void isValidAddress() {
- // null address
- assertThrows(NullPointerException.class, () -> Address.isValidAddress(null));
-
- // invalid addresses
- assertFalse(Address.isValidAddress("")); // empty string
- assertFalse(Address.isValidAddress(" ")); // spaces only
-
- // valid addresses
- assertTrue(Address.isValidAddress("Blk 456, Den Road, #01-355"));
- assertTrue(Address.isValidAddress("-")); // one character
- assertTrue(Address.isValidAddress("Leng Inc; 1234 Market St; San Francisco CA 2349879; USA")); // long address
- }
-
- @Test
- public void equals() {
- Address address = new Address("Valid Address");
-
- // same values -> returns true
- assertTrue(address.equals(new Address("Valid Address")));
-
- // same object -> returns true
- assertTrue(address.equals(address));
-
- // null -> returns false
- assertFalse(address.equals(null));
-
- // different types -> returns false
- assertFalse(address.equals(5.0f));
-
- // different values -> returns false
- assertFalse(address.equals(new Address("Other Valid Address")));
- }
-}
diff --git a/src/test/java/seedu/address/model/person/EmailTest.java b/src/test/java/seedu/address/model/person/EmailTest.java
deleted file mode 100644
index f08cdff0a64..00000000000
--- a/src/test/java/seedu/address/model/person/EmailTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package seedu.address.model.person;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
-
-import org.junit.jupiter.api.Test;
-
-public class EmailTest {
-
- @Test
- public void constructor_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new Email(null));
- }
-
- @Test
- public void constructor_invalidEmail_throwsIllegalArgumentException() {
- String invalidEmail = "";
- assertThrows(IllegalArgumentException.class, () -> new Email(invalidEmail));
- }
-
- @Test
- public void isValidEmail() {
- // null email
- assertThrows(NullPointerException.class, () -> Email.isValidEmail(null));
-
- // blank email
- assertFalse(Email.isValidEmail("")); // empty string
- assertFalse(Email.isValidEmail(" ")); // spaces only
-
- // missing parts
- assertFalse(Email.isValidEmail("@example.com")); // missing local part
- assertFalse(Email.isValidEmail("peterjackexample.com")); // missing '@' symbol
- assertFalse(Email.isValidEmail("peterjack@")); // missing domain name
-
- // invalid parts
- assertFalse(Email.isValidEmail("peterjack@-")); // invalid domain name
- assertFalse(Email.isValidEmail("peterjack@exam_ple.com")); // underscore in domain name
- assertFalse(Email.isValidEmail("peter jack@example.com")); // spaces in local part
- assertFalse(Email.isValidEmail("peterjack@exam ple.com")); // spaces in domain name
- assertFalse(Email.isValidEmail(" peterjack@example.com")); // leading space
- assertFalse(Email.isValidEmail("peterjack@example.com ")); // trailing space
- assertFalse(Email.isValidEmail("peterjack@@example.com")); // double '@' symbol
- assertFalse(Email.isValidEmail("peter@jack@example.com")); // '@' symbol in local part
- assertFalse(Email.isValidEmail("-peterjack@example.com")); // local part starts with a hyphen
- assertFalse(Email.isValidEmail("peterjack-@example.com")); // local part ends with a hyphen
- assertFalse(Email.isValidEmail("peter..jack@example.com")); // local part has two consecutive periods
- assertFalse(Email.isValidEmail("peterjack@example@com")); // '@' symbol in domain name
- assertFalse(Email.isValidEmail("peterjack@.example.com")); // domain name starts with a period
- assertFalse(Email.isValidEmail("peterjack@example.com.")); // domain name ends with a period
- assertFalse(Email.isValidEmail("peterjack@-example.com")); // domain name starts with a hyphen
- assertFalse(Email.isValidEmail("peterjack@example.com-")); // domain name ends with a hyphen
- assertFalse(Email.isValidEmail("peterjack@example.c")); // top level domain has less than two chars
-
- // valid email
- assertTrue(Email.isValidEmail("PeterJack_1190@example.com")); // underscore in local part
- assertTrue(Email.isValidEmail("PeterJack.1190@example.com")); // period in local part
- assertTrue(Email.isValidEmail("PeterJack+1190@example.com")); // '+' symbol in local part
- assertTrue(Email.isValidEmail("PeterJack-1190@example.com")); // hyphen in local part
- assertTrue(Email.isValidEmail("a@bc")); // minimal
- assertTrue(Email.isValidEmail("test@localhost")); // alphabets only
- assertTrue(Email.isValidEmail("123@145")); // numeric local part and domain name
- assertTrue(Email.isValidEmail("a1+be.d@example1.com")); // mixture of alphanumeric and special characters
- assertTrue(Email.isValidEmail("peter_jack@very-very-very-long-example.com")); // long domain name
- assertTrue(Email.isValidEmail("if.you.dream.it_you.can.do.it@example.com")); // long local part
- assertTrue(Email.isValidEmail("e1234567@u.nus.edu")); // more than one period in domain
- }
-
- @Test
- public void equals() {
- Email email = new Email("valid@email");
-
- // same values -> returns true
- assertTrue(email.equals(new Email("valid@email")));
-
- // same object -> returns true
- assertTrue(email.equals(email));
-
- // null -> returns false
- assertFalse(email.equals(null));
-
- // different types -> returns false
- assertFalse(email.equals(5.0f));
-
- // different values -> returns false
- assertFalse(email.equals(new Email("other.valid@email")));
- }
-}
diff --git a/src/test/java/seedu/address/model/person/PersonTest.java b/src/test/java/seedu/address/model/person/PersonTest.java
deleted file mode 100644
index 31a10d156c9..00000000000
--- a/src/test/java/seedu/address/model/person/PersonTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package seedu.address.model.person;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.BOB;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.testutil.PersonBuilder;
-
-public class PersonTest {
-
- @Test
- public void asObservableList_modifyList_throwsUnsupportedOperationException() {
- Person person = new PersonBuilder().build();
- assertThrows(UnsupportedOperationException.class, () -> person.getTags().remove(0));
- }
-
- @Test
- public void isSamePerson() {
- // same object -> returns true
- assertTrue(ALICE.isSamePerson(ALICE));
-
- // null -> returns false
- assertFalse(ALICE.isSamePerson(null));
-
- // same name, all other attributes different -> returns true
- Person editedAlice = new PersonBuilder(ALICE).withPhone(VALID_PHONE_BOB).withEmail(VALID_EMAIL_BOB)
- .withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND).build();
- assertTrue(ALICE.isSamePerson(editedAlice));
-
- // different name, all other attributes same -> returns false
- editedAlice = new PersonBuilder(ALICE).withName(VALID_NAME_BOB).build();
- assertFalse(ALICE.isSamePerson(editedAlice));
-
- // name differs in case, all other attributes same -> returns false
- Person editedBob = new PersonBuilder(BOB).withName(VALID_NAME_BOB.toLowerCase()).build();
- assertFalse(BOB.isSamePerson(editedBob));
-
- // name has trailing spaces, all other attributes same -> returns false
- String nameWithTrailingSpaces = VALID_NAME_BOB + " ";
- editedBob = new PersonBuilder(BOB).withName(nameWithTrailingSpaces).build();
- assertFalse(BOB.isSamePerson(editedBob));
- }
-
- @Test
- public void equals() {
- // same values -> returns true
- Person aliceCopy = new PersonBuilder(ALICE).build();
- assertTrue(ALICE.equals(aliceCopy));
-
- // same object -> returns true
- assertTrue(ALICE.equals(ALICE));
-
- // null -> returns false
- assertFalse(ALICE.equals(null));
-
- // different type -> returns false
- assertFalse(ALICE.equals(5));
-
- // different person -> returns false
- assertFalse(ALICE.equals(BOB));
-
- // different name -> returns false
- Person editedAlice = new PersonBuilder(ALICE).withName(VALID_NAME_BOB).build();
- assertFalse(ALICE.equals(editedAlice));
-
- // different phone -> returns false
- editedAlice = new PersonBuilder(ALICE).withPhone(VALID_PHONE_BOB).build();
- assertFalse(ALICE.equals(editedAlice));
-
- // different email -> returns false
- editedAlice = new PersonBuilder(ALICE).withEmail(VALID_EMAIL_BOB).build();
- assertFalse(ALICE.equals(editedAlice));
-
- // different address -> returns false
- editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).build();
- assertFalse(ALICE.equals(editedAlice));
-
- // different tags -> returns false
- editedAlice = new PersonBuilder(ALICE).withTags(VALID_TAG_HUSBAND).build();
- assertFalse(ALICE.equals(editedAlice));
- }
-
- @Test
- public void toStringMethod() {
- String expected = Person.class.getCanonicalName() + "{name=" + ALICE.getName() + ", phone=" + ALICE.getPhone()
- + ", email=" + ALICE.getEmail() + ", address=" + ALICE.getAddress() + ", tags=" + ALICE.getTags() + "}";
- assertEquals(expected, ALICE.toString());
- }
-}
diff --git a/src/test/java/seedu/address/model/person/PhoneTest.java b/src/test/java/seedu/address/model/person/PhoneTest.java
deleted file mode 100644
index deaaa5ba190..00000000000
--- a/src/test/java/seedu/address/model/person/PhoneTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package seedu.address.model.person;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
-
-import org.junit.jupiter.api.Test;
-
-public class PhoneTest {
-
- @Test
- public void constructor_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new Phone(null));
- }
-
- @Test
- public void constructor_invalidPhone_throwsIllegalArgumentException() {
- String invalidPhone = "";
- assertThrows(IllegalArgumentException.class, () -> new Phone(invalidPhone));
- }
-
- @Test
- public void isValidPhone() {
- // null phone number
- assertThrows(NullPointerException.class, () -> Phone.isValidPhone(null));
-
- // invalid phone numbers
- assertFalse(Phone.isValidPhone("")); // empty string
- assertFalse(Phone.isValidPhone(" ")); // spaces only
- assertFalse(Phone.isValidPhone("91")); // less than 3 numbers
- assertFalse(Phone.isValidPhone("phone")); // non-numeric
- assertFalse(Phone.isValidPhone("9011p041")); // alphabets within digits
- assertFalse(Phone.isValidPhone("9312 1534")); // spaces within digits
-
- // valid phone numbers
- assertTrue(Phone.isValidPhone("911")); // exactly 3 numbers
- assertTrue(Phone.isValidPhone("93121534"));
- assertTrue(Phone.isValidPhone("124293842033123")); // long phone numbers
- }
-
- @Test
- public void equals() {
- Phone phone = new Phone("999");
-
- // same values -> returns true
- assertTrue(phone.equals(new Phone("999")));
-
- // same object -> returns true
- assertTrue(phone.equals(phone));
-
- // null -> returns false
- assertFalse(phone.equals(null));
-
- // different types -> returns false
- assertFalse(phone.equals(5.0f));
-
- // different values -> returns false
- assertFalse(phone.equals(new Phone("995")));
- }
-}
diff --git a/src/test/java/seedu/address/model/person/UniquePersonListTest.java b/src/test/java/seedu/address/model/person/UniquePersonListTest.java
deleted file mode 100644
index 17ae501df08..00000000000
--- a/src/test/java/seedu/address/model/person/UniquePersonListTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-package seedu.address.model.person;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.BOB;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.model.person.exceptions.DuplicatePersonException;
-import seedu.address.model.person.exceptions.PersonNotFoundException;
-import seedu.address.testutil.PersonBuilder;
-
-public class UniquePersonListTest {
-
- private final UniquePersonList uniquePersonList = new UniquePersonList();
-
- @Test
- public void contains_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.contains(null));
- }
-
- @Test
- public void contains_personNotInList_returnsFalse() {
- assertFalse(uniquePersonList.contains(ALICE));
- }
-
- @Test
- public void contains_personInList_returnsTrue() {
- uniquePersonList.add(ALICE);
- assertTrue(uniquePersonList.contains(ALICE));
- }
-
- @Test
- public void contains_personWithSameIdentityFieldsInList_returnsTrue() {
- uniquePersonList.add(ALICE);
- Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND)
- .build();
- assertTrue(uniquePersonList.contains(editedAlice));
- }
-
- @Test
- public void add_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.add(null));
- }
-
- @Test
- public void add_duplicatePerson_throwsDuplicatePersonException() {
- uniquePersonList.add(ALICE);
- assertThrows(DuplicatePersonException.class, () -> uniquePersonList.add(ALICE));
- }
-
- @Test
- public void setPerson_nullTargetPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.setPerson(null, ALICE));
- }
-
- @Test
- public void setPerson_nullEditedPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.setPerson(ALICE, null));
- }
-
- @Test
- public void setPerson_targetPersonNotInList_throwsPersonNotFoundException() {
- assertThrows(PersonNotFoundException.class, () -> uniquePersonList.setPerson(ALICE, ALICE));
- }
-
- @Test
- public void setPerson_editedPersonIsSamePerson_success() {
- uniquePersonList.add(ALICE);
- uniquePersonList.setPerson(ALICE, ALICE);
- UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(ALICE);
- assertEquals(expectedUniquePersonList, uniquePersonList);
- }
-
- @Test
- public void setPerson_editedPersonHasSameIdentity_success() {
- uniquePersonList.add(ALICE);
- Person editedAlice = new PersonBuilder(ALICE).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND)
- .build();
- uniquePersonList.setPerson(ALICE, editedAlice);
- UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(editedAlice);
- assertEquals(expectedUniquePersonList, uniquePersonList);
- }
-
- @Test
- public void setPerson_editedPersonHasDifferentIdentity_success() {
- uniquePersonList.add(ALICE);
- uniquePersonList.setPerson(ALICE, BOB);
- UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(BOB);
- assertEquals(expectedUniquePersonList, uniquePersonList);
- }
-
- @Test
- public void setPerson_editedPersonHasNonUniqueIdentity_throwsDuplicatePersonException() {
- uniquePersonList.add(ALICE);
- uniquePersonList.add(BOB);
- assertThrows(DuplicatePersonException.class, () -> uniquePersonList.setPerson(ALICE, BOB));
- }
-
- @Test
- public void remove_nullPerson_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.remove(null));
- }
-
- @Test
- public void remove_personDoesNotExist_throwsPersonNotFoundException() {
- assertThrows(PersonNotFoundException.class, () -> uniquePersonList.remove(ALICE));
- }
-
- @Test
- public void remove_existingPerson_removesPerson() {
- uniquePersonList.add(ALICE);
- uniquePersonList.remove(ALICE);
- UniquePersonList expectedUniquePersonList = new UniquePersonList();
- assertEquals(expectedUniquePersonList, uniquePersonList);
- }
-
- @Test
- public void setPersons_nullUniquePersonList_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.setPersons((UniquePersonList) null));
- }
-
- @Test
- public void setPersons_uniquePersonList_replacesOwnListWithProvidedUniquePersonList() {
- uniquePersonList.add(ALICE);
- UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(BOB);
- uniquePersonList.setPersons(expectedUniquePersonList);
- assertEquals(expectedUniquePersonList, uniquePersonList);
- }
-
- @Test
- public void setPersons_nullList_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> uniquePersonList.setPersons((List) null));
- }
-
- @Test
- public void setPersons_list_replacesOwnListWithProvidedList() {
- uniquePersonList.add(ALICE);
- List personList = Collections.singletonList(BOB);
- uniquePersonList.setPersons(personList);
- UniquePersonList expectedUniquePersonList = new UniquePersonList();
- expectedUniquePersonList.add(BOB);
- assertEquals(expectedUniquePersonList, uniquePersonList);
- }
-
- @Test
- public void setPersons_listWithDuplicatePersons_throwsDuplicatePersonException() {
- List listWithDuplicatePersons = Arrays.asList(ALICE, ALICE);
- assertThrows(DuplicatePersonException.class, () -> uniquePersonList.setPersons(listWithDuplicatePersons));
- }
-
- @Test
- public void asUnmodifiableObservableList_modifyList_throwsUnsupportedOperationException() {
- assertThrows(UnsupportedOperationException.class, ()
- -> uniquePersonList.asUnmodifiableObservableList().remove(0));
- }
-
- @Test
- public void toStringMethod() {
- assertEquals(uniquePersonList.asUnmodifiableObservableList().toString(), uniquePersonList.toString());
- }
-}
diff --git a/src/test/java/seedu/address/model/tag/TagTest.java b/src/test/java/seedu/address/model/tag/TagTest.java
deleted file mode 100644
index 64d07d79ee2..00000000000
--- a/src/test/java/seedu/address/model/tag/TagTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package seedu.address.model.tag;
-
-import static seedu.address.testutil.Assert.assertThrows;
-
-import org.junit.jupiter.api.Test;
-
-public class TagTest {
-
- @Test
- public void constructor_null_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> new Tag(null));
- }
-
- @Test
- public void constructor_invalidTagName_throwsIllegalArgumentException() {
- String invalidTagName = "";
- assertThrows(IllegalArgumentException.class, () -> new Tag(invalidTagName));
- }
-
- @Test
- public void isValidTagName() {
- // null tag name
- assertThrows(NullPointerException.class, () -> Tag.isValidTagName(null));
- }
-
-}
diff --git a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java b/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java
deleted file mode 100644
index 83b11331cdb..00000000000
--- a/src/test/java/seedu/address/storage/JsonAdaptedPersonTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package seedu.address.storage;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static seedu.address.storage.JsonAdaptedPerson.MISSING_FIELD_MESSAGE_FORMAT;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.BENSON;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Phone;
-
-public class JsonAdaptedPersonTest {
- private static final String INVALID_NAME = "R@chel";
- private static final String INVALID_PHONE = "+651234";
- private static final String INVALID_ADDRESS = " ";
- private static final String INVALID_EMAIL = "example.com";
- private static final String INVALID_TAG = "#friend";
-
- private static final String VALID_NAME = BENSON.getName().toString();
- private static final String VALID_PHONE = BENSON.getPhone().toString();
- private static final String VALID_EMAIL = BENSON.getEmail().toString();
- private static final String VALID_ADDRESS = BENSON.getAddress().toString();
- private static final List VALID_TAGS = BENSON.getTags().stream()
- .map(JsonAdaptedTag::new)
- .collect(Collectors.toList());
-
- @Test
- public void toModelType_validPersonDetails_returnsPerson() throws Exception {
- JsonAdaptedPerson person = new JsonAdaptedPerson(BENSON);
- assertEquals(BENSON, person.toModelType());
- }
-
- @Test
- public void toModelType_invalidName_throwsIllegalValueException() {
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = Name.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_nullName_throwsIllegalValueException() {
- JsonAdaptedPerson person = new JsonAdaptedPerson(null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName());
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_invalidPhone_throwsIllegalValueException() {
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = Phone.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_nullPhone_throwsIllegalValueException() {
- JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, null, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName());
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_invalidEmail_throwsIllegalValueException() {
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = Email.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_nullEmail_throwsIllegalValueException() {
- JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, null, VALID_ADDRESS, VALID_TAGS);
- String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName());
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_invalidAddress_throwsIllegalValueException() {
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_ADDRESS, VALID_TAGS);
- String expectedMessage = Address.MESSAGE_CONSTRAINTS;
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_nullAddress_throwsIllegalValueException() {
- JsonAdaptedPerson person = new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, null, VALID_TAGS);
- String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName());
- assertThrows(IllegalValueException.class, expectedMessage, person::toModelType);
- }
-
- @Test
- public void toModelType_invalidTags_throwsIllegalValueException() {
- List invalidTags = new ArrayList<>(VALID_TAGS);
- invalidTags.add(new JsonAdaptedTag(INVALID_TAG));
- JsonAdaptedPerson person =
- new JsonAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, invalidTags);
- assertThrows(IllegalValueException.class, person::toModelType);
- }
-
-}
diff --git a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java b/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java
deleted file mode 100644
index 4e5ce9200c8..00000000000
--- a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package seedu.address.storage;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
-import static seedu.address.testutil.TypicalPersons.HOON;
-import static seedu.address.testutil.TypicalPersons.IDA;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.io.TempDir;
-
-import seedu.address.commons.exceptions.DataLoadingException;
-import seedu.address.model.AddressBook;
-import seedu.address.model.ReadOnlyAddressBook;
-
-public class JsonAddressBookStorageTest {
- private static final Path TEST_DATA_FOLDER = Paths.get("src", "test", "data", "JsonAddressBookStorageTest");
-
- @TempDir
- public Path testFolder;
-
- @Test
- public void readAddressBook_nullFilePath_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> readAddressBook(null));
- }
-
- private java.util.Optional readAddressBook(String filePath) throws Exception {
- return new JsonAddressBookStorage(Paths.get(filePath)).readAddressBook(addToTestDataPathIfNotNull(filePath));
- }
-
- private Path addToTestDataPathIfNotNull(String prefsFileInTestDataFolder) {
- return prefsFileInTestDataFolder != null
- ? TEST_DATA_FOLDER.resolve(prefsFileInTestDataFolder)
- : null;
- }
-
- @Test
- public void read_missingFile_emptyResult() throws Exception {
- assertFalse(readAddressBook("NonExistentFile.json").isPresent());
- }
-
- @Test
- public void read_notJsonFormat_exceptionThrown() {
- assertThrows(DataLoadingException.class, () -> readAddressBook("notJsonFormatAddressBook.json"));
- }
-
- @Test
- public void readAddressBook_invalidPersonAddressBook_throwDataLoadingException() {
- assertThrows(DataLoadingException.class, () -> readAddressBook("invalidPersonAddressBook.json"));
- }
-
- @Test
- public void readAddressBook_invalidAndValidPersonAddressBook_throwDataLoadingException() {
- assertThrows(DataLoadingException.class, () -> readAddressBook("invalidAndValidPersonAddressBook.json"));
- }
-
- @Test
- public void readAndSaveAddressBook_allInOrder_success() throws Exception {
- Path filePath = testFolder.resolve("TempAddressBook.json");
- AddressBook original = getTypicalAddressBook();
- JsonAddressBookStorage jsonAddressBookStorage = new JsonAddressBookStorage(filePath);
-
- // Save in new file and read back
- jsonAddressBookStorage.saveAddressBook(original, filePath);
- ReadOnlyAddressBook readBack = jsonAddressBookStorage.readAddressBook(filePath).get();
- assertEquals(original, new AddressBook(readBack));
-
- // Modify data, overwrite exiting file, and read back
- original.addPerson(HOON);
- original.removePerson(ALICE);
- jsonAddressBookStorage.saveAddressBook(original, filePath);
- readBack = jsonAddressBookStorage.readAddressBook(filePath).get();
- assertEquals(original, new AddressBook(readBack));
-
- // Save and read without specifying file path
- original.addPerson(IDA);
- jsonAddressBookStorage.saveAddressBook(original); // file path not specified
- readBack = jsonAddressBookStorage.readAddressBook().get(); // file path not specified
- assertEquals(original, new AddressBook(readBack));
-
- }
-
- @Test
- public void saveAddressBook_nullAddressBook_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> saveAddressBook(null, "SomeFile.json"));
- }
-
- /**
- * Saves {@code addressBook} at the specified {@code filePath}.
- */
- private void saveAddressBook(ReadOnlyAddressBook addressBook, String filePath) {
- try {
- new JsonAddressBookStorage(Paths.get(filePath))
- .saveAddressBook(addressBook, addToTestDataPathIfNotNull(filePath));
- } catch (IOException ioe) {
- throw new AssertionError("There should not be an error writing to the file.", ioe);
- }
- }
-
- @Test
- public void saveAddressBook_nullFilePath_throwsNullPointerException() {
- assertThrows(NullPointerException.class, () -> saveAddressBook(new AddressBook(), null));
- }
-}
diff --git a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java b/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java
deleted file mode 100644
index 188c9058d20..00000000000
--- a/src/test/java/seedu/address/storage/JsonSerializableAddressBookTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package seedu.address.storage;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static seedu.address.testutil.Assert.assertThrows;
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import org.junit.jupiter.api.Test;
-
-import seedu.address.commons.exceptions.IllegalValueException;
-import seedu.address.commons.util.JsonUtil;
-import seedu.address.model.AddressBook;
-import seedu.address.testutil.TypicalPersons;
-
-public class JsonSerializableAddressBookTest {
-
- private static final Path TEST_DATA_FOLDER = Paths.get("src", "test", "data", "JsonSerializableAddressBookTest");
- private static final Path TYPICAL_PERSONS_FILE = TEST_DATA_FOLDER.resolve("typicalPersonsAddressBook.json");
- private static final Path INVALID_PERSON_FILE = TEST_DATA_FOLDER.resolve("invalidPersonAddressBook.json");
- private static final Path DUPLICATE_PERSON_FILE = TEST_DATA_FOLDER.resolve("duplicatePersonAddressBook.json");
-
- @Test
- public void toModelType_typicalPersonsFile_success() throws Exception {
- JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(TYPICAL_PERSONS_FILE,
- JsonSerializableAddressBook.class).get();
- AddressBook addressBookFromFile = dataFromFile.toModelType();
- AddressBook typicalPersonsAddressBook = TypicalPersons.getTypicalAddressBook();
- assertEquals(addressBookFromFile, typicalPersonsAddressBook);
- }
-
- @Test
- public void toModelType_invalidPersonFile_throwsIllegalValueException() throws Exception {
- JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(INVALID_PERSON_FILE,
- JsonSerializableAddressBook.class).get();
- assertThrows(IllegalValueException.class, dataFromFile::toModelType);
- }
-
- @Test
- public void toModelType_duplicatePersons_throwsIllegalValueException() throws Exception {
- JsonSerializableAddressBook dataFromFile = JsonUtil.readJsonFile(DUPLICATE_PERSON_FILE,
- JsonSerializableAddressBook.class).get();
- assertThrows(IllegalValueException.class, JsonSerializableAddressBook.MESSAGE_DUPLICATE_PERSON,
- dataFromFile::toModelType);
- }
-
-}
diff --git a/src/test/java/seedu/address/storage/StorageManagerTest.java b/src/test/java/seedu/address/storage/StorageManagerTest.java
deleted file mode 100644
index 99a16548970..00000000000
--- a/src/test/java/seedu/address/storage/StorageManagerTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package seedu.address.storage;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
-
-import java.nio.file.Path;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.io.TempDir;
-
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.model.AddressBook;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.UserPrefs;
-
-public class StorageManagerTest {
-
- @TempDir
- public Path testFolder;
-
- private StorageManager storageManager;
-
- @BeforeEach
- public void setUp() {
- JsonAddressBookStorage addressBookStorage = new JsonAddressBookStorage(getTempFilePath("ab"));
- JsonUserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(getTempFilePath("prefs"));
- storageManager = new StorageManager(addressBookStorage, userPrefsStorage);
- }
-
- private Path getTempFilePath(String fileName) {
- return testFolder.resolve(fileName);
- }
-
- @Test
- public void prefsReadSave() throws Exception {
- /*
- * Note: This is an integration test that verifies the StorageManager is properly wired to the
- * {@link JsonUserPrefsStorage} class.
- * More extensive testing of UserPref saving/reading is done in {@link JsonUserPrefsStorageTest} class.
- */
- UserPrefs original = new UserPrefs();
- original.setGuiSettings(new GuiSettings(300, 600, 4, 6));
- storageManager.saveUserPrefs(original);
- UserPrefs retrieved = storageManager.readUserPrefs().get();
- assertEquals(original, retrieved);
- }
-
- @Test
- public void addressBookReadSave() throws Exception {
- /*
- * Note: This is an integration test that verifies the StorageManager is properly wired to the
- * {@link JsonAddressBookStorage} class.
- * More extensive testing of UserPref saving/reading is done in {@link JsonAddressBookStorageTest} class.
- */
- AddressBook original = getTypicalAddressBook();
- storageManager.saveAddressBook(original);
- ReadOnlyAddressBook retrieved = storageManager.readAddressBook().get();
- assertEquals(original, new AddressBook(retrieved));
- }
-
- @Test
- public void getAddressBookFilePath() {
- assertNotNull(storageManager.getAddressBookFilePath());
- }
-
-}
diff --git a/src/test/java/seedu/address/testutil/AddressBookBuilder.java b/src/test/java/seedu/address/testutil/AddressBookBuilder.java
deleted file mode 100644
index d53799fd110..00000000000
--- a/src/test/java/seedu/address/testutil/AddressBookBuilder.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package seedu.address.testutil;
-
-import seedu.address.model.AddressBook;
-import seedu.address.model.person.Person;
-
-/**
- * A utility class to help with building Addressbook objects.
- * Example usage:
- * {@code AddressBook ab = new AddressBookBuilder().withPerson("John", "Doe").build();}
- */
-public class AddressBookBuilder {
-
- private AddressBook addressBook;
-
- public AddressBookBuilder() {
- addressBook = new AddressBook();
- }
-
- public AddressBookBuilder(AddressBook addressBook) {
- this.addressBook = addressBook;
- }
-
- /**
- * Adds a new {@code Person} to the {@code AddressBook} that we are building.
- */
- public AddressBookBuilder withPerson(Person person) {
- addressBook.addPerson(person);
- return this;
- }
-
- public AddressBook build() {
- return addressBook;
- }
-}
diff --git a/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java b/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java
deleted file mode 100644
index 4584bd5044e..00000000000
--- a/src/test/java/seedu/address/testutil/EditPersonDescriptorBuilder.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package seedu.address.testutil;
-
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-
-/**
- * A utility class to help with building EditPersonDescriptor objects.
- */
-public class EditPersonDescriptorBuilder {
-
- private EditPersonDescriptor descriptor;
-
- public EditPersonDescriptorBuilder() {
- descriptor = new EditPersonDescriptor();
- }
-
- public EditPersonDescriptorBuilder(EditPersonDescriptor descriptor) {
- this.descriptor = new EditPersonDescriptor(descriptor);
- }
-
- /**
- * Returns an {@code EditPersonDescriptor} with fields containing {@code person}'s details
- */
- public EditPersonDescriptorBuilder(Person person) {
- descriptor = new EditPersonDescriptor();
- descriptor.setName(person.getName());
- descriptor.setPhone(person.getPhone());
- descriptor.setEmail(person.getEmail());
- descriptor.setAddress(person.getAddress());
- descriptor.setTags(person.getTags());
- }
-
- /**
- * Sets the {@code Name} of the {@code EditPersonDescriptor} that we are building.
- */
- public EditPersonDescriptorBuilder withName(String name) {
- descriptor.setName(new Name(name));
- return this;
- }
-
- /**
- * Sets the {@code Phone} of the {@code EditPersonDescriptor} that we are building.
- */
- public EditPersonDescriptorBuilder withPhone(String phone) {
- descriptor.setPhone(new Phone(phone));
- return this;
- }
-
- /**
- * Sets the {@code Email} of the {@code EditPersonDescriptor} that we are building.
- */
- public EditPersonDescriptorBuilder withEmail(String email) {
- descriptor.setEmail(new Email(email));
- return this;
- }
-
- /**
- * Sets the {@code Address} of the {@code EditPersonDescriptor} that we are building.
- */
- public EditPersonDescriptorBuilder withAddress(String address) {
- descriptor.setAddress(new Address(address));
- return this;
- }
-
- /**
- * Parses the {@code tags} into a {@code Set} and set it to the {@code EditPersonDescriptor}
- * that we are building.
- */
- public EditPersonDescriptorBuilder withTags(String... tags) {
- Set tagSet = Stream.of(tags).map(Tag::new).collect(Collectors.toSet());
- descriptor.setTags(tagSet);
- return this;
- }
-
- public EditPersonDescriptor build() {
- return descriptor;
- }
-}
diff --git a/src/test/java/seedu/address/testutil/PersonBuilder.java b/src/test/java/seedu/address/testutil/PersonBuilder.java
deleted file mode 100644
index 6be381d39ba..00000000000
--- a/src/test/java/seedu/address/testutil/PersonBuilder.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package seedu.address.testutil;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import seedu.address.model.person.Address;
-import seedu.address.model.person.Email;
-import seedu.address.model.person.Name;
-import seedu.address.model.person.Person;
-import seedu.address.model.person.Phone;
-import seedu.address.model.tag.Tag;
-import seedu.address.model.util.SampleDataUtil;
-
-/**
- * A utility class to help with building Person objects.
- */
-public class PersonBuilder {
-
- public static final String DEFAULT_NAME = "Amy Bee";
- public static final String DEFAULT_PHONE = "85355255";
- public static final String DEFAULT_EMAIL = "amy@gmail.com";
- public static final String DEFAULT_ADDRESS = "123, Jurong West Ave 6, #08-111";
-
- private Name name;
- private Phone phone;
- private Email email;
- private Address address;
- private Set tags;
-
- /**
- * Creates a {@code PersonBuilder} with the default details.
- */
- public PersonBuilder() {
- name = new Name(DEFAULT_NAME);
- phone = new Phone(DEFAULT_PHONE);
- email = new Email(DEFAULT_EMAIL);
- address = new Address(DEFAULT_ADDRESS);
- tags = new HashSet<>();
- }
-
- /**
- * Initializes the PersonBuilder with the data of {@code personToCopy}.
- */
- public PersonBuilder(Person personToCopy) {
- name = personToCopy.getName();
- phone = personToCopy.getPhone();
- email = personToCopy.getEmail();
- address = personToCopy.getAddress();
- tags = new HashSet<>(personToCopy.getTags());
- }
-
- /**
- * Sets the {@code Name} of the {@code Person} that we are building.
- */
- public PersonBuilder withName(String name) {
- this.name = new Name(name);
- return this;
- }
-
- /**
- * Parses the {@code tags} into a {@code Set} and set it to the {@code Person} that we are building.
- */
- public PersonBuilder withTags(String ... tags) {
- this.tags = SampleDataUtil.getTagSet(tags);
- return this;
- }
-
- /**
- * Sets the {@code Address} of the {@code Person} that we are building.
- */
- public PersonBuilder withAddress(String address) {
- this.address = new Address(address);
- return this;
- }
-
- /**
- * Sets the {@code Phone} of the {@code Person} that we are building.
- */
- public PersonBuilder withPhone(String phone) {
- this.phone = new Phone(phone);
- return this;
- }
-
- /**
- * Sets the {@code Email} of the {@code Person} that we are building.
- */
- public PersonBuilder withEmail(String email) {
- this.email = new Email(email);
- return this;
- }
-
- public Person build() {
- return new Person(name, phone, email, address, tags);
- }
-
-}
diff --git a/src/test/java/seedu/address/testutil/PersonUtil.java b/src/test/java/seedu/address/testutil/PersonUtil.java
deleted file mode 100644
index 90849945183..00000000000
--- a/src/test/java/seedu/address/testutil/PersonUtil.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package seedu.address.testutil;
-
-import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
-import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;
-
-import java.util.Set;
-
-import seedu.address.logic.commands.AddCommand;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.model.person.Person;
-import seedu.address.model.tag.Tag;
-
-/**
- * A utility class for Person.
- */
-public class PersonUtil {
-
- /**
- * Returns an add command string for adding the {@code person}.
- */
- public static String getAddCommand(Person person) {
- return AddCommand.COMMAND_WORD + " " + getPersonDetails(person);
- }
-
- /**
- * Returns the part of command string for the given {@code person}'s details.
- */
- public static String getPersonDetails(Person person) {
- StringBuilder sb = new StringBuilder();
- sb.append(PREFIX_NAME + person.getName().fullName + " ");
- sb.append(PREFIX_PHONE + person.getPhone().value + " ");
- sb.append(PREFIX_EMAIL + person.getEmail().value + " ");
- sb.append(PREFIX_ADDRESS + person.getAddress().value + " ");
- person.getTags().stream().forEach(
- s -> sb.append(PREFIX_TAG + s.tagName + " ")
- );
- return sb.toString();
- }
-
- /**
- * Returns the part of command string for the given {@code EditPersonDescriptor}'s details.
- */
- public static String getEditPersonDescriptorDetails(EditPersonDescriptor descriptor) {
- StringBuilder sb = new StringBuilder();
- descriptor.getName().ifPresent(name -> sb.append(PREFIX_NAME).append(name.fullName).append(" "));
- descriptor.getPhone().ifPresent(phone -> sb.append(PREFIX_PHONE).append(phone.value).append(" "));
- descriptor.getEmail().ifPresent(email -> sb.append(PREFIX_EMAIL).append(email.value).append(" "));
- descriptor.getAddress().ifPresent(address -> sb.append(PREFIX_ADDRESS).append(address.value).append(" "));
- if (descriptor.getTags().isPresent()) {
- Set tags = descriptor.getTags().get();
- if (tags.isEmpty()) {
- sb.append(PREFIX_TAG);
- } else {
- tags.forEach(s -> sb.append(PREFIX_TAG).append(s.tagName).append(" "));
- }
- }
- return sb.toString();
- }
-}
diff --git a/src/test/java/seedu/address/testutil/TypicalPersons.java b/src/test/java/seedu/address/testutil/TypicalPersons.java
deleted file mode 100644
index fec76fb7129..00000000000
--- a/src/test/java/seedu/address/testutil/TypicalPersons.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package seedu.address.testutil;
-
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_FRIEND;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import seedu.address.model.AddressBook;
-import seedu.address.model.person.Person;
-
-/**
- * A utility class containing a list of {@code Person} objects to be used in tests.
- */
-public class TypicalPersons {
-
- public static final Person ALICE = new PersonBuilder().withName("Alice Pauline")
- .withAddress("123, Jurong West Ave 6, #08-111").withEmail("alice@example.com")
- .withPhone("94351253")
- .withTags("friends").build();
- public static final Person BENSON = new PersonBuilder().withName("Benson Meier")
- .withAddress("311, Clementi Ave 2, #02-25")
- .withEmail("johnd@example.com").withPhone("98765432")
- .withTags("owesMoney", "friends").build();
- public static final Person CARL = new PersonBuilder().withName("Carl Kurz").withPhone("95352563")
- .withEmail("heinz@example.com").withAddress("wall street").build();
- public static final Person DANIEL = new PersonBuilder().withName("Daniel Meier").withPhone("87652533")
- .withEmail("cornelia@example.com").withAddress("10th street").withTags("friends").build();
- public static final Person ELLE = new PersonBuilder().withName("Elle Meyer").withPhone("9482224")
- .withEmail("werner@example.com").withAddress("michegan ave").build();
- public static final Person FIONA = new PersonBuilder().withName("Fiona Kunz").withPhone("9482427")
- .withEmail("lydia@example.com").withAddress("little tokyo").build();
- public static final Person GEORGE = new PersonBuilder().withName("George Best").withPhone("9482442")
- .withEmail("anna@example.com").withAddress("4th street").build();
-
- // Manually added
- public static final Person HOON = new PersonBuilder().withName("Hoon Meier").withPhone("8482424")
- .withEmail("stefan@example.com").withAddress("little india").build();
- public static final Person IDA = new PersonBuilder().withName("Ida Mueller").withPhone("8482131")
- .withEmail("hans@example.com").withAddress("chicago ave").build();
-
- // Manually added - Person's details found in {@code CommandTestUtil}
- public static final Person AMY = new PersonBuilder().withName(VALID_NAME_AMY).withPhone(VALID_PHONE_AMY)
- .withEmail(VALID_EMAIL_AMY).withAddress(VALID_ADDRESS_AMY).withTags(VALID_TAG_FRIEND).build();
- public static final Person BOB = new PersonBuilder().withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB)
- .withEmail(VALID_EMAIL_BOB).withAddress(VALID_ADDRESS_BOB).withTags(VALID_TAG_HUSBAND, VALID_TAG_FRIEND)
- .build();
-
- public static final String KEYWORD_MATCHING_MEIER = "Meier"; // A keyword that matches MEIER
-
- private TypicalPersons() {} // prevents instantiation
-
- /**
- * Returns an {@code AddressBook} with all the typical persons.
- */
- public static AddressBook getTypicalAddressBook() {
- AddressBook ab = new AddressBook();
- for (Person person : getTypicalPersons()) {
- ab.addPerson(person);
- }
- return ab;
- }
-
- public static List getTypicalPersons() {
- return new ArrayList<>(Arrays.asList(ALICE, BENSON, CARL, DANIEL, ELLE, FIONA, GEORGE));
- }
-}
diff --git a/src/test/java/seedu/address/AppParametersTest.java b/src/test/java/seedu/lovebook/AppParametersTest.java
similarity index 99%
rename from src/test/java/seedu/address/AppParametersTest.java
rename to src/test/java/seedu/lovebook/AppParametersTest.java
index 133cc008bce..7a67c71bb92 100644
--- a/src/test/java/seedu/address/AppParametersTest.java
+++ b/src/test/java/seedu/lovebook/AppParametersTest.java
@@ -1,4 +1,4 @@
-package seedu.address;
+package seedu.lovebook;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
diff --git a/src/test/java/seedu/address/commons/core/ConfigTest.java b/src/test/java/seedu/lovebook/commons/core/ConfigTest.java
similarity index 95%
rename from src/test/java/seedu/address/commons/core/ConfigTest.java
rename to src/test/java/seedu/lovebook/commons/core/ConfigTest.java
index d3ba2a52a89..13af608e0ce 100644
--- a/src/test/java/seedu/address/commons/core/ConfigTest.java
+++ b/src/test/java/seedu/lovebook/commons/core/ConfigTest.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.core;
+package seedu.lovebook.commons.core;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
diff --git a/src/test/java/seedu/address/commons/core/GuiSettingsTest.java b/src/test/java/seedu/lovebook/commons/core/GuiSettingsTest.java
similarity index 93%
rename from src/test/java/seedu/address/commons/core/GuiSettingsTest.java
rename to src/test/java/seedu/lovebook/commons/core/GuiSettingsTest.java
index b7876c4349d..342da9f47f6 100644
--- a/src/test/java/seedu/address/commons/core/GuiSettingsTest.java
+++ b/src/test/java/seedu/lovebook/commons/core/GuiSettingsTest.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.core;
+package seedu.lovebook.commons.core;
import static org.junit.jupiter.api.Assertions.assertEquals;
diff --git a/src/test/java/seedu/address/commons/core/VersionTest.java b/src/test/java/seedu/lovebook/commons/core/VersionTest.java
similarity index 98%
rename from src/test/java/seedu/address/commons/core/VersionTest.java
rename to src/test/java/seedu/lovebook/commons/core/VersionTest.java
index 495cd231554..655149046f3 100644
--- a/src/test/java/seedu/address/commons/core/VersionTest.java
+++ b/src/test/java/seedu/lovebook/commons/core/VersionTest.java
@@ -1,8 +1,8 @@
-package seedu.address.commons.core;
+package seedu.lovebook.commons.core;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.lovebook.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/seedu/address/commons/core/index/IndexTest.java b/src/test/java/seedu/lovebook/commons/core/index/IndexTest.java
similarity index 95%
rename from src/test/java/seedu/address/commons/core/index/IndexTest.java
rename to src/test/java/seedu/lovebook/commons/core/index/IndexTest.java
index fc395ab964b..a55ad40aa36 100644
--- a/src/test/java/seedu/address/commons/core/index/IndexTest.java
+++ b/src/test/java/seedu/lovebook/commons/core/index/IndexTest.java
@@ -1,9 +1,9 @@
-package seedu.address.commons.core.index;
+package seedu.lovebook.commons.core.index;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.lovebook.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/seedu/address/commons/util/AppUtilTest.java b/src/test/java/seedu/lovebook/commons/util/AppUtilTest.java
similarity index 85%
rename from src/test/java/seedu/address/commons/util/AppUtilTest.java
rename to src/test/java/seedu/lovebook/commons/util/AppUtilTest.java
index 594de1e6365..a5de91194e4 100644
--- a/src/test/java/seedu/address/commons/util/AppUtilTest.java
+++ b/src/test/java/seedu/lovebook/commons/util/AppUtilTest.java
@@ -1,7 +1,7 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.lovebook.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
@@ -9,7 +9,7 @@ public class AppUtilTest {
@Test
public void getImage_exitingImage() {
- assertNotNull(AppUtil.getImage("/images/address_book_32.png"));
+ assertNotNull(AppUtil.getImage("/images/bot.png"));
}
@Test
diff --git a/src/test/java/seedu/address/commons/util/CollectionUtilTest.java b/src/test/java/seedu/lovebook/commons/util/CollectionUtilTest.java
similarity index 96%
rename from src/test/java/seedu/address/commons/util/CollectionUtilTest.java
rename to src/test/java/seedu/lovebook/commons/util/CollectionUtilTest.java
index b467a3dc025..94dea94b0a5 100644
--- a/src/test/java/seedu/address/commons/util/CollectionUtilTest.java
+++ b/src/test/java/seedu/lovebook/commons/util/CollectionUtilTest.java
@@ -1,9 +1,9 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
-import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.lovebook.commons.util.CollectionUtil.requireAllNonNull;
+import static seedu.lovebook.testutil.Assert.assertThrows;
import java.util.Arrays;
import java.util.Collection;
diff --git a/src/test/java/seedu/address/commons/util/ConfigUtilTest.java b/src/test/java/seedu/lovebook/commons/util/ConfigUtilTest.java
similarity index 94%
rename from src/test/java/seedu/address/commons/util/ConfigUtilTest.java
rename to src/test/java/seedu/lovebook/commons/util/ConfigUtilTest.java
index 69d7b89cfd8..37ed42dcad0 100644
--- a/src/test/java/seedu/address/commons/util/ConfigUtilTest.java
+++ b/src/test/java/seedu/lovebook/commons/util/ConfigUtilTest.java
@@ -1,8 +1,8 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
-import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.lovebook.testutil.Assert.assertThrows;
import java.io.IOException;
import java.nio.file.Path;
@@ -13,8 +13,8 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import seedu.address.commons.core.Config;
-import seedu.address.commons.exceptions.DataLoadingException;
+import seedu.lovebook.commons.core.Config;
+import seedu.lovebook.commons.exceptions.DataLoadingException;
public class ConfigUtilTest {
diff --git a/src/test/java/seedu/address/commons/util/FileUtilTest.java b/src/test/java/seedu/lovebook/commons/util/FileUtilTest.java
similarity index 84%
rename from src/test/java/seedu/address/commons/util/FileUtilTest.java
rename to src/test/java/seedu/lovebook/commons/util/FileUtilTest.java
index 1fe5478c756..bbffb83bf7d 100644
--- a/src/test/java/seedu/address/commons/util/FileUtilTest.java
+++ b/src/test/java/seedu/lovebook/commons/util/FileUtilTest.java
@@ -1,8 +1,8 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.lovebook.testutil.Assert.assertThrows;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/seedu/address/commons/util/JsonUtilTest.java b/src/test/java/seedu/lovebook/commons/util/JsonUtilTest.java
similarity index 92%
rename from src/test/java/seedu/address/commons/util/JsonUtilTest.java
rename to src/test/java/seedu/lovebook/commons/util/JsonUtilTest.java
index d4907539dee..b69458f531f 100644
--- a/src/test/java/seedu/address/commons/util/JsonUtilTest.java
+++ b/src/test/java/seedu/lovebook/commons/util/JsonUtilTest.java
@@ -1,4 +1,4 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -7,8 +7,8 @@
import org.junit.jupiter.api.Test;
-import seedu.address.testutil.SerializableTestClass;
-import seedu.address.testutil.TestUtil;
+import seedu.lovebook.testutil.SerializableTestClass;
+import seedu.lovebook.testutil.TestUtil;
/**
* Tests JSON Read and Write
diff --git a/src/test/java/seedu/address/commons/util/StringUtilTest.java b/src/test/java/seedu/lovebook/commons/util/StringUtilTest.java
similarity index 98%
rename from src/test/java/seedu/address/commons/util/StringUtilTest.java
rename to src/test/java/seedu/lovebook/commons/util/StringUtilTest.java
index c56d407bf3f..25fd5e841bd 100644
--- a/src/test/java/seedu/address/commons/util/StringUtilTest.java
+++ b/src/test/java/seedu/lovebook/commons/util/StringUtilTest.java
@@ -1,8 +1,8 @@
-package seedu.address.commons.util;
+package seedu.lovebook.commons.util;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
+import static seedu.lovebook.testutil.Assert.assertThrows;
import java.io.FileNotFoundException;
diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/lovebook/logic/LogicManagerTest.java
similarity index 68%
rename from src/test/java/seedu/address/logic/LogicManagerTest.java
rename to src/test/java/seedu/lovebook/logic/LogicManagerTest.java
index baf8ce336a2..b0aa9032ff1 100644
--- a/src/test/java/seedu/address/logic/LogicManagerTest.java
+++ b/src/test/java/seedu/lovebook/logic/LogicManagerTest.java
@@ -1,14 +1,16 @@
-package seedu.address.logic;
+package seedu.lovebook.logic;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static seedu.address.logic.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX;
-import static seedu.address.logic.Messages.MESSAGE_UNKNOWN_COMMAND;
-import static seedu.address.logic.commands.CommandTestUtil.ADDRESS_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.EMAIL_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.NAME_DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.PHONE_DESC_AMY;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.AMY;
+import static seedu.lovebook.logic.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX;
+import static seedu.lovebook.logic.Messages.MESSAGE_UNKNOWN_COMMAND;
+import static seedu.lovebook.logic.commands.CommandTestUtil.AGE_DESC_AMY;
+import static seedu.lovebook.logic.commands.CommandTestUtil.GENDER_DESC_AMY;
+import static seedu.lovebook.logic.commands.CommandTestUtil.HEIGHT_DESC_AMY;
+import static seedu.lovebook.logic.commands.CommandTestUtil.HOROSCOPE_DESC_AMY;
+import static seedu.lovebook.logic.commands.CommandTestUtil.INCOME_DESC_AMY;
+import static seedu.lovebook.logic.commands.CommandTestUtil.NAME_DESC_AMY;
+import static seedu.lovebook.testutil.Assert.assertThrows;
+import static seedu.lovebook.testutil.TypicalDates.AMY;
import java.io.IOException;
import java.nio.file.AccessDeniedException;
@@ -18,20 +20,20 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
-import seedu.address.logic.commands.AddCommand;
-import seedu.address.logic.commands.CommandResult;
-import seedu.address.logic.commands.ListCommand;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.logic.parser.exceptions.ParseException;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.UserPrefs;
-import seedu.address.model.person.Person;
-import seedu.address.storage.JsonAddressBookStorage;
-import seedu.address.storage.JsonUserPrefsStorage;
-import seedu.address.storage.StorageManager;
-import seedu.address.testutil.PersonBuilder;
+import seedu.lovebook.logic.commands.AddCommand;
+import seedu.lovebook.logic.commands.CommandResult;
+import seedu.lovebook.logic.commands.ListCommand;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ModelManager;
+import seedu.lovebook.model.ReadOnlyLoveBook;
+import seedu.lovebook.model.UserPrefs;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.storage.JsonLoveBookStorage;
+import seedu.lovebook.storage.JsonUserPrefsStorage;
+import seedu.lovebook.storage.StorageManager;
+import seedu.lovebook.testutil.PersonBuilder;
public class LogicManagerTest {
private static final IOException DUMMY_IO_EXCEPTION = new IOException("dummy IO exception");
@@ -45,10 +47,10 @@ public class LogicManagerTest {
@BeforeEach
public void setUp() {
- JsonAddressBookStorage addressBookStorage =
- new JsonAddressBookStorage(temporaryFolder.resolve("addressBook.json"));
+ JsonLoveBookStorage loveBookStorage =
+ new JsonLoveBookStorage(temporaryFolder.resolve("LoveBook.json"));
JsonUserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(temporaryFolder.resolve("userPrefs.json"));
- StorageManager storage = new StorageManager(addressBookStorage, userPrefsStorage);
+ StorageManager storage = new StorageManager(loveBookStorage, userPrefsStorage);
logic = new LogicManager(model, storage);
}
@@ -87,6 +89,13 @@ public void getFilteredPersonList_modifyList_throwsUnsupportedOperationException
assertThrows(UnsupportedOperationException.class, () -> logic.getFilteredPersonList().remove(0));
}
+ @Test
+ public void executeGetWelcomeMessage() {
+ String expected = "Hey there, fabulous single!" + "\n"
+ + "Get ready to embark on an exciting journey with LoveBook to find your perfect match ❤︎₊ ⊹";
+ assertEquals(expected, logic.getWelcomeMessage());
+ }
+
/**
* Executes the command and confirms that
* - no exceptions are thrown
@@ -123,7 +132,7 @@ private void assertCommandException(String inputCommand, String expectedMessage)
*/
private void assertCommandFailure(String inputCommand, Class extends Throwable> expectedException,
String expectedMessage) {
- Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
+ Model expectedModel = new ModelManager(model.getLoveBook(), new UserPrefs(), model.getDatePrefs());
assertCommandFailure(inputCommand, expectedException, expectedMessage, expectedModel);
}
@@ -149,10 +158,10 @@ private void assertCommandFailure(String inputCommand, Class extends Throwable
private void assertCommandFailureForExceptionFromStorage(IOException e, String expectedMessage) {
Path prefPath = temporaryFolder.resolve("ExceptionUserPrefs.json");
- // Inject LogicManager with an AddressBookStorage that throws the IOException e when saving
- JsonAddressBookStorage addressBookStorage = new JsonAddressBookStorage(prefPath) {
+ // Inject LogicManager with an LoveBookStorage that throws the IOException e when saving
+ JsonLoveBookStorage loveBookStorage = new JsonLoveBookStorage(prefPath) {
@Override
- public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath)
+ public void saveLoveBook(ReadOnlyLoveBook loveBook, Path filePath)
throws IOException {
throw e;
}
@@ -160,16 +169,16 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath)
JsonUserPrefsStorage userPrefsStorage =
new JsonUserPrefsStorage(temporaryFolder.resolve("ExceptionUserPrefs.json"));
- StorageManager storage = new StorageManager(addressBookStorage, userPrefsStorage);
+ StorageManager storage = new StorageManager(loveBookStorage, userPrefsStorage);
logic = new LogicManager(model, storage);
- // Triggers the saveAddressBook method by executing an add command
- String addCommand = AddCommand.COMMAND_WORD + NAME_DESC_AMY + PHONE_DESC_AMY
- + EMAIL_DESC_AMY + ADDRESS_DESC_AMY;
- Person expectedPerson = new PersonBuilder(AMY).withTags().build();
+ // Triggers the saveLoveBook method by executing an add command
+ String addCommand = AddCommand.COMMAND_WORD + NAME_DESC_AMY + AGE_DESC_AMY
+ + GENDER_DESC_AMY + HEIGHT_DESC_AMY + INCOME_DESC_AMY + HOROSCOPE_DESC_AMY;
+ Date expectedDate = new PersonBuilder(AMY).build();
ModelManager expectedModel = new ModelManager();
- expectedModel.addPerson(expectedPerson);
+ expectedModel.addDate(expectedDate);
assertCommandFailure(addCommand, CommandException.class, expectedMessage, expectedModel);
}
}
diff --git a/src/test/java/seedu/lovebook/logic/commands/AddCommandIntegrationTest.java b/src/test/java/seedu/lovebook/logic/commands/AddCommandIntegrationTest.java
new file mode 100644
index 00000000000..9327b4fb689
--- /dev/null
+++ b/src/test/java/seedu/lovebook/logic/commands/AddCommandIntegrationTest.java
@@ -0,0 +1,49 @@
+package seedu.lovebook.logic.commands;
+
+import static seedu.lovebook.logic.commands.CommandTestUtil.assertCommandFailure;
+import static seedu.lovebook.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.lovebook.testutil.TypicalDatePrefs.getTypicalDatePrefs;
+import static seedu.lovebook.testutil.TypicalDates.getTypicalLoveBook;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ModelManager;
+import seedu.lovebook.model.UserPrefs;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.testutil.PersonBuilder;
+
+/**
+ * Contains integration tests (interaction with the Model) for {@code AddCommand}.
+ */
+public class AddCommandIntegrationTest {
+
+ private Model model;
+
+ @BeforeEach
+ public void setUp() {
+ model = new ModelManager(getTypicalLoveBook(), new UserPrefs(), getTypicalDatePrefs());
+ }
+
+ @Test
+ public void execute_newPerson_success() {
+ Date validDate = new PersonBuilder().build();
+
+ Model expectedModel = new ModelManager(model.getLoveBook(), new UserPrefs(), model.getDatePrefs());
+ expectedModel.addDate(validDate);
+
+ assertCommandSuccess(new AddCommand(validDate), model,
+ String.format(AddCommand.MESSAGE_SUCCESS, Messages.format(validDate)),
+ expectedModel);
+ }
+
+ @Test
+ public void execute_duplicatePerson_throwsCommandException() {
+ Date dateInList = model.getLoveBook().getPersonList().get(0);
+ assertCommandFailure(new AddCommand(dateInList), model,
+ AddCommand.MESSAGE_DUPLICATE_PERSON);
+ }
+
+}
diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/lovebook/logic/commands/AddCommandTest.java
similarity index 51%
rename from src/test/java/seedu/address/logic/commands/AddCommandTest.java
rename to src/test/java/seedu/lovebook/logic/commands/AddCommandTest.java
index 90e8253f48e..da34f4fe242 100644
--- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java
+++ b/src/test/java/seedu/lovebook/logic/commands/AddCommandTest.java
@@ -1,29 +1,32 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
import static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.testutil.Assert.assertThrows;
-import static seedu.address.testutil.TypicalPersons.ALICE;
+import static seedu.lovebook.testutil.Assert.assertThrows;
+import static seedu.lovebook.testutil.TypicalDates.ALICE;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.function.Predicate;
import org.junit.jupiter.api.Test;
import javafx.collections.ObservableList;
-import seedu.address.commons.core.GuiSettings;
-import seedu.address.logic.Messages;
-import seedu.address.logic.commands.exceptions.CommandException;
-import seedu.address.model.AddressBook;
-import seedu.address.model.Model;
-import seedu.address.model.ReadOnlyAddressBook;
-import seedu.address.model.ReadOnlyUserPrefs;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.PersonBuilder;
+import seedu.lovebook.commons.core.GuiSettings;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.model.DatePrefs;
+import seedu.lovebook.model.LoveBook;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ReadOnlyDatePrefs;
+import seedu.lovebook.model.ReadOnlyLoveBook;
+import seedu.lovebook.model.ReadOnlyUserPrefs;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.testutil.PersonBuilder;
public class AddCommandTest {
@@ -35,28 +38,28 @@ public void constructor_nullPerson_throwsNullPointerException() {
@Test
public void execute_personAcceptedByModel_addSuccessful() throws Exception {
ModelStubAcceptingPersonAdded modelStub = new ModelStubAcceptingPersonAdded();
- Person validPerson = new PersonBuilder().build();
+ Date validDate = new PersonBuilder().build();
- CommandResult commandResult = new AddCommand(validPerson).execute(modelStub);
+ CommandResult commandResult = new AddCommand(validDate).execute(modelStub);
- assertEquals(String.format(AddCommand.MESSAGE_SUCCESS, Messages.format(validPerson)),
+ assertEquals(String.format(AddCommand.MESSAGE_SUCCESS, Messages.format(validDate)),
commandResult.getFeedbackToUser());
- assertEquals(Arrays.asList(validPerson), modelStub.personsAdded);
+ assertEquals(Arrays.asList(validDate), modelStub.datesAdded);
}
@Test
public void execute_duplicatePerson_throwsCommandException() {
- Person validPerson = new PersonBuilder().build();
- AddCommand addCommand = new AddCommand(validPerson);
- ModelStub modelStub = new ModelStubWithPerson(validPerson);
+ Date validDate = new PersonBuilder().build();
+ AddCommand addCommand = new AddCommand(validDate);
+ ModelStub modelStub = new ModelStubWithPerson(validDate);
assertThrows(CommandException.class, AddCommand.MESSAGE_DUPLICATE_PERSON, () -> addCommand.execute(modelStub));
}
@Test
public void equals() {
- Person alice = new PersonBuilder().withName("Alice").build();
- Person bob = new PersonBuilder().withName("Bob").build();
+ Date alice = new PersonBuilder().withName("Alice").build();
+ Date bob = new PersonBuilder().withName("Bob").build();
AddCommand addAliceCommand = new AddCommand(alice);
AddCommand addBobCommand = new AddCommand(bob);
@@ -73,7 +76,7 @@ public void equals() {
// null -> returns false
assertFalse(addAliceCommand.equals(null));
- // different person -> returns false
+ // different date -> returns false
assertFalse(addAliceCommand.equals(addBobCommand));
}
@@ -109,95 +112,139 @@ public void setGuiSettings(GuiSettings guiSettings) {
}
@Override
- public Path getAddressBookFilePath() {
+ public Path getLoveBookFilePath() {
throw new AssertionError("This method should not be called.");
}
@Override
- public void setAddressBookFilePath(Path addressBookFilePath) {
+ public void setLoveBookFilePath(Path loveBookFilePath) {
throw new AssertionError("This method should not be called.");
}
@Override
- public void addPerson(Person person) {
+ public void addDate(Date date) {
throw new AssertionError("This method should not be called.");
}
@Override
- public void setAddressBook(ReadOnlyAddressBook newData) {
+ public void setLoveBook(ReadOnlyLoveBook newData) {
throw new AssertionError("This method should not be called.");
}
@Override
- public ReadOnlyAddressBook getAddressBook() {
+ public ReadOnlyLoveBook getLoveBook() {
throw new AssertionError("This method should not be called.");
}
@Override
- public boolean hasPerson(Person person) {
+ public boolean hasDate(Date date) {
throw new AssertionError("This method should not be called.");
}
@Override
- public void deletePerson(Person target) {
+ public void deleteDate(Date target) {
throw new AssertionError("This method should not be called.");
}
@Override
- public void setPerson(Person target, Person editedPerson) {
+ public void setDate(Date target, Date editedDate) {
throw new AssertionError("This method should not be called.");
}
@Override
- public ObservableList getFilteredPersonList() {
+ public ObservableList getFilteredPersonList() {
throw new AssertionError("This method should not be called.");
}
@Override
- public void updateFilteredPersonList(Predicate predicate) {
+ public void getBlindDate() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void updateFilteredPersonList(Predicate predicate) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public String getWelcomeMessage() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public DatePrefs getDatePrefs() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void updateSortedDateList(Comparator comparator) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void setDatePrefs(ReadOnlyDatePrefs datePrefs) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public Path getDatePrefsFilePath() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void setDatePrefsFilePath(Path datePrefsFilePath) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void getBestDate() {
throw new AssertionError("This method should not be called.");
}
}
/**
- * A Model stub that contains a single person.
+ * A Model stub that contains a single date.
*/
private class ModelStubWithPerson extends ModelStub {
- private final Person person;
+ private final Date date;
- ModelStubWithPerson(Person person) {
- requireNonNull(person);
- this.person = person;
+ ModelStubWithPerson(Date date) {
+ requireNonNull(date);
+ this.date = date;
}
@Override
- public boolean hasPerson(Person person) {
- requireNonNull(person);
- return this.person.isSamePerson(person);
+ public boolean hasDate(Date date) {
+ requireNonNull(date);
+ return this.date.isSamePerson(date);
}
}
/**
- * A Model stub that always accept the person being added.
+ * A Model stub that always accept the date being added.
*/
private class ModelStubAcceptingPersonAdded extends ModelStub {
- final ArrayList personsAdded = new ArrayList<>();
+ final ArrayList datesAdded = new ArrayList<>();
@Override
- public boolean hasPerson(Person person) {
- requireNonNull(person);
- return personsAdded.stream().anyMatch(person::isSamePerson);
+ public boolean hasDate(Date date) {
+ requireNonNull(date);
+ return datesAdded.stream().anyMatch(date::isSamePerson);
}
@Override
- public void addPerson(Person person) {
- requireNonNull(person);
- personsAdded.add(person);
+ public void addDate(Date date) {
+ requireNonNull(date);
+ datesAdded.add(date);
}
@Override
- public ReadOnlyAddressBook getAddressBook() {
- return new AddressBook();
+ public void updateSortedDateList(Comparator comparator) {
+ requireNonNull(comparator);
+ }
+ @Override
+ public ReadOnlyLoveBook getLoveBook() {
+ return new LoveBook();
}
}
diff --git a/src/test/java/seedu/lovebook/logic/commands/BlindDateCommandTest.java b/src/test/java/seedu/lovebook/logic/commands/BlindDateCommandTest.java
new file mode 100644
index 00000000000..ef427733b6f
--- /dev/null
+++ b/src/test/java/seedu/lovebook/logic/commands/BlindDateCommandTest.java
@@ -0,0 +1,32 @@
+package seedu.lovebook.logic.commands;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.lovebook.model.Model;
+
+
+public class BlindDateCommandTest {
+ private Model model;
+ private Model expectedModel;
+
+ @Test
+ public void equals() {
+ BlindDateCommand blindDateCommand = new BlindDateCommand();
+ BlindDateCommand blindDateCommandCopy = new BlindDateCommand();
+
+ // same object -> returns true
+ assertTrue(blindDateCommand.equals(blindDateCommand));
+
+ // same values -> returns true
+ assertTrue(blindDateCommand.equals(blindDateCommandCopy));
+
+ // different types -> returns false
+ assertFalse(blindDateCommand.equals(1));
+
+ // null -> returns false
+ assertFalse(blindDateCommand.equals(null));
+ }
+}
diff --git a/src/test/java/seedu/lovebook/logic/commands/ClearCommandTest.java b/src/test/java/seedu/lovebook/logic/commands/ClearCommandTest.java
new file mode 100644
index 00000000000..36c0dac165a
--- /dev/null
+++ b/src/test/java/seedu/lovebook/logic/commands/ClearCommandTest.java
@@ -0,0 +1,33 @@
+package seedu.lovebook.logic.commands;
+
+import static seedu.lovebook.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.lovebook.testutil.TypicalDatePrefs.getTypicalDatePrefs;
+import static seedu.lovebook.testutil.TypicalDates.getTypicalLoveBook;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.lovebook.model.LoveBook;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ModelManager;
+import seedu.lovebook.model.UserPrefs;
+
+public class ClearCommandTest {
+
+ @Test
+ public void execute_emptyLoveBook_success() {
+ Model model = new ModelManager();
+ Model expectedModel = new ModelManager();
+
+ assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel);
+ }
+
+ @Test
+ public void execute_nonEmptyLoveBook_success() {
+ Model model = new ModelManager(getTypicalLoveBook(), new UserPrefs(), getTypicalDatePrefs());
+ Model expectedModel = new ModelManager(getTypicalLoveBook(), new UserPrefs(), getTypicalDatePrefs());
+ expectedModel.setLoveBook(new LoveBook());
+
+ assertCommandSuccess(new ClearCommand(), model, ClearCommand.MESSAGE_SUCCESS, expectedModel);
+ }
+
+}
diff --git a/src/test/java/seedu/address/logic/commands/CommandResultTest.java b/src/test/java/seedu/lovebook/logic/commands/CommandResultTest.java
similarity index 98%
rename from src/test/java/seedu/address/logic/commands/CommandResultTest.java
rename to src/test/java/seedu/lovebook/logic/commands/CommandResultTest.java
index 7b8c7cd4546..d6d6db7b5ac 100644
--- a/src/test/java/seedu/address/logic/commands/CommandResultTest.java
+++ b/src/test/java/seedu/lovebook/logic/commands/CommandResultTest.java
@@ -1,4 +1,4 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
diff --git a/src/test/java/seedu/lovebook/logic/commands/CommandTestUtil.java b/src/test/java/seedu/lovebook/logic/commands/CommandTestUtil.java
new file mode 100644
index 00000000000..6a869ba70d0
--- /dev/null
+++ b/src/test/java/seedu/lovebook/logic/commands/CommandTestUtil.java
@@ -0,0 +1,146 @@
+package seedu.lovebook.logic.commands;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_GENDER;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HOROSCOPE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_INCOME;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME;
+import static seedu.lovebook.testutil.Assert.assertThrows;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import seedu.lovebook.commons.core.index.Index;
+import seedu.lovebook.logic.commands.exceptions.CommandException;
+import seedu.lovebook.logic.parser.exceptions.ParseException;
+import seedu.lovebook.model.LoveBook;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.model.date.NameContainsKeywordsPredicate;
+import seedu.lovebook.testutil.EditPersonDescriptorBuilder;
+import seedu.lovebook.testutil.SetPreferenceDescriptorBuilder;
+
+/**
+ * Contains helper methods for testing commands.
+ */
+public class CommandTestUtil {
+
+ public static final String VALID_NAME_AMY = "Amy Bee";
+ public static final String VALID_NAME_BOB = "Bob Choo";
+ public static final String VALID_AGE_AMY = "33";
+ public static final String VALID_AGE_BOB = "22";
+ public static final String VALID_GENDER_AMY = "F";
+ public static final String VALID_GENDER_BOB = "M";
+ public static final String VALID_HEIGHT_AMY = "180";
+ public static final String VALID_HEIGHT_BOB = "140";
+ public static final String VALID_INCOME_AMY = "3000";
+ public static final String VALID_INCOME_BOB = "2000";
+ public static final String VALID_HOROSCOPE_AMY = "TAURUS";
+ public static final String VALID_HOROSCOPE_BOB = "LIBRA";
+ public static final String VALID_STAR_AMY = "false";
+ public static final String VALID_STAR_BOB = "false";
+ public static final String VALID_AVATAR_AMY = "4";
+ public static final String VALID_AVATAR_BOB = "4";
+ public static final String NAME_DESC_AMY = " " + PREFIX_NAME + VALID_NAME_AMY;
+ public static final String NAME_DESC_BOB = " " + PREFIX_NAME + VALID_NAME_BOB;
+ public static final String AGE_DESC_AMY = " " + PREFIX_AGE + VALID_AGE_AMY;
+ public static final String AGE_DESC_BOB = " " + PREFIX_AGE + VALID_AGE_BOB;
+ public static final String GENDER_DESC_AMY = " " + PREFIX_GENDER + VALID_GENDER_AMY;
+ public static final String GENDER_DESC_BOB = " " + PREFIX_GENDER + VALID_GENDER_BOB;
+ public static final String HEIGHT_DESC_AMY = " " + PREFIX_HEIGHT + VALID_HEIGHT_AMY;
+ public static final String HEIGHT_DESC_BOB = " " + PREFIX_HEIGHT + VALID_HEIGHT_BOB;
+ public static final String INCOME_DESC_AMY = " " + PREFIX_INCOME + VALID_INCOME_AMY;
+ public static final String INCOME_DESC_BOB = " " + PREFIX_INCOME + VALID_INCOME_BOB;
+ public static final String HOROSCOPE_DESC_AMY = " " + PREFIX_HOROSCOPE + VALID_HOROSCOPE_AMY;
+ public static final String HOROSCOPE_DESC_BOB = " " + PREFIX_HOROSCOPE + VALID_HOROSCOPE_BOB;
+ public static final String INVALID_NAME_DESC = " " + PREFIX_NAME + "James&"; // '&' not allowed in names
+ public static final String INVALID_AGE_DESC = " " + PREFIX_AGE + "911a"; // 'a' not allowed in ages
+ public static final String INVALID_GENDER_DESC = " " + PREFIX_GENDER + "bob!yahoo"; // missing '@' symbol
+ public static final String INVALID_HEIGHT_DESC = " " + PREFIX_HEIGHT; // empty string not allowed for addresses
+ public static final String INVALID_INCOME_DESC = " " + PREFIX_INCOME; // empty string not allowed for income
+ public static final String INVALID_HOROSCOPE_DESC =
+ " " + PREFIX_HOROSCOPE; // empty string not allowed for horoscope
+ public static final String PREAMBLE_WHITESPACE = "\t \r \n";
+ public static final String PREAMBLE_NON_EMPTY = "NonEmptyPreamble";
+
+ public static final EditCommand.EditPersonDescriptor DESC_AMY;
+ public static final EditCommand.EditPersonDescriptor DESC_BOB;
+ public static final SetPrefCommand.SetPreferenceDescriptor DESC_PREF_AMY;
+ public static final SetPrefCommand.SetPreferenceDescriptor DESC_PREF_BOB;
+
+ static {
+ DESC_AMY = new EditPersonDescriptorBuilder().withName(VALID_NAME_AMY)
+ .withAge(VALID_AGE_AMY).withGender(VALID_GENDER_AMY).withHeight(VALID_HEIGHT_AMY)
+ .withIncome(VALID_INCOME_AMY).withHoroscope(VALID_HOROSCOPE_AMY).build();
+ DESC_BOB = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB)
+ .withAge(VALID_AGE_BOB).withGender(VALID_GENDER_BOB).withHeight(VALID_HEIGHT_BOB)
+ .withIncome(VALID_INCOME_AMY).withHoroscope(VALID_HOROSCOPE_BOB).build();
+ DESC_PREF_AMY = new SetPreferenceDescriptorBuilder().withAge(VALID_AGE_AMY).withHeight(VALID_HEIGHT_AMY)
+ .withIncome(VALID_INCOME_AMY).withHoroscope(VALID_HOROSCOPE_AMY).build();
+ DESC_PREF_BOB = new SetPreferenceDescriptorBuilder().withAge(VALID_AGE_BOB).withHeight(VALID_HEIGHT_BOB)
+ .withIncome(VALID_INCOME_AMY).withHoroscope(VALID_HOROSCOPE_BOB).build();
+ }
+
+ /**
+ * Executes the given {@code command}, confirms that
+ * - the returned {@link CommandResult} matches {@code expectedCommandResult}
+ * - the {@code actualModel} matches {@code expectedModel}
+ */
+ public static void assertCommandSuccess(Command command, Model actualModel, CommandResult expectedCommandResult,
+ Model expectedModel) {
+ try {
+ CommandResult result = command.execute(actualModel);
+ assertEquals(expectedCommandResult, result);
+ assertEquals(expectedModel, actualModel);
+ } catch (CommandException ce) {
+ throw new AssertionError("Execution of command should not fail.", ce);
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Convenience wrapper to {@link #assertCommandSuccess(Command, Model, CommandResult, Model)}
+ * that takes a string {@code expectedMessage}.
+ */
+ public static void assertCommandSuccess(Command command, Model actualModel, String expectedMessage,
+ Model expectedModel) {
+ CommandResult expectedCommandResult = new CommandResult(expectedMessage);
+ assertCommandSuccess(command, actualModel, expectedCommandResult, expectedModel);
+ }
+
+ /**
+ * Executes the given {@code command}, confirms that
+ * - a {@code CommandException} is thrown
+ * - the CommandException message matches {@code expectedMessage}
+ * - the LoveBook, filtered date list and selected date in {@code actualModel} remain unchanged
+ */
+ public static void assertCommandFailure(Command command, Model actualModel, String expectedMessage) {
+ // we are unable to defensively copy the model for comparison later, so we can
+ // only do so by copying its components.
+ LoveBook expectedLoveBook = new LoveBook(actualModel.getLoveBook());
+ List expectedFilteredList = new ArrayList<>(actualModel.getFilteredPersonList());
+
+ assertThrows(CommandException.class, expectedMessage, () -> command.execute(actualModel));
+ assertEquals(expectedLoveBook, actualModel.getLoveBook());
+ assertEquals(expectedFilteredList, actualModel.getFilteredPersonList());
+ }
+ /**
+ * Updates {@code model}'s filtered list to show only the date at the given {@code targetIndex} in the
+ * {@code model}'s LoveBook.
+ */
+ public static void showPersonAtIndex(Model model, Index targetIndex) {
+ assertTrue(targetIndex.getZeroBased() < model.getFilteredPersonList().size());
+
+ Date date = model.getFilteredPersonList().get(targetIndex.getZeroBased());
+ final String[] splitName = date.getName().fullName.split("\\s+");
+ model.updateFilteredPersonList(new NameContainsKeywordsPredicate(Arrays.asList(splitName[0])));
+
+ assertEquals(1, model.getFilteredPersonList().size());
+ }
+
+}
diff --git a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java b/src/test/java/seedu/lovebook/logic/commands/DeleteCommandTest.java
similarity index 64%
rename from src/test/java/seedu/address/logic/commands/DeleteCommandTest.java
rename to src/test/java/seedu/lovebook/logic/commands/DeleteCommandTest.java
index b6f332eabca..d0be87743b5 100644
--- a/src/test/java/seedu/address/logic/commands/DeleteCommandTest.java
+++ b/src/test/java/seedu/lovebook/logic/commands/DeleteCommandTest.java
@@ -1,23 +1,24 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.lovebook.logic.commands.CommandTestUtil.assertCommandFailure;
+import static seedu.lovebook.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.lovebook.logic.commands.CommandTestUtil.showPersonAtIndex;
+import static seedu.lovebook.testutil.TypicalDatePrefs.getTypicalDatePrefs;
+import static seedu.lovebook.testutil.TypicalDates.getTypicalLoveBook;
+import static seedu.lovebook.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
+import static seedu.lovebook.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
import org.junit.jupiter.api.Test;
-import seedu.address.commons.core.index.Index;
-import seedu.address.logic.Messages;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.UserPrefs;
-import seedu.address.model.person.Person;
+import seedu.lovebook.commons.core.index.Index;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ModelManager;
+import seedu.lovebook.model.UserPrefs;
+import seedu.lovebook.model.date.Date;
/**
* Contains integration tests (interaction with the Model) and unit tests for
@@ -25,18 +26,18 @@
*/
public class DeleteCommandTest {
- private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private Model model = new ModelManager(getTypicalLoveBook(), new UserPrefs(), getTypicalDatePrefs());
@Test
public void execute_validIndexUnfilteredList_success() {
- Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
+ Date dateToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_PERSON);
String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS,
- Messages.format(personToDelete));
+ Messages.format(dateToDelete));
- ModelManager expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
- expectedModel.deletePerson(personToDelete);
+ ModelManager expectedModel = new ModelManager(model.getLoveBook(), new UserPrefs(), model.getDatePrefs());
+ expectedModel.deleteDate(dateToDelete);
assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel);
}
@@ -53,14 +54,14 @@ public void execute_invalidIndexUnfilteredList_throwsCommandException() {
public void execute_validIndexFilteredList_success() {
showPersonAtIndex(model, INDEX_FIRST_PERSON);
- Person personToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
+ Date dateToDelete = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
DeleteCommand deleteCommand = new DeleteCommand(INDEX_FIRST_PERSON);
String expectedMessage = String.format(DeleteCommand.MESSAGE_DELETE_PERSON_SUCCESS,
- Messages.format(personToDelete));
+ Messages.format(dateToDelete));
- Model expectedModel = new ModelManager(model.getAddressBook(), new UserPrefs());
- expectedModel.deletePerson(personToDelete);
+ Model expectedModel = new ModelManager(model.getLoveBook(), new UserPrefs(), model.getDatePrefs());
+ expectedModel.deleteDate(dateToDelete);
showNoPerson(expectedModel);
assertCommandSuccess(deleteCommand, model, expectedMessage, expectedModel);
@@ -71,8 +72,8 @@ public void execute_invalidIndexFilteredList_throwsCommandException() {
showPersonAtIndex(model, INDEX_FIRST_PERSON);
Index outOfBoundIndex = INDEX_SECOND_PERSON;
- // ensures that outOfBoundIndex is still in bounds of address book list
- assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size());
+ // ensures that outOfBoundIndex is still in bounds of LoveBook list
+ assertTrue(outOfBoundIndex.getZeroBased() < model.getLoveBook().getPersonList().size());
DeleteCommand deleteCommand = new DeleteCommand(outOfBoundIndex);
@@ -97,7 +98,7 @@ public void equals() {
// null -> returns false
assertFalse(deleteFirstCommand.equals(null));
- // different person -> returns false
+ // different date -> returns false
assertFalse(deleteFirstCommand.equals(deleteSecondCommand));
}
diff --git a/src/test/java/seedu/address/logic/commands/EditCommandTest.java b/src/test/java/seedu/lovebook/logic/commands/EditCommandTest.java
similarity index 58%
rename from src/test/java/seedu/address/logic/commands/EditCommandTest.java
rename to src/test/java/seedu/lovebook/logic/commands/EditCommandTest.java
index 469dd97daa7..10ade663ab2 100644
--- a/src/test/java/seedu/address/logic/commands/EditCommandTest.java
+++ b/src/test/java/seedu/lovebook/logic/commands/EditCommandTest.java
@@ -1,50 +1,51 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandFailure;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.CommandTestUtil.showPersonAtIndex;
-import static seedu.address.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
-import static seedu.address.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.lovebook.logic.commands.CommandTestUtil.DESC_AMY;
+import static seedu.lovebook.logic.commands.CommandTestUtil.DESC_BOB;
+import static seedu.lovebook.logic.commands.CommandTestUtil.VALID_AGE_BOB;
+import static seedu.lovebook.logic.commands.CommandTestUtil.VALID_NAME_BOB;
+import static seedu.lovebook.logic.commands.CommandTestUtil.assertCommandFailure;
+import static seedu.lovebook.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.lovebook.logic.commands.CommandTestUtil.showPersonAtIndex;
+import static seedu.lovebook.testutil.TypicalDatePrefs.getTypicalDatePrefs;
+import static seedu.lovebook.testutil.TypicalDates.getTypicalLoveBook;
+import static seedu.lovebook.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
+import static seedu.lovebook.testutil.TypicalIndexes.INDEX_SECOND_PERSON;
import org.junit.jupiter.api.Test;
-import seedu.address.commons.core.index.Index;
-import seedu.address.logic.Messages;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.model.AddressBook;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.UserPrefs;
-import seedu.address.model.person.Person;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
-import seedu.address.testutil.PersonBuilder;
+import seedu.lovebook.commons.core.index.Index;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.logic.commands.EditCommand.EditPersonDescriptor;
+import seedu.lovebook.model.LoveBook;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ModelManager;
+import seedu.lovebook.model.UserPrefs;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.testutil.EditPersonDescriptorBuilder;
+import seedu.lovebook.testutil.PersonBuilder;
/**
* Contains integration tests (interaction with the Model) and unit tests for EditCommand.
*/
public class EditCommandTest {
- private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private Model model = new ModelManager(getTypicalLoveBook(), new UserPrefs(), getTypicalDatePrefs());
@Test
public void execute_allFieldsSpecifiedUnfilteredList_success() {
- Person editedPerson = new PersonBuilder().build();
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(editedPerson).build();
+ Date editedDate = new PersonBuilder().build();
+ EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(editedDate).build();
EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, descriptor);
- String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson));
+ String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedDate));
- Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
- expectedModel.setPerson(model.getFilteredPersonList().get(0), editedPerson);
+ Model expectedModel = new ModelManager(new LoveBook(model.getLoveBook()), new UserPrefs(),
+ model.getDatePrefs());
+ expectedModel.setDate(model.getFilteredPersonList().get(0), editedDate);
assertCommandSuccess(editCommand, model, expectedMessage, expectedModel);
}
@@ -52,20 +53,20 @@ public void execute_allFieldsSpecifiedUnfilteredList_success() {
@Test
public void execute_someFieldsSpecifiedUnfilteredList_success() {
Index indexLastPerson = Index.fromOneBased(model.getFilteredPersonList().size());
- Person lastPerson = model.getFilteredPersonList().get(indexLastPerson.getZeroBased());
+ Date lastDate = model.getFilteredPersonList().get(indexLastPerson.getZeroBased());
- PersonBuilder personInList = new PersonBuilder(lastPerson);
- Person editedPerson = personInList.withName(VALID_NAME_BOB).withPhone(VALID_PHONE_BOB)
- .withTags(VALID_TAG_HUSBAND).build();
+ PersonBuilder personInList = new PersonBuilder(lastDate);
+ Date editedDate = personInList.withName(VALID_NAME_BOB).withAge(VALID_AGE_BOB).build();
EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB)
- .withPhone(VALID_PHONE_BOB).withTags(VALID_TAG_HUSBAND).build();
+ .withAge(VALID_AGE_BOB).build();
EditCommand editCommand = new EditCommand(indexLastPerson, descriptor);
- String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson));
+ String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedDate));
- Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
- expectedModel.setPerson(lastPerson, editedPerson);
+ Model expectedModel = new ModelManager(new LoveBook(model.getLoveBook()), new UserPrefs(),
+ model.getDatePrefs());
+ expectedModel.setDate(lastDate, editedDate);
assertCommandSuccess(editCommand, model, expectedMessage, expectedModel);
}
@@ -73,11 +74,12 @@ public void execute_someFieldsSpecifiedUnfilteredList_success() {
@Test
public void execute_noFieldSpecifiedUnfilteredList_success() {
EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON, new EditPersonDescriptor());
- Person editedPerson = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
+ Date editedDate = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
- String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson));
+ String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedDate));
- Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
+ Model expectedModel = new ModelManager(new LoveBook(model.getLoveBook()), new UserPrefs(),
+ model.getDatePrefs());
assertCommandSuccess(editCommand, model, expectedMessage, expectedModel);
}
@@ -86,23 +88,24 @@ public void execute_noFieldSpecifiedUnfilteredList_success() {
public void execute_filteredList_success() {
showPersonAtIndex(model, INDEX_FIRST_PERSON);
- Person personInFilteredList = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
- Person editedPerson = new PersonBuilder(personInFilteredList).withName(VALID_NAME_BOB).build();
+ Date dateInFilteredList = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
+ Date editedDate = new PersonBuilder(dateInFilteredList).withName(VALID_NAME_BOB).build();
EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON,
new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build());
- String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedPerson));
+ String expectedMessage = String.format(EditCommand.MESSAGE_EDIT_PERSON_SUCCESS, Messages.format(editedDate));
- Model expectedModel = new ModelManager(new AddressBook(model.getAddressBook()), new UserPrefs());
- expectedModel.setPerson(model.getFilteredPersonList().get(0), editedPerson);
+ Model expectedModel = new ModelManager(new LoveBook(model.getLoveBook()), new UserPrefs(),
+ model.getDatePrefs());
+ expectedModel.setDate(model.getFilteredPersonList().get(0), editedDate);
assertCommandSuccess(editCommand, model, expectedMessage, expectedModel);
}
@Test
public void execute_duplicatePersonUnfilteredList_failure() {
- Person firstPerson = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
- EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(firstPerson).build();
+ Date firstDate = model.getFilteredPersonList().get(INDEX_FIRST_PERSON.getZeroBased());
+ EditPersonDescriptor descriptor = new EditPersonDescriptorBuilder(firstDate).build();
EditCommand editCommand = new EditCommand(INDEX_SECOND_PERSON, descriptor);
assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_PERSON);
@@ -112,10 +115,10 @@ public void execute_duplicatePersonUnfilteredList_failure() {
public void execute_duplicatePersonFilteredList_failure() {
showPersonAtIndex(model, INDEX_FIRST_PERSON);
- // edit person in filtered list into a duplicate in address book
- Person personInList = model.getAddressBook().getPersonList().get(INDEX_SECOND_PERSON.getZeroBased());
+ // edit date in filtered list into a duplicate in LoveBook
+ Date dateInList = model.getLoveBook().getPersonList().get(INDEX_SECOND_PERSON.getZeroBased());
EditCommand editCommand = new EditCommand(INDEX_FIRST_PERSON,
- new EditPersonDescriptorBuilder(personInList).build());
+ new EditPersonDescriptorBuilder(dateInList).build());
assertCommandFailure(editCommand, model, EditCommand.MESSAGE_DUPLICATE_PERSON);
}
@@ -131,14 +134,14 @@ public void execute_invalidPersonIndexUnfilteredList_failure() {
/**
* Edit filtered list where index is larger than size of filtered list,
- * but smaller than size of address book
+ * but smaller than size of LoveBook
*/
@Test
public void execute_invalidPersonIndexFilteredList_failure() {
showPersonAtIndex(model, INDEX_FIRST_PERSON);
Index outOfBoundIndex = INDEX_SECOND_PERSON;
- // ensures that outOfBoundIndex is still in bounds of address book list
- assertTrue(outOfBoundIndex.getZeroBased() < model.getAddressBook().getPersonList().size());
+ // ensures that outOfBoundIndex is still in bounds of LoveBook list
+ assertTrue(outOfBoundIndex.getZeroBased() < model.getLoveBook().getPersonList().size());
EditCommand editCommand = new EditCommand(outOfBoundIndex,
new EditPersonDescriptorBuilder().withName(VALID_NAME_BOB).build());
diff --git a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java b/src/test/java/seedu/lovebook/logic/commands/EditDateDescriptorTest.java
similarity index 53%
rename from src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java
rename to src/test/java/seedu/lovebook/logic/commands/EditDateDescriptorTest.java
index b17c1f3d5c2..17b61f8cb30 100644
--- a/src/test/java/seedu/address/logic/commands/EditPersonDescriptorTest.java
+++ b/src/test/java/seedu/lovebook/logic/commands/EditDateDescriptorTest.java
@@ -1,22 +1,21 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.commands.CommandTestUtil.DESC_AMY;
-import static seedu.address.logic.commands.CommandTestUtil.DESC_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_ADDRESS_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_EMAIL_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_NAME_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_PHONE_BOB;
-import static seedu.address.logic.commands.CommandTestUtil.VALID_TAG_HUSBAND;
+import static seedu.lovebook.logic.commands.CommandTestUtil.DESC_AMY;
+import static seedu.lovebook.logic.commands.CommandTestUtil.DESC_BOB;
+import static seedu.lovebook.logic.commands.CommandTestUtil.VALID_AGE_BOB;
+import static seedu.lovebook.logic.commands.CommandTestUtil.VALID_GENDER_BOB;
+import static seedu.lovebook.logic.commands.CommandTestUtil.VALID_HEIGHT_BOB;
+import static seedu.lovebook.logic.commands.CommandTestUtil.VALID_NAME_BOB;
import org.junit.jupiter.api.Test;
-import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
-import seedu.address.testutil.EditPersonDescriptorBuilder;
+import seedu.lovebook.logic.commands.EditCommand.EditPersonDescriptor;
+import seedu.lovebook.testutil.EditPersonDescriptorBuilder;
-public class EditPersonDescriptorTest {
+public class EditDateDescriptorTest {
@Test
public void equals() {
@@ -40,32 +39,29 @@ public void equals() {
EditPersonDescriptor editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withName(VALID_NAME_BOB).build();
assertFalse(DESC_AMY.equals(editedAmy));
- // different phone -> returns false
- editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withPhone(VALID_PHONE_BOB).build();
+ // different age -> returns false
+ editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withAge(VALID_AGE_BOB).build();
assertFalse(DESC_AMY.equals(editedAmy));
- // different email -> returns false
- editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withEmail(VALID_EMAIL_BOB).build();
+ // different gender -> returns false
+ editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withGender(VALID_GENDER_BOB).build();
assertFalse(DESC_AMY.equals(editedAmy));
- // different address -> returns false
- editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withAddress(VALID_ADDRESS_BOB).build();
+ // different lovebook -> returns false
+ editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withHeight(VALID_HEIGHT_BOB).build();
assertFalse(DESC_AMY.equals(editedAmy));
- // different tags -> returns false
- editedAmy = new EditPersonDescriptorBuilder(DESC_AMY).withTags(VALID_TAG_HUSBAND).build();
- assertFalse(DESC_AMY.equals(editedAmy));
}
@Test
public void toStringMethod() {
EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor();
String expected = EditPersonDescriptor.class.getCanonicalName() + "{name="
- + editPersonDescriptor.getName().orElse(null) + ", phone="
- + editPersonDescriptor.getPhone().orElse(null) + ", email="
- + editPersonDescriptor.getEmail().orElse(null) + ", address="
- + editPersonDescriptor.getAddress().orElse(null) + ", tags="
- + editPersonDescriptor.getTags().orElse(null) + "}";
+ + editPersonDescriptor.getName().orElse(null) + ", age="
+ + editPersonDescriptor.getAge().orElse(null) + ", gender="
+ + editPersonDescriptor.getGender().orElse(null) + ", height="
+ + editPersonDescriptor.getHeight().orElse(null) + ", income="
+ + editPersonDescriptor.getIncome().orElse(null) + "}";
assertEquals(expected, editPersonDescriptor.toString());
}
}
diff --git a/src/test/java/seedu/address/logic/commands/ExitCommandTest.java b/src/test/java/seedu/lovebook/logic/commands/ExitCommandTest.java
similarity index 60%
rename from src/test/java/seedu/address/logic/commands/ExitCommandTest.java
rename to src/test/java/seedu/lovebook/logic/commands/ExitCommandTest.java
index 9533c473875..64ca3506dd0 100644
--- a/src/test/java/seedu/address/logic/commands/ExitCommandTest.java
+++ b/src/test/java/seedu/lovebook/logic/commands/ExitCommandTest.java
@@ -1,12 +1,12 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.ExitCommand.MESSAGE_EXIT_ACKNOWLEDGEMENT;
+import static seedu.lovebook.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.lovebook.logic.commands.ExitCommand.MESSAGE_EXIT_ACKNOWLEDGEMENT;
import org.junit.jupiter.api.Test;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ModelManager;
public class ExitCommandTest {
private Model model = new ModelManager();
diff --git a/src/test/java/seedu/lovebook/logic/commands/FilterCommandTest.java b/src/test/java/seedu/lovebook/logic/commands/FilterCommandTest.java
new file mode 100644
index 00000000000..df431230b21
--- /dev/null
+++ b/src/test/java/seedu/lovebook/logic/commands/FilterCommandTest.java
@@ -0,0 +1,165 @@
+package seedu.lovebook.logic.commands;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.lovebook.logic.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW;
+import static seedu.lovebook.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_AGE;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_GENDER;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_HEIGHT;
+import static seedu.lovebook.logic.parser.CliSyntax.PREFIX_NAME;
+import static seedu.lovebook.testutil.TypicalDatePrefs.getTypicalDatePrefs;
+import static seedu.lovebook.testutil.TypicalDates.ALICE;
+import static seedu.lovebook.testutil.TypicalDates.BENSON;
+import static seedu.lovebook.testutil.TypicalDates.ELLE;
+import static seedu.lovebook.testutil.TypicalDates.FIONA;
+import static seedu.lovebook.testutil.TypicalDates.GEORGE;
+import static seedu.lovebook.testutil.TypicalDates.getTypicalLoveBook;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.junit.jupiter.api.Test;
+
+import seedu.lovebook.commons.util.PredicatesUtil;
+import seedu.lovebook.logic.parser.Prefix;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ModelManager;
+import seedu.lovebook.model.UserPrefs;
+import seedu.lovebook.model.date.MetricContainsKeywordPredicate;
+
+/**
+ * Contains integration tests (interaction with the Model) for {@code FilterCommand}.
+ */
+public class FilterCommandTest {
+ private Model model = new ModelManager(getTypicalLoveBook(), new UserPrefs(), getTypicalDatePrefs());
+ private Model expectedModel = new ModelManager(getTypicalLoveBook(), new UserPrefs(), getTypicalDatePrefs());
+ private final ArrayList predicates = new ArrayList<>();
+
+ @Test
+ public void equals() {
+ ArrayList predicatesList1 = new ArrayList<>();
+ ArrayList predicatesList2 = new ArrayList<>();
+ MetricContainsKeywordPredicate predicate1 = new MetricContainsKeywordPredicate("John", PREFIX_NAME);
+ MetricContainsKeywordPredicate predicate2 = new MetricContainsKeywordPredicate("Mary", PREFIX_NAME);
+ predicatesList1.add(predicate1);
+ predicatesList2.add(predicate2);
+
+ FilterCommand filterFirstCommand = new FilterCommand(predicatesList1);
+ FilterCommand filterSecondCommand = new FilterCommand(predicatesList2);
+
+ // same object -> returns true
+ assertTrue(filterFirstCommand.equals(filterFirstCommand));
+
+ // same values -> returns true
+ FilterCommand findFirstCommandCopy = new FilterCommand(predicatesList1);
+ assertTrue(filterFirstCommand.equals(findFirstCommandCopy));
+
+ // different types -> returns false
+ assertFalse(filterFirstCommand.equals(1));
+
+ // different keyword -> returns false
+ assertFalse(filterFirstCommand.equals(filterSecondCommand));
+ }
+
+ @Test
+ public void execute_filterByName_noPersonsFound() {
+ String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0);
+ ArrayList predicate = preparePredicate("Johnny", PREFIX_NAME);
+ FilterCommand command = new FilterCommand(predicate);
+ expectedModel.updateFilteredPersonList(new PredicatesUtil(predicate));
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Collections.emptyList(), model.getFilteredPersonList());
+ }
+
+ @Test
+ public void execute_filterByName_personsFound() {
+ String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 1);
+ ArrayList predicateList = preparePredicate("Alice", PREFIX_NAME);
+ FilterCommand command = new FilterCommand(predicateList);
+ expectedModel.updateFilteredPersonList(new PredicatesUtil(predicateList));
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Collections.singletonList(ALICE), model.getFilteredPersonList());
+ }
+
+ @Test
+ public void execute_filterByHeight_noPersonsFound() {
+ String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0);
+ ArrayList predicateList = preparePredicate("190", PREFIX_HEIGHT);
+ FilterCommand command = new FilterCommand(predicateList);
+ expectedModel.updateFilteredPersonList(new PredicatesUtil(predicateList));
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Collections.emptyList(), model.getFilteredPersonList());
+ }
+ @Test
+ public void execute_filterByAge_noPersonsFound() {
+ String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 0);
+ ArrayList predicateList = preparePredicate("100", PREFIX_AGE);
+ FilterCommand command = new FilterCommand(predicateList);
+ expectedModel.updateFilteredPersonList((person) -> {
+ for (MetricContainsKeywordPredicate predicate : predicates) {
+ if (!predicate.test(person)) {
+ return false;
+ }
+ }
+ return true;
+ });
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Collections.emptyList(), model.getFilteredPersonList());
+ }
+ @Test
+ public void execute_filterByHeight_personsFound() {
+ String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 1);
+ ArrayList predicateList = preparePredicate("245", PREFIX_HEIGHT);
+ FilterCommand command = new FilterCommand(predicateList);
+ expectedModel.updateFilteredPersonList((person) -> {
+ for (MetricContainsKeywordPredicate predicate : predicates) {
+ if (!predicate.test(person)) {
+ return false;
+ }
+ }
+ return true;
+ });
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Arrays.asList(GEORGE), model.getFilteredPersonList());
+ }
+
+ @Test
+ public void execute_filterByAge_personsFound() {
+ String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 1);
+ ArrayList predicateList = preparePredicate("22", PREFIX_AGE);
+ FilterCommand command = new FilterCommand(predicateList);
+ expectedModel.updateFilteredPersonList(new PredicatesUtil(predicateList));
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Arrays.asList(BENSON), model.getFilteredPersonList());
+ }
+ @Test
+ public void execute_filterByGender_personsFound() {
+ String expectedMessage = String.format(MESSAGE_PERSONS_LISTED_OVERVIEW, 3);
+ ArrayList predicateList = preparePredicate("F", PREFIX_GENDER);
+ FilterCommand command = new FilterCommand(predicateList);
+ expectedModel.updateFilteredPersonList(new PredicatesUtil(predicateList));
+
+ assertCommandSuccess(command, model, expectedMessage, expectedModel);
+ assertEquals(Arrays.asList(ALICE, ELLE, FIONA), model.getFilteredPersonList());
+ }
+
+ @Test
+ public void toStringMethod() {
+ ArrayList predicateList = preparePredicate("F", PREFIX_GENDER);
+ FilterCommand findCommand = new FilterCommand(predicateList);
+ String expected = FilterCommand.class.getCanonicalName() + "{predicateList=" + predicateList + "}";
+ assertEquals(expected, findCommand.toString());
+ }
+
+ /**
+ * Parses {@code userInput} into a {@code MetricContainsKeywordsPredicate}.
+ */
+ private ArrayList preparePredicate(String userInput, Prefix prefix) {
+ MetricContainsKeywordPredicate predicate = new MetricContainsKeywordPredicate(userInput, prefix);
+ predicates.add(predicate);
+ return predicates;
+ }
+}
diff --git a/src/test/java/seedu/address/logic/commands/FindCommandTest.java b/src/test/java/seedu/lovebook/logic/commands/FindCommandTest.java
similarity index 76%
rename from src/test/java/seedu/address/logic/commands/FindCommandTest.java
rename to src/test/java/seedu/lovebook/logic/commands/FindCommandTest.java
index b8b7dbba91a..d445c8168f6 100644
--- a/src/test/java/seedu/address/logic/commands/FindCommandTest.java
+++ b/src/test/java/seedu/lovebook/logic/commands/FindCommandTest.java
@@ -1,31 +1,32 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static seedu.address.logic.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.testutil.TypicalPersons.CARL;
-import static seedu.address.testutil.TypicalPersons.ELLE;
-import static seedu.address.testutil.TypicalPersons.FIONA;
-import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;
+import static seedu.lovebook.logic.Messages.MESSAGE_PERSONS_LISTED_OVERVIEW;
+import static seedu.lovebook.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.lovebook.testutil.TypicalDatePrefs.getTypicalDatePrefs;
+import static seedu.lovebook.testutil.TypicalDates.CARL;
+import static seedu.lovebook.testutil.TypicalDates.ELLE;
+import static seedu.lovebook.testutil.TypicalDates.FIONA;
+import static seedu.lovebook.testutil.TypicalDates.getTypicalLoveBook;
import java.util.Arrays;
import java.util.Collections;
import org.junit.jupiter.api.Test;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
-import seedu.address.model.UserPrefs;
-import seedu.address.model.person.NameContainsKeywordsPredicate;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ModelManager;
+import seedu.lovebook.model.UserPrefs;
+import seedu.lovebook.model.date.NameContainsKeywordsPredicate;
/**
* Contains integration tests (interaction with the Model) for {@code FindCommand}.
*/
public class FindCommandTest {
- private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs());
- private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs());
+ private Model model = new ModelManager(getTypicalLoveBook(), new UserPrefs(), getTypicalDatePrefs());
+ private Model expectedModel = new ModelManager(getTypicalLoveBook(), new UserPrefs(), getTypicalDatePrefs());
@Test
public void equals() {
@@ -50,7 +51,7 @@ public void equals() {
// null -> returns false
assertFalse(findFirstCommand.equals(null));
- // different person -> returns false
+ // different date -> returns false
assertFalse(findFirstCommand.equals(findSecondCommand));
}
diff --git a/src/test/java/seedu/address/logic/commands/HelpCommandTest.java b/src/test/java/seedu/lovebook/logic/commands/HelpCommandTest.java
similarity index 60%
rename from src/test/java/seedu/address/logic/commands/HelpCommandTest.java
rename to src/test/java/seedu/lovebook/logic/commands/HelpCommandTest.java
index 4904fc4352e..e3783481cd3 100644
--- a/src/test/java/seedu/address/logic/commands/HelpCommandTest.java
+++ b/src/test/java/seedu/lovebook/logic/commands/HelpCommandTest.java
@@ -1,12 +1,12 @@
-package seedu.address.logic.commands;
+package seedu.lovebook.logic.commands;
-import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
-import static seedu.address.logic.commands.HelpCommand.SHOWING_HELP_MESSAGE;
+import static seedu.lovebook.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.lovebook.logic.commands.HelpCommand.SHOWING_HELP_MESSAGE;
import org.junit.jupiter.api.Test;
-import seedu.address.model.Model;
-import seedu.address.model.ModelManager;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ModelManager;
public class HelpCommandTest {
private Model model = new ModelManager();
diff --git a/src/test/java/seedu/lovebook/logic/commands/ListCommandTest.java b/src/test/java/seedu/lovebook/logic/commands/ListCommandTest.java
new file mode 100644
index 00000000000..c56caddb06d
--- /dev/null
+++ b/src/test/java/seedu/lovebook/logic/commands/ListCommandTest.java
@@ -0,0 +1,40 @@
+package seedu.lovebook.logic.commands;
+
+import static seedu.lovebook.logic.commands.CommandTestUtil.assertCommandSuccess;
+import static seedu.lovebook.logic.commands.CommandTestUtil.showPersonAtIndex;
+import static seedu.lovebook.testutil.TypicalDatePrefs.getTypicalDatePrefs;
+import static seedu.lovebook.testutil.TypicalDates.getTypicalLoveBook;
+import static seedu.lovebook.testutil.TypicalIndexes.INDEX_FIRST_PERSON;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ModelManager;
+import seedu.lovebook.model.UserPrefs;
+
+/**
+ * Contains integration tests (interaction with the Model) and unit tests for ListCommand.
+ */
+public class ListCommandTest {
+
+ private Model model;
+ private Model expectedModel;
+
+ @BeforeEach
+ public void setUp() {
+ model = new ModelManager(getTypicalLoveBook(), new UserPrefs(), getTypicalDatePrefs());
+ expectedModel = new ModelManager(model.getLoveBook(), new UserPrefs(), getTypicalDatePrefs());
+ }
+
+ @Test
+ public void execute_listIsNotFiltered_showsSameList() {
+ assertCommandSuccess(new ListCommand(), model, ListCommand.MESSAGE_SUCCESS, expectedModel);
+ }
+
+ @Test
+ public void execute_listIsFiltered_showsEverything() {
+ showPersonAtIndex(model, INDEX_FIRST_PERSON);
+ assertCommandSuccess(new ListCommand(), model, ListCommand.MESSAGE_SUCCESS, expectedModel);
+ }
+}
diff --git a/src/test/java/seedu/lovebook/logic/commands/SetPrefCommandTest.java b/src/test/java/seedu/lovebook/logic/commands/SetPrefCommandTest.java
new file mode 100644
index 00000000000..3c5e029c2e5
--- /dev/null
+++ b/src/test/java/seedu/lovebook/logic/commands/SetPrefCommandTest.java
@@ -0,0 +1,226 @@
+package seedu.lovebook.logic.commands;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static seedu.lovebook.logic.commands.CommandTestUtil.DESC_PREF_AMY;
+import static seedu.lovebook.logic.commands.CommandTestUtil.DESC_PREF_BOB;
+import static seedu.lovebook.testutil.Assert.assertThrows;
+
+import java.nio.file.Path;
+import java.util.Comparator;
+import java.util.function.Predicate;
+
+import org.junit.jupiter.api.Test;
+
+import javafx.collections.ObservableList;
+import seedu.lovebook.commons.core.GuiSettings;
+import seedu.lovebook.logic.Messages;
+import seedu.lovebook.model.DatePrefs;
+import seedu.lovebook.model.Model;
+import seedu.lovebook.model.ReadOnlyDatePrefs;
+import seedu.lovebook.model.ReadOnlyLoveBook;
+import seedu.lovebook.model.ReadOnlyUserPrefs;
+import seedu.lovebook.model.date.Age;
+import seedu.lovebook.model.date.Date;
+import seedu.lovebook.model.date.Height;
+import seedu.lovebook.model.date.Income;
+import seedu.lovebook.model.date.horoscope.Horoscope;
+import seedu.lovebook.testutil.PreferenceBuilder;
+
+
+public class SetPrefCommandTest {
+
+ @Test
+ public void constructor_nullPreference_throwsNullPointerException() {
+ assertThrows(NullPointerException.class, () -> new SetPrefCommand(null));
+ }
+
+ @Test
+ public void execute_preferenceAcceptedByModel_addSuccessful() throws Exception {
+ ModelStubAcceptingPreferenceAdded modelStub = new ModelStubAcceptingPreferenceAdded();
+ SetPrefCommand.SetPreferenceDescriptor validPreference = new PreferenceBuilder().build();
+
+ CommandResult commandResult = new SetPrefCommand(validPreference).execute(modelStub);
+ assertEquals(String.format(SetPrefCommand.MESSAGE_EDIT_PREF_SUCCESS, Messages.format(validPreference)),
+ commandResult.getFeedbackToUser());
+ }
+
+ @Test
+ public void execute_emptyPreference_throwException() throws Exception {
+ ModelStubAcceptingPreferenceAdded modelStub = new ModelStubAcceptingPreferenceAdded();
+ SetPrefCommand.SetPreferenceDescriptor emptyPreference = new SetPrefCommand.SetPreferenceDescriptor();
+ assertThrows(RuntimeException.class, () -> new SetPrefCommand(emptyPreference).execute(modelStub));
+ }
+
+ @Test
+ public void equals() {
+ SetPrefCommand.SetPreferenceDescriptor descriptor =
+ new SetPrefCommand.SetPreferenceDescriptor(DESC_PREF_AMY);
+
+ SetPrefCommand.SetPreferenceDescriptor secondDescriptor =
+ new SetPrefCommand.SetPreferenceDescriptor(DESC_PREF_BOB);
+
+ final SetPrefCommand standardCommand = new SetPrefCommand(descriptor);
+
+ // same values -> returns true
+ SetPrefCommand commandWithSameValues = new SetPrefCommand(descriptor);
+ assertTrue(standardCommand.equals(commandWithSameValues));
+
+ // same object -> returns true
+ assertTrue(standardCommand.equals(standardCommand));
+
+ // null -> returns false
+ assertFalse(standardCommand.equals(null));
+
+ // different types -> returns false
+ assertFalse(standardCommand.equals(new ClearCommand()));
+
+ // different descriptor -> returns false
+ assertFalse(standardCommand.equals(new SetPrefCommand(secondDescriptor)));
+ }
+
+ @Test
+ public void toStringMethod() {
+ SetPrefCommand.SetPreferenceDescriptor setPrefDescriptor =
+ new SetPrefCommand.SetPreferenceDescriptor(DESC_PREF_BOB);
+ SetPrefCommand setPrefCommand = new SetPrefCommand(setPrefDescriptor);
+ String expected = SetPrefCommand.class.getCanonicalName() + "{setPreferenceDescriptor="
+ + setPrefDescriptor + "}";
+ assertEquals(expected, setPrefCommand.toString());
+ }
+
+ /**
+ * A default model stub that have all of the methods failing.
+ */
+ private class ModelStub implements Model {
+ @Override
+ public void setUserPrefs(ReadOnlyUserPrefs userPrefs) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public ReadOnlyUserPrefs getUserPrefs() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public GuiSettings getGuiSettings() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void setGuiSettings(GuiSettings guiSettings) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public Path getLoveBookFilePath() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void setLoveBookFilePath(Path loveBookFilePath) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void addDate(Date date) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void setLoveBook(ReadOnlyLoveBook newData) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public ReadOnlyLoveBook getLoveBook() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public boolean hasDate(Date date) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void deleteDate(Date target) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void setDate(Date target, Date editedDate) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public ObservableList getFilteredPersonList() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void getBlindDate() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void updateFilteredPersonList(Predicate predicate) {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public String getWelcomeMessage() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public DatePrefs getDatePrefs() {
+ throw new AssertionError("This method should not be called.");
+ }
+
+ @Override
+ public void updateSortedDateList(Comparator