Developer Guide
- Setting up, getting started
- Design
- Implementation
- Documentation, logging, testing, configuration, dev-ops
-
Appendix: Requirements
- Product scope
- User stories
-
Use cases
- Use case U1: Add an expense
- Use case U2: Top-up budget
- Use case U3: Delete an expense
- Use case U4: Edit an expense
- Use case U5: List all expenses
- Use case U6: Add a remark to an expense
- Use case U7: Find an expense
- Use case U8: Sort expense list
- Use case U9: Add category
- Use case U10: Delete category
- Use case U11: Switch category
- Use case U12: Change Command Keyword
- Use case U13: Reset Changed Command Keyword
- Use case U15: Graph Command Keyword
- Use case U14: Reduce Category Budget
- Non-Functional Requirement
- Glossary
- Appendix: Instructions for manual testing
Setting up, getting started
Refer to the guide Setting up and getting started.
Design
Architecture
The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.
.puml
files used to create diagrams in this document can be found in the diagrams folder. Refer to the PlantUML Tutorial at se-edu/guides to learn how to create and edit diagrams.
Main
has two classes called Main
and MainApp
. It is responsible for,
- At app launch: Initializes the components in the correct sequence, and connects them up with each other.
- At shut down: Shuts down the components and invokes cleanup methods where necessary.
Commons
represents a collection of classes used by multiple other components.
The rest of the App consists of four components.
-
UI
: The UI of the App. -
Logic
: The command executor. -
Model
: Holds the data of the App in memory. -
Storage
: Reads data from, and writes data to, the hard disk.
Each of the four components,
- defines its API in an
interface
with the same name as the Component. - exposes its functionality using a concrete
{Component Name}Manager
class (which implements the corresponding APIinterface
mentioned in the previous point.
For example, the Logic
component (see the class diagram given below) defines its API in the Logic.java
interface and exposes its functionality using the LogicManager.java
class which implements the Logic
interface.
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
.
The sections below give more details of each component.
UI component
API :
Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, ExpenseListPanel
, StatusBarFooter
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class.
The UI
component uses 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
is specified in 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.
Logic component
API :
Logic.java
-
Logic
uses theExpenseBookParser
class to parse the user command. - This results in a
Command
object which is executed by theLogicManager
. - The command execution can affect the
Model
(e.g. adding a expense). - The result of the command execution is encapsulated as a
CommandResult
object which is passed back to theUi
. - In addition, the
CommandResult
object can also instruct theUi
to perform certain actions, such as displaying help to the user.
Given below is the Sequence Diagram for interactions within the Logic
component for the execute("delete 1")
API call.
DeleteCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Model component
API : Model.java
The Model
,
- stores a
UserPref
object that represents the user’s preferences. - stores the expense book data.
- exposes an unmodifiable
ObservableList<Expense>
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. - does not depend on any of the other three components.
Tag
list in the ExpenseBook
, which Expense
references. This allows ExpenseBook
to only require one Tag
object per unique Tag
, instead of each Expense
needing their own Tag
object.Storage component
API : Storage.java
The Storage
component,
- can save
UserPref
objects in json format and read it back. - can save the expense book data in json format and read it back.
Common classes
Classes used by multiple components are in the seedu.expense.commons
package.
Implementation
This section describes some noteworthy details on how certain features are implemented.
Category Account Switching Feature
Implementation
The switching mechanism is facilitated by ExpenseBook
and initialised by
Model#switchCategory(Tag category)
. Additionally, ExpenseBook
implements the following operations:
-
ExpenseBook#containsCategory(Tag toCheck)
— Checks if the given tag matches the tag of category budget. -
ExpenseBook#updateExpenseBookCategory(Tag category)
- Updates the expense to only show expenses and budgets that matches the category. -
ExpenseBook#updateFilteredBudgets(Predicate<CategoryBudget> predicate)
— Filters the budget list to the given predicate. -
ExpenseBook#updateFilteredExpenses(Predicate<Expense> predicate)
— Filters the expense list to the given predicate .
These operations are exposed in the Model
interface as
Model#hasCategory(Tag toCheck)
Model#updateExpenseBookCategory(Tag category)
Model#updateFilteredExpenseList(Predicate<Expense> predicate)
Model#updateFilteredBudgetList(Predicate<CategoryBudget> predicate)
Given below is a successful usage scenario example and how the switching mechanism behaves at each step.
Step 1. The user launches the application for the first time. The ExpenseBook
will be initialized with the
initial expense book state in Model.
Step 2. The user executes switch t/Food
command to switch to ExpenseBook
with “Food” tag in category budget
and expenses in the expense book. The switch
command calls Model#switchCategory(Tag category)
. The method then
calls the operations mentioned above causing the category budgets and expenses to be filtered.
The following sequence diagram shows how the switch operation works:
SwitchCommand
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Step 3. The user then decides to execute the command topup
. Commands that modify the expense book,
such as topup
, delete
, edit
, will usually call their respectively method in Model. As such the budget balance
display of the application will change accordingly to reflect on their corresponding values.
Step 4. The user then decides to execute the command list
. Commands that do not modify the expense book but have strong
relationship with altering the budget display such as list
, will usually revert the displayed budget to the overall
amount instead of category-specific. In addition, the expenses calculated will be based on the displayed list total
amount.
Step 5. The user then decides to execute the command find
. Commands that do not modify the expense book and do not
have a clear relationship with the budget display such as find
, will usually omit out the budget display after
their execution. However, exceptions are given to command such as help
, exit
which will not alter the visibility
of the current budget display.
Design consideration:
Aspect: How Category switching executes
-
Alternative 1 (current choice): Filters the entire expense book by category tag.
- Pros: Easy to implement.
- Cons: May have performance issues in terms of execution speed. (Require repeated calculation and filtering)
-
Alternative 2: Create multiple expense books for each category.
- Pros: Will be faster during execution. (Calculation and sorting/filtering are done during initialisation)
- Cons: Slower initialisation and higher overhead cost and more memory used.
Expense Sorting Feature
Implementation
The expense sorting command is facilitated by UniqueExpenseList
and ExpenseBook
. In addition
, a new Command
subclass, SortCommand
, is required. Specifically, the following operations are relevant to this
command:
-
ExpenseBook#sortExpenses(Comparator<Expense> comparator)
— Sorts itsUniqueExpenseList
according to the comparator provided. -
UniqueExpenseList#sortExpenses(Comparator<Expense> comparator)
— Sorts itsObservableList<Expense>
according to the comparator provided.
These operations are exposed in the Model
interface as Model#sortExpenseList(Comparator<Expense> comparator)
SortCommand
and SortCommandParser
SortCommand
will take in at least one, and up to three keywords which specify the order and the parameters to sort
by (date, description, amount). The conversion of the String
input to a SortKeyComparator
, which implements Comparator<Expense>
, is facilitated by
SortCommandParser#parse()
, and the order of the sorting parameters is implemented via the Comparator#thenComparing()
method.
The concrete implementation of the #Compare(Expense other)
method is present in subclasses of SortKeyComparator
: AmountComparator
, DateComparator
, and DescriptionComparator
.
These are the methods that are called when combining SortKeyComparators
through the Comparator#thenComparing()
method.
Command Example:
-
sort -by date
— Sorted by chronological order. -
sort -by date -by descriptionR
— Sorted in chronological order, then based on reverse alphabetical order of descriptions. -
sort -by date -by amount -by description
— Sorted in following order of priority: Chronological order, then by increasing order of amounts, then by alphabetical order of descriptions.
Example Usage
Given below is an example usage scenario and how the sorting command behaves at each step.
Step 1. The user launches the application. The ExpenseBook
shows the list of expenses in the expense book.
Step 2. The user executes sort by/date by/descriptionR
command to sort the Expenses
in ExpenseBook
first by
date, then in reverse alphabetical order of the descriptions.
A comparator is created reflecting the above sorting.
The sort
command calls Model#sortExpenseList(Comparator<Expense> c)
, causing the ExpenseBook
expenses to be
sorted according to the comparator, and the filteredExpenses
in Model
to be modified since it is a listener.
The following sequence diagrams shows how the sort command works:
SortCommand
and
Comparator<Expense>
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
Step 3. The user then decides to execute the command delete
. Commands that modify the expense book, such as delete
, edit
, will usually call their respectively method in Model, but using the new index ordering of the sorted list.
Step 4. The user then decides to execute the command list
. This will revert the display view to initial
ExpenseBook
.
Design consideration:
Aspect: How Sorting Command executes
-
Alternative 1 (current choice): Add an additional sort on top of current list implementation.
- Pros: Easy to implement.
- Cons: Lack customizability in list views.
-
Alternative 2: Create multiple list views each representing a particular sort.
- Pros: Greater degree of customisation with regards to GUI.
- Cons: Difficult to implement as it requires the creation of multiple subclasses of
ListCommand
.
Customisation of Command Keywords using Alias Feature
Implementation
The implementation for the customisation of command keyword shortcuts for various Command
subclasses is by introducing a class called AliasMap
which stores mappings between a command shortcut (‘alias’) and the actual command word of the class, as well as a class called AliasCommand
which takes in two user input as parameters. The first parameter is the default command word for which the user wishes to create an alias, or if there is an existing alias for the command word, it must be the existing alias for which the user wishes to alter into a new alias. The second keyword determines what the command’s (new) alias would be.
Sample usage: By default, the only command word for FindCommand
is "find"
-
alias find get
-> The user can now trigger aFindCommand
with"get"
alias. The"find"
command word will still work. -
alias get find
-> The “get” alias is removed fromAliasMap
object and only"find"
can now triggerFindCommand
. In other words,FindCommand
no longer has an alias.
To maintain some degree of simplicity and neatness, we require that AliasCommand
and ResetAliasCommand
cannot have aliases themselves. Furthermore, any custom alias is restricted to 10 case-sensitive alphabetical characters and each command can only have up to a single alias at any point in time. Default command words of each Command
subclasses cannot be used as aliases.
To allow for customisation to remain even after the user exits the app and subsequently restarts it, a customised alias-to-command mapping will be stored in JSON format, which can be converted to AliasMap
and AliasEntry
objects when Bamboo runs.
The ExpenseBookParser
’s parseCommand()
method takes in an AliasMap object in addition to the user input, which allows the parser to map aliases to the default keyword and allows the execution of the associated Command
object.
Step 1. The user launches the application for the first time. Assume no alias is present (by default, aliases in the JSON file will be the default command word).
Step 2. The user inputs alias find get
to update the alias for FindCommand
as ”get”
.
This will not only update the current AliasMap object, but will also update the JSON mapping with the help of StorageManager which handles all types of storage including JsonAliasMapStorage.
The following is a sequence diagram showing how it works:
Step 3. The user can now use the following command to trigger a FindCommand.
get -d lunch at macs
Design consideration:
Aspect: How alias executes
-
Alternative 1 (current choice): Allows aliases of all command words except for
AliasCommand
. Does not override default command words but merely adds an alias. Reserved keywords cannot be applied unless it is for its associated subclass (i.e. removing the custom alias).- Pros: Neater implementation especially if the user might frequently change his alias.
- Cons: Restricts degree of customisation.
-
Alternative 2: Allows aliases of all command words. Does not override default command words but merely adds an alias. Reserved keywords cannot be applied unless it is for its associated subclass (i.e. removing the custom alias).
- Pros: More flexibility than Alternative 1.
- Cons: Restricts degree of customisation due to reserved keywords not being allowed to use as alias for other Commands.
-
Alternative 3: Allows customisation of ALL command words.
- Pros: Highest degree of flexibility, better for users who can easily get used to Command Line Apps.
- Cons: May be messy and slower learning users may get confused. {more aspects and alternatives to be added}
Default Category
The function of the default category is to subsume all “untagged” expenses
under some category.
This is especially important for possible occasions such as when the User uses the application without any categories,
or when the User deletes a category that existing expenses
are linked to.
Implementation
The default category generally functions the same way as any user-created category, except that it cannot be deleted or renamed. It is contained separately from the user-created categories (if any) for this reason. If a new ExpenseBook is started, the default category is automatically initialized so that the User can use the full range of the basic features even without creating customized categories.
Expense and Budget Categorization Feature
The budgets and expenses in the expense book are grouped according to the user’s specifications, as they can freely create the categories that they need, top-up the desired amount for each category, and tag their expenses (both new and old) to the respective categories to keep track of their spending.
Implementation
Each expense is tagged to exactly one category, and the category must exist in the expense book before any expenses can be tagged to it. When a category is created in the expense book, the corresponding budget is automatically initialized with zero amount. Thereafter, the user can top-up (or reduce) each budget accordingly, and the balance after deducting all expenses within that category is shown to the user.
The activity diagram above shows a possible flow of the user attempting to add an expense tagged to a specific category.
This second activity diagram shows a possible flow of the user trying to top-up the budget of a specific category.
Graphical Representation Feature
Implementation
The graphical representation feature will allow the user to view a pie chart of his/her total spending, with each wedge representing the percentage of spending that corresponds to a specific tag.
This graphical representation will be displayed on GraphDisplayWindow
upon the execution of GraphCommand
. This mechanism will be facilitated by PieChartData
to retrieve the required data from ExpenseBook
.
PieChartData
extends ChartData
which allows abstracting out the implementation of different graphical representation formats for future versions.
-
PieChartData#collectData(ObservableList<Expense>)
— Retrieves required data. -
PieChartData#getData()
— Returns data of eachTag
and the corresponding total expenditure.
The interactions between ExpenseBook
(which contains the in-memory data of expenses) and GraphicalDisplayWindow
(which specifies the UI displayed) facilitated by PieChartData
is given below. </br>
The user initiates this function by executing the graph command. Refer Logic Component architecture diagram for the mechanism by which strings are read and parsed into Command objects.
The sequence diagram below shows the proposed mechanism by which the required data necessary to initialise a pie chart is retrieved. This data is then used to format the UI output.
A possible edge case would be the user having empty expense record prior to executing the graph command. In such a case, the program will display a default message.
The following activity diagram summarizes what happens when a user enters a graph command:
Points to Note:
-
UI classes to only act as placeholders
- UI formatting is separated from the backend logic.
- Allows for dynamic updating of graphs.
-
Data retrieval occurs upon every execution
- Updates graph accordingly.
- Will not show outdated graphs.
-
Easily extensible
- Different sub-classes of
ChartData
can be implemented to collect a variety of meaningful data fromExpenseBook
to be displayed by various UI classes in different formats.
- Different sub-classes of
Documentation, logging, testing, configuration, dev-ops
Appendix: Requirements
Product scope
Target user profile:
- is a college student
- spends money mainly on food, transportation, social life and material goods
- wants to keep track of his personal expenses
- considers oneself as “tech-folk”
- is familiar and comfortable with the command line
- types fast
- wants to set and keep to a budget
- likes things that are fast and simple
- is attached
- pays for his own bills
- is all for cashless
- is cautious about digital security
- prefers storing things digitally rather than on paper
- likes flexibility/customization
- plays games and likes achievements
- is not earning income
- is lazy enough to find a solution to manage his expenses for him
Value proposition: manage expenses faster and simpler than a typical mouse/GUI driven app
User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
user | add a new expense | update my new spending |
* * * |
user | delete an expense | remove entries that I no longer need |
* * * |
user | set a budget | track if I am sticking to my financial goals |
* * * |
user | top up a budget | increase my spending limit |
* * * |
user | edit an expense | change details of the expense that is outdated or wrong |
* * |
organized user | categorise my expenditure | better segregate and manage various areas of my spending |
* * |
new user | use a help command | refer to instructions when I forget how to use the App |
* * |
efficient user | customise my command keywords | customize my user experience and workflow according to my preferences |
* * |
user with many expenses | find expenses via date, keywords, or category | locate a specific expense easily |
* * |
careless user | sort expenses based on date, description, or amount | organise my expenses better and gain a big picture view |
* |
meticulous user | track my saving progress to buy big ticket items | know how far away am I from the target |
* |
user who likes to see progress | use a progress tracker to motivate myself | keep working at saving up |
* |
cautious user | view my ledger data in a human-readable format and only edit the file when commands are executed | be assured that the accounts are updated and accurate |
* |
long-time user | archive older data from my view | manage my expenses easier |
* |
careless user | revert my commands | easily undo changes I made to my budgeting |
* |
user who likes to plan in advance | simulate future spending | visualize my journey towards my financial goals |
* |
forgetful user | receive notifications of budget limits and bill payments | better plan for daily expenditure and make payments on time |
{More to be added}
Use cases
(For all use cases below, the System is the Bamboo and the Actor is the user, unless specified otherwise)
Use case U1: Add an expense
MSS
- User requests to add an expense.
- Bamboo adds the expense.
-
Bamboo lists all expenses and shows the new budget balance.
Use case ends.
Extensions
- 1a. The given command format is invalid.
-
1a1. Bamboo shows an error message.
Use case ends.
-
- 1b. The given field value is invalid.
-
1b1. Bamboo shows an error message.
Use case ends.
-
Use case U2: Top-up budget
MSS
- User requests to top up a specified budget by an amount and category he provides.
- Bamboo tops up the user’s budget in the category and by the amount given by the user.
-
Bamboo updates the budget balance.
Use case ends.
Extensions
- 1a. The given top-up value is invalid.
-
1a1. Bamboo shows an error message.
Use case ends.
-
- 1b. The given category value is invalid.
-
1b1. Bamboo shows an error message.
Use case ends.
-
Use case U3: Delete an expense
MSS
- User requests to list expenses (U5).
- Bamboo shows a list of expenses.
- User requests to delete a specific expense in the list.
- Bamboo deletes the expense.
-
Bamboo lists all expenses and shows the budget balance.
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given expense does not exist.
-
3a1. Bamboo shows an error message.
Use case resumes at step 2.
-
Use case U4: Edit an expense
MSS
- User requests to list expenses (U5).
- Bamboo shows a list of expenses.
- User requests to edit an expense with the new fields given.
- Bamboo edits the expense.
- Bamboo feedbacks to user what was changed.
-
Bamboo lists all expenses and shows the new budget balance.
Use case ends.
Extensions
- 2a. The list is empty.
-
2a1. Bamboo shows an error message
Use case ends
-
- 3a. The given field value is invalid.
-
3a1. Bamboo shows an error message.
Use case ends.
-
Use case U5: List all expenses
MSS
- User requests to list all expenses.
-
Bamboo shows a list of all expenses recorded and the current budget balance.
Use case ends.
Use case U6: Add a remark to an expense
Preconditions:
- Expense List is not empty.
MSS
- User requests to add a remark to specified expense item.
- Bamboo adds remark to specified expense item.
-
Bamboo lists all expenses and shows the budget balance.
Use case ends.
Extensions
- 1a. The given expense does not exist.
- 1a1. Bamboo shows an error message.
Use case ends.
- 1b. The given field value is invalid.
-
1b1. Bamboo shows an error message.
Use case ends.
-
Use case U7: Find an expense
MSS
- User requests to find expense by certain identifiers and search terms.
-
Bamboo shows a list of expenses which match the identifiers and search terms, and shows the overall budget balance.
Use case ends.
Extensions
- 1a. The given field values are invalid.
-
1a1. Bamboo shows an error message.
Use case ends.
-
Use case U8: Sort expense list
MSS
- User requests to sort currently displayed expenses by certain sort criterion.
- Bamboo sorts the currently displayed expenses according to user-specified sort criterion.
-
Bamboo displays the sorted expenses to the user with the budget balance.
Use case ends.
Extensions
- 1a. The given field values are invalid.
-
1a1. Bamboo shows an error message.
Use case ends.
-
Use case U9: Add category
MSS
- User requests to add a new category with a user-specified category name.
- Bamboo creates a new category with the user-specified name and shows a success message.
-
Bamboo lists all expenses and shows the budget balance.
Use case ends.
Extensions
- 1a. The given field values are invalid.
-
1a1. Bamboo shows an error message.
Use case ends.
-
- 1b. The given category name already exists.
-
1b1. Bamboo shows an error message.
Use case ends.
-
Use case U10: Delete category
Similar to U9, except it’s the opposite.
Extensions
- 1a. The given field values are invalid.
-
1a1. Bamboo shows an error message.
Use case ends.
-
- 1b. The given category name does not exist.
-
1b1. Bamboo shows an error message.
Use case ends.
-
- 1c. The given category name is restricted e.g.
Default
category.-
1c1. Bamboo shows an error message.
Use case ends.
-
Use case U11: Switch category
MSS
- User requests to switch to a user-specified category
-
Bamboo shows all expenses which are tagged under the user-specified category, along with the budget for that category.
Use case ends.
Extensions
- 1a. The given field values are invalid.
-
1a1. Bamboo shows an error message.
Use case ends.
-
- 1b. The given category does not exist.
-
1b1. Bamboo shows an error message.
Use case ends.
-
Use case U12: Change Command Keyword
MSS
- User requests to change command keyword to a user-defined string.
-
Bamboo maps the command linked to the original command keyword to the user-defined string.
Use case ends.
Extensions
- 1a. The given field values are invalid.
-
1a1. Bamboo shows an error message.
Use case ends.
-
- 1b. The user-defined string is already a command keyword.
-
1b1. Bamboo shows an error message.
Use case ends.
-
Use case U13: Reset Changed Command Keyword
MSS
- User requests to reset changed command keyword to default command keyword.
-
Bamboo clears the changed commands linked to the original command keyword.
Use case ends.
Extensions
- 1a. No command keyword changed previously.
-
1a1. Bamboo shows an error message.
Use case ends.
-
Use case U15: Graph Command Keyword
MSS
- User requests to view graph of his personal finance.
-
Bamboo displays a pop-up window containing a pie chart showing amount spent for each category.
Use case ends.
Extensions
- 1a. User has not recorded any expenditures into the app.
-
1a1. Bamboo shows a blank pop-up window.
Use case ends.
-
Use case U14: Reduce Category Budget
MSS
- User requests to reduce a given amount of budget from a specific category.
- Bamboo reduces the matching category-budget by the specified amount.
- Bamboo shows the new budget amount for that category.
-
Bamboo updates the budget balance bar.
Use case ends.
Extensions
- 1a. The category does not exist in the expense book.
-
1a1. Bamboo shows an error message.
Use case ends.
-
- 1b. The specified amount is invalid.
-
1b1. Bamboo shows an error message.
Use case ends.
-
- 1c. The specified amount exceeds the amount present in the specified budget.
- 1c1. Bamboo reduces the amount in the specified budget to zero.
- 1c2. Bamboo alerts the user that the amount reduced from the budget exceeded the amount present.
-
1c3. Bamboo updates the budget balance bar.
Use case resumes from 4.
Non-Functional Requirement
Project Constraints:
- Product does not handle user’s actual financial account
- User input in the form of command line
- System should be beginner-friendly
- User’s spending data should be saved in an external storage file
- Storage file should be updated after each addition or update of spending data
- Product is offered as an offline application
Process Requirements:
- Project is expected to adhere to the set Milestones.
- User can execute actions using at most 1 command.
Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X
- Expense: A single instance of expenditure containing a description, amount spent, date, and category. Expenses are subtracted from the user’s budget.
- Budget: The amount a user sets aside to spend.
- Budget Balance: The amount of budget left after deducting all expenses.
Appendix: Instructions for manual testing
Given below are instructions to test the app manually.
Launch and shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum. Alternatively, enter
java -jar expensebook-v1.4.jar
in Command Prompt after switching to the directory with the jar file.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to a different location. Close the window.
-
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-
Deleting an expense
-
Deleting an expense while all expenses are being shown
-
Prerequisites: List all expenses using the
list
command. At least 1 expense in the list. -
Test case:
delete 1
Expected: First expense is deleted from the list. Details of the deleted expense shown in the command box with a uscess. -
Test case:
delete 0
Expected: No expense is deleted. Error details shown in the command box. -
Other incorrect delete commands to try:
delete
,delete x
,...
(where x is larger than the list size)
Expected: Similar to previous.
-
Adding an expense
-
Adding an expense while Expense Book is empty.
-
Prerequisites: List all expenses using
list
command. Expense Book is empty. -
Test case:
add -d lunch -$10
Expected: An Expense with the description “lunch”, costing $10, with the date set as the present date, is added to the expense book. A success message detailing this is shown in the command box. -
Test case:
add -d lunch -$10 -@27/09/2020
Expected: An Expense with the description “lunch”, costing $10, occuring on 27th September 2020 is added to the expense book. A success message detailing this is shown in the command box. -
Test cases:
add -d lunch
Expected: No expense is added. Error details shown in the command box.
-
-
Adding an expense while Expense Book has some expenses
-
Prerequisites: List all expenses using
list
command. Expense Book has at least 1 entry. -
Test case: Add an expense with the same description, amount and date as an existing expense in the expense book.
Expected: No expense is added. Error details shown in the command box.
-
Topup budget
-
Topping up budget without a category specified
-
Test case:
topup -$-10
Expected: Budget is not topped up. Error message shown in command box because of negative value provided. -
Test case:
topup -$10
Expected: “Default” category budget is topped up by $10. A success message detailing this is shown in the command box.
-
-
Topping up budget with a category specified
-
Test case:
topup -$10 t/Food
(“Food” category exists)
Expected: “Food” category budget is topped up by $10. A success message detailing this is shown in the command box. -
Test case:
topup -$10 t/Transport
(“Transport” category does not exist yet)
Expected: No budget is topped up. Error message shown in command box because the “Transport” category does not exist.
-
Saving data
-
Saving data automatically after every command
-
Prerequisites: At least one expense is in the expense book.
-
Add an expense:
add -d test -$10
-
Test case: Close the app, then start it up again.
Expected: the expense book should be the same as when the app was closed.
-