By: Team SE-EDU
Since: Jun 2016
Licence: MIT
- 1. Setting up
- 2. Design
- 3. Implementation
- 3.1. [Proposed] Data Encryption
- 3.2. Reminder Default Feature
- 3.3. General Undo/Redo Feature
- 3.4. Grocery Undo/Redo Feature
- 3.5. Shopping Undo/Redo Feature
- 3.6. Template Undo/Redo Feature
- 3.7. Waste Report Feature
- 3.8. Use Grocery Feature
- 3.9. Add Template Feature
- 3.10. MergeBought Feature
- 3.11. Logging
- 3.12. Configuration
- 4. Documentation
- 5. Testing
- 6. Dev Ops
- Appendix A: Product Scope
- Appendix B: User Stories
- Appendix C: Use Cases
- Appendix D: Non Functional Requirements
- Appendix E: Glossary
- Appendix F: Product Survey
- Appendix G: Instructions for Manual Testing
1. Setting up
Refer to the guide here.
2. Design
2.1. Architecture
The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.
The .puml files used to create diagrams in this document can be found in the diagrams folder.
Refer to the Using PlantUML guide to learn how to create and edit diagrams.
|
-
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 method where necessary.
Commons
represents a collection of classes used by multiple other components.
The following class plays an important role at the architecture level:
-
LogsCenter
: Used by many classes to write log messages to the App’s log file.
The rest of the App consists of four components.
Each of the four components
-
Defines its API in an
interface
with the same name as the Component. -
Exposes its functionality using a
{Component Name}Manager
class.
For example, the Logic
component (see the class diagram given below) defines it’s API in the Logic.java
interface and exposes its functionality using the LogicManager.java
class.
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 glist delete 1
.
glist delete 1
commandThe sections below give more details of each component.
2.2. UI component
API : Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, GroceryListPanel
, 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.
2.3. Logic component
API :
Logic.java
-
Logic
uses theiFridgeParser
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 person). -
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.
tlist add n/Tomato Soup
Command-
args1: tlist add n/Tomato Soup
-
args2: add n/Tomato Soup
-
args3: n/Tomato Soup
The lifeline for AddTemplateListCommandParser , TemplateListParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
|
2.4. Model component
Notes regarding the class diagram:
-
XYZ refers to the different lists used in our model - waste list, grocery list, template list and shopping list.
-
The curved arrows emanating from the
ModelManager
class all refer to filtered lists.
API : Model.java
The Model
,
-
stores a
UserPref
object that represents the user’s preferences. -
stores the data for the different lists: WasteList, GroceryList, TemplateList, ShoppingList.
-
exposes unmodifiable
ObservableList
for all the different lists so 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.
To enhance the OOP-design of our architecture, we abstracted out a separate food class to cater to the different requirements of separate lists.
For instance, shopping lists require its food items to have additional attributes which indicates the urgent and bought status.
|
2.5. Storage component
API : Storage.java
The Storage
component,
-
can save
UserPref
objects in json format and read it back. -
can save the Address Book data in json format and read it back.
2.6. Common classes
Classes used by multiple components are in the seedu.addressbook.commons
package.
3. Implementation
This section describes some noteworthy details on how certain features are implemented.
3.1. [Proposed] Data Encryption
{Explain here how the data encryption feature will be implemented}
3.2. Reminder Default Feature
3.2.1. Implementation
Color coding for grocery list is based on the default number of days set in the iFridge settings in the user prefs. Changing the default reminder number of days will update the color coding in the grocery list accordingly. It will also be saved when the app is closed and used again when the app is relaunched.
Given below is the Sequence Diagram for interactions within the Logic
component for the execute("remDefault r/3")
API call.
remDefault r/3
Command
The lifeline for ReminderDefaultCommandParser should end at the destroy marker (X)
but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
|
3.3. General Undo/Redo Feature
3.3.1. Implementation
There are 3 types of undo/redo feature, glist undo/redo for grocery list, slist undo/redo for shopping list, and tlist undo/redo for template list.
3.3.2. Design Considerations
Aspect: How undo/redo is implemented
Alternative 1 (current choice): Create undo/redo separately for different lists.
-
Pros: More flexibility for user in choosing which list to undo.
-
Cons: Does not support commands which connects between the different lists which has an undo/redo feature of its own (eg. mergebought command which links shopping list and grocery list cannot be undone, as both shopping list and grocery list have their own undo/redo feature and complications may occur due to the interdependency between the different lists)
Alternative 2: Implement undo/redo universally so undo/redo will undo/redo any type of the last command executed.
-
Pros: Supports undoing/redoing commands which connects between different lists as there will be no complications arising from the interdependency of the list.
-
Cons: Less flexibility to choose which list to undo.
3.4. Grocery Undo/Redo Feature
3.4.1. Implementation
Versioned Grocery List extends Grocery List and contains different states of grocery list.
Versioned Waste List extends Waste List and contains different states of waste list.
It supports any kinds of grocery command which modifies the content of the grocery list. Since the delete
grocery command modifies both grocery list and waste list, each grocery command will call
Model#commitGroceryList
and Model#commitWasteList
so that undoing/redoing a grocery delete command will update both
grocery list and waste list, while the other commands will only modify the grocery list.
Given below is an example usage scenario and how the grocery list undo/redo mechanism behaves at each step.
3.5. Shopping Undo/Redo Feature
3.5.1. Implementation
Versioned Shopping List extends Shopping List and contains different states of shopping list.
Versioned Bought List extends Grocery List and contains different states of bought list.
It supports any kinds of shopping command which modifies the content of the shopping list except for mergebought command.
Since the bought shopping command modifies both shopping list and bought list, each shopping command excluding mergebought command
will call Model#commitShoppingList
and Model#commitBoughtList
so that undoing/redoing a bought shopping command will update both
shopping list and bought list, while the other commands will only modify the shopping list.
3.6. Template Undo/Redo Feature
3.6.1. Implementation
Versioned Template List extends Template List and contains different states of template list, previous templates, new templates, and index list.
It supports template list command undo/redo, and template item command undo/redo. Each template command will call Model#commitTemplateList
which updates the corresponding lists in the versioned template list.
When a template list command is undone/redone, the user interface will update the template list panel and clear the template item panel. When a template item command is undone/redone, the user interface will update the template item panel with the corresponding updated template from the prevTemplate/newTemplate list respectively. The index list is used to determine whether a template list command or a template item command is being undone/redone. If the current index is -1, the current state pointer is pointing to a template list command, else, it is pointing to a template item command.
3.6.2. Design Considerations
Aspect: How template undo/redo is implemented
Alternative 1 (current choice): Template undo/redo feature covers both template list command and template item command
-
Pros: Prevents issues surfacing from interdependency between template list and template item command
-
Cons: Less flexibility for users in choosing to undo/redo which list
Alternative 2: Create undo/redo separately for template list command and template item command
-
Pros: More flexibility as users can choose which list to undo/redo
-
Cons: Harder to implement as we need to check for interdependency between the two list and how it affects the other list' state before performing the corresponding undo/redo
3.7. Waste Report Feature
3.7.1. Implementation
The wlist report
feature allows users to generate a graphical report of their food wastage performance.
We illustrate below our method of implementation.
Support for flexibility of months
By allowing the user to specify a start and an end month, thorough checks are implemented in the
WasteReportCommand#execute
method to identify the best suited time frame:
-
After the
WasteReportCommandParser#parse
successfully provides the user-specified start and end months inWasteMonth
objects, the following checks are performed:-
starting month cannot be later than ending month
-
starting month cannot be after current month (latest record in waste archive)
-
ending month cannot be before earliest waste record
-
-
Upon passing the checks, the we proceed to refine the actual start and end months as follows:
-
Starting month will be the later of the specified month and the earliest record found in the waste archive. This is achieved with the use of the
WasteMonth#earlier
method. -
Ending month will be the earlier of the specified end month and the current month (latest record in waste archive). This is achieved with the user of the
WasteMonth#later
method.
-
This completes the first part on checking for a valid range of months.
Generating the report
Under WasteReportCommand#execute
, when iterating through the months from the starting month to
the ending month:
-
We first retrieve the relevant
WasteList
for the month usingModel#getWasteListByMonth(WasteMonth)
-
Thereafter, we obtain a
WasteStatistic
object, which contains the weight, volume and quantity of food wasted for the given month by callingWasteList#getWasteStatistic
.-
Note that the
WasteList#getWasteStatistic
method is a wrapper method to calculate the waste statistics. The actual computation of the statistics for the given waste list is done in theWasteStatistic#getWasteStatistic
static method, which takes in aUniqueWasteList
and calculates the statistics by iterating through the list.
-
-
Collect the data by storing it in a
HashMap
indexed by the month (aWasteMonth
object) with the correspondingWasteStatistic
as the value. -
The data collected in the
HashMap
is used to initiate aWasteReport
object, which will then be passed back to the model, along with the respectiveCommandResult
object.
You may find the following activity and sequence diagrams helpful.
In summary, the activity diagram below illustrates what happens when a command to generate a waste report is entered.
Refer to our user guide to see what constitutes a valid time frame.
To complete the big picture, we have included a class diagram to illustrate the key components pertaining to implementing statistical waste list features.
Our waste archive is stored as a static member of the WasteList class, in the form of a TreeMap .
|
3.7.2. Possible Alternative Implementations
-
Alternative 1 (Chosen implementation)
Go through the waste archive to retrieve the grocery items in the waste list for the past months and calculate the waste statistic for each month.
-
Pros: This is a fail-proof way of ensuring the waste statistics are accurately computed every time.
-
Cons: The runtime is linear in terms of the total number of grocery items found across all waste lists in the waste archive. With a growing waste archive, it will take longer to generate the report.
-
-
Alternative 2
Since the waste statistics for the previous months are unlikely to change, they can be stored externally and loaded upon launch of the application, instead of calculating every time the waste report command is executed.
-
Pros: Will improve the runtime of the application.
-
Cons: Will take up more storage space. Additionally, this does not guard against the event that the user modifies the external storage files which may cause the waste archive and the statistics to be synced incorrectly.
-
3.8. Use Grocery Feature
3.8.1. Implementations
The glist use
feature in the grocery list allows user to use their food items based on the AMOUNT
inputted.
This implementation of this feature is highly dependent on the Amount
class as deduction of values is done by the Amount
class itself.
The sequence diagram for interactions between the Logic and Model components when a user executes the glist use
command is shown below.
The subsequent sequence diagram shows a lower level picture of how a grocery item is used.
The current implementation for using a grocery item is by overwriting the existing grocery item with a new grocery item object with its amount field deducted, as shown in the diagram above. The rest of the fields are copied over without any other modifications.
The glist use
command is also able to support unit conversion. Currently, the implementation of the unit conversion are calculated manually inside the Amount
class. No external library is used.
The following activity diagram summarises how the unit conversion is done.
The conversions of units are done in the Amount
class. Unit type is necessary in the implementation to allow for keeping track of different unit groups across different lists in the application. For example, kg
, g
, lbs
, and oz
are all categorised under the unit type Weight
.
(Refer to the User Guide for more info about the Amount
parameter.
3.8.2. Design Considerations
Aspect: Storing of the value and unit
Alternative 1 (Chosen Implementation) | Alternative 2 | Alternative 3 |
---|---|---|
Storing the value and unit as a combined string.
|
Storing the value and unit as a float and a string
|
Storing the value and unit as two classes of itw own (i.e. Value class and Unit class)
|
Aspect: Deducting the Amount
Alternative 1 (Chosen Implementation) | Alternative 2 |
---|---|
Create a new grocery item and replace it with the old one.
|
Modify the
|
Aspect: Keeping track of unit type
Alternative 1 (Chosen Implementation) | Alternative 2 |
---|---|
Keeping the original unit of the item.
|
Changing the original unit of item to the one input by user.
|
3.9. Add Template Feature
The add template mechanism is facilitated by UniqueTemplateItems
, TemplateList
.
The TemplateList
is an observable list of UniqueTemplateItems
while the UniqueTemplateItems contains an observable list
of template items.
To add a template into the TemplateList
, a new UniqueTemplateItems
object is created with the entered name.
The model is updated with the new TemplateList
containing the new UniqueTemplateItems
object. The TemplateToBeShown
, which is an instance of the object UniqueTemplateItems
containing
the details of the template being edited or viewed will not be updated. Only a TemplateItemCommand
will involve an update of the TemplateToBeShown
.
Due to multiple lists in the iFridge app, the template list will only be usable to the user when executing a TemplateList or a TemplateItem Command. For example, an AddTemplateListCommand or a AddTemplateItemCommand. |
The following activity diagram summarizes what happens when a user executes a new template list command related to the managing of templates and illustrates some differences in the UI as compared to when a template item command is executed:
The following sequence diagram shows how the edit template item operation works for the logic component:
Due to lack of space, please refer to the below list for args1, args2, args3 shown in the diagram above.
-
args1: "tlist add n/Tomato Soup"
-
args2: "add n/Tomato Soup"
-
args3: "n/Tomato Soup"
The lifeline for TemplateListParser , AddTemplateListCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
|
3.9.1. Design Considerations
Aspect: How add command is parsed
Refer to the above class diagram about the logic component that shows the relationship between the TemplateListParser and the TemplateItemParser.
-
Alternative 1 (current choice): Create a separate parser for template list management and template item management
-
Pros: Easy to implement. Parser structure follows the same structure as the model. More OOP.
-
Cons: May be confusing to differentiate between TemplateItemParser and TemplateListParser.
-
-
Alternative 2: The TemplateListParser is able to distinguish between template and template item management and call the respective XYZCommandParsers
-
Pros: Less confusing as there is only one parser toggling between the different command parsers to managing the template list.
-
Cons: Implementation of the parser becomes less OOP.
-
-
Alternative 3: The TemplateItemParser is at the same hierarchy as the TemplateListParser instead of inside.
-
Pros: The user command can be shorter. E.g. "template edit …" instead of "tlist template edit …"
-
Cons: Not as obvious to the user that both commands involve the same template list.
-
3.10. MergeBought Feature
3.10.1. Implementations
The user is able to merge all the bought shopping items into the grocery list. This can be done with the use of the `slist mergebought' command.
The current implementation to merge bought items is as follows:
-
For each boughtItem in boughtList:
-
For each groceryItem in GroceryList
-
If there is an existing groceryItem in GroceryList with same name and expiry date as the boughtItem, the quantity of that groceryItem will be updated according to the amount bought.
-
If there is no existing groceryItem with same Name and ExpiryDate, the boughtItem will be added to the GroceryList.
-
-
For each shoppingItem in ShoppingList find the bought shoppingItem with same name as the boughtItem:
-
If the boughtItem has greater Amount than its corresponding shoppingItem, the shoppingItem is deleted from the ShoppingList.
-
If the boughtItem has lesser Amount than its corresponding shoppingItem, the shoppingItem’s quantity is just reduced. The shopping item loses its bought tag since there are no bought items that have not been moved to the grocery list.
-
-
The Merge Bought mechanism is facilitated by ShoppingList
, GroceryList
, and ShoppingComparator
.
The ShoppingList
is an observable list of ShoppingItem
and GroceryList
is an observable list of GroceryItem
.
Merging needs to use the BoughtList to modify the ShoppingList and GroceryList. Hence, the command retrieves the 3 lists.
When a GroceryItem
's amount is be added, the GroceryItem at that index is overwritten by a new GroceryItem with the updated amount. If a new boughtItem (Groceryitem
) is to be added to the GroceryList
, it is appended to the GroceryList
Similarly, when a ShoppingItem
's amount is reduced, the ShoppingItem at that index is overwritten by a new ShoppingItem with the updated amount. If a ShoppingItem
is to be deleted from the ShoppingList
, it is deleted and the ShoppingList
is sorted using a ShoppingComparator
.
The creation of new objects to replace the existing ones is necessary since all the objects are immutable.
-
Model#getFilteredBoughtList — Gets
ObservableList
with the elements of theModel
's boughtList (stored in aGroceryList
) -
Model#getFilteredGroceryList — Gets
ObservableList
with the elements of theModel
'sGroceryList
-
Model#getFilteredShoppingList — Gets
ObservableList
with the elements of theModel
'sShoppingList
-
Model#setBoughtList — Sets the boughtList as the specified
GroceryList
-
Model#sortShoppingItems — Sorts the
ShoppingList
by urgent status first, and then by alphabetical order. -
MergeShoppingCommand#modifyGroceryListAccordingToBoughtItem — Updates
GroceryList
according to a boughtItem -
MergeShoppingCommand#modifyShoppingListAccordingToBoughtItem — Updates
ShoppingList
according to a boughtItem
These operations are exposed in the Model
interface as Model#getFilteredBoughtList
The sequence diagrams for interactions between Logic and Model components when a user executes slist mergebought
command is shown below.
The following activity diagram summarises how slist mergebought
is carried out.
The mergebought command supports unit conversion. The boughtAmount’s unit will be converted to match the groceryAmount. The following activity diagram delineates how the unit conversion takes place.
The conversions of units are done by Amount
class. Unit type is necessary in the implementation to allow for keeping track of different unit groups. For example, kg
, g
, lbs
, and oz
are all categorised under the unit type Weight
.
3.10.2. Design Considerations
Aspect: Storing BoughtItems
Alternative 1 (Chosen Implementation) | Alternative 2 | Alternative 3 |
---|---|---|
Use
|
Use
|
Use child class of
|
3.11. Logging
We are using java.util.logging
package for logging. The LogsCenter
class is used to manage the logging levels and logging destinations.
-
The logging level can be controlled using the
logLevel
setting in the configuration file (See Section 3.12, “Configuration”) -
The
Logger
for a class can be obtained usingLogsCenter.getLogger(Class)
which will log messages according to the specified logging level -
Currently log messages are output through:
Console
and to a.log
file.
Logging Levels
-
SEVERE
: Critical problem detected which may possibly cause the termination of the application -
WARNING
: Can continue, but with caution -
INFO
: Information showing the noteworthy actions by the App -
FINE
: Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size
3.12. Configuration
Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json
).
4. Documentation
Refer to the guide here.
5. Testing
Refer to the guide here.
6. Dev Ops
Refer to the guide here.
Appendix A: Product Scope
Target user profile:
-
has a need to manage a significant number of groceries
-
has a tendency to forget to keep track of expiring items
-
interested in reducing their own food waste
-
wants an hassle-free way to shop for groceries
-
can type fast
-
prefers typing over mouse input
-
is reasonably comfortable using CLI apps
Value proposition: manage food inventory in order to reduce food waste
Appendix B: User Stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
|
organized user |
add items to shopping list |
decide the grocery items that I need to purchase later |
|
organized user |
mark grocery items as bought and add their corresponding expiry and amount details |
keep track of bought groceries |
|
lazy user |
add all bought items to grocery list |
update grocery to contain all the bought items |
|
meticulous user |
display shopping list |
view the items in shopping list (items yet to be bought before bought items) |
|
organized user |
tag items (not yet bought) in shopping list as urgent |
view the urgent items first when I display shopping list |
|
careless user |
edit and delete items in shopping list |
change details of or remove grocery items |
|
user |
create pdf of shopping list |
refer to the pdf while shopping |
|
user |
add templates of grocery items |
to keep track of what I want to have in my fridge |
|
user |
edit templates of grocery items |
edit items and volumes based on my current needs and preferences |
|
user |
delete templates |
maintain a short list of templates I regularly use |
|
user |
add multiple templates |
use different templates depending on the occasion |
|
user |
generate a shopping list using my templates |
save time on checking what is missing from my fridge |
|
environmentally-conscious user |
compare my food wastage statistics |
better manage my food waste |
|
environmentally-conscious user |
get feedback on how I am performing on my food waste management |
improve my food waste management |
|
environmentally-conscious user |
see which kinds of food I most commonly waste |
cut down on unnecessary food waste |
|
forgetful user |
see a list of my expired food items |
retrieve and dispose of them |
|
user |
add groceries |
keep track of all the groceries bought |
|
user |
see the expiry dates of my groceries |
manage my usage accordingly. |
|
user |
update my grocery list |
keep track of the amount of groceries I have |
|
user |
find a specific grocery |
be more efficient in finding a specific item |
|
user |
view all groceries |
know what to buy more of |
|
user |
remove a grocery |
maintain only usable items in the fridge |
|
user with many grocery items in the grocery list |
sort grocery items by expiry date |
locate an expired grocery item easily |
|
forgetful user |
get reminders on expiring food items |
prevent food wastage |
|
user |
set default reminder settings |
get reminders of expiring food within the specified number of days every time I launch the app |
|
organised user |
sort food items |
view grocery list with the specified sorting method |
|
user |
set default sort settings |
view grocery list with the specified sorting method every time I display the grocery list |
Appendix C: Use Cases
(For all use cases below, the System is the iFridge
and the Actor is the user
, unless specified otherwise)
Use case: Edit grocery item
MSS
-
User requests to list grocery items
-
iFridge shows the list of grocery items
-
User requests to edit a specific grocery item’s name/expiry date/tag
-
iFridge performs the specified edit on the specified grocery item
Use case ends.
Use case: Add food item
MSS
-
User requests to list all food items
-
iFridge shows a list of food items
-
User requests to add an item to the list
-
iFridge appends the item to the list
Use case ends.
Extensions
-
3a. The given input is invalid
-
3a1. iFridge shows an error message.
Use case ends.
Extensions
-
-
2a. The list is empty.
Use case ends.
-
3a. The given input is invalid
-
3a1. iFridge shows an error message.
Use case resumes at step 2.
Use case resumes at step 2.
-
-
3b. The given amount is negative.
-
3b1. iFridge shows an error message.
Use case resumes at step 2.
-
-
3c. The given expiry date is of invalid format
-
3c1. iFridge shows an error message.
-
Use case: Removing a tag
MSS
-
User requests to list all food items
-
iFridge shows a list of food items
-
User requests to remove a tag from a specific food item in the list
-
iFridge removes the tag
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. iFridge shows an error message.
-
Use case resumes at step 2.
-
-
3b. The tag specified is non-existent.
-
3b1. iFridge shows an error message.
-
Use case resumes at step 2.
-
Use case: Using food item
MSS
-
User requests to list all food items
-
iFridge shows a list of food items
-
User requests to use a certain amount of a specific food item
-
iFridge reduces the amount of the specific food item
Use case ends.
-
3a. The given amount is more than the amount of food registered in the list.
-
3a1. iFridge shows an error message.
Use case resumes at step 2.
-
-
3b. The given amount is exactly the same as amount of food registered in the list.
-
3b1. iFridge removes the food item from the list.
Use case ends.
-
3a1. iFridge shows an error message.
-
-
Use case: Delete grocery item
MSS
-
User requests to list grocery items
-
GroceryList shows a list of grocery items
-
User requests to delete a specific grocery item in the list
-
GroceryList deletes the grocery item
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. GroceryList shows an error message.
Use case resumes at step 2.
-
Appendix D: Non Functional Requirements
-
Should work on any mainstream OS as long as it has Java
11
or above installed. -
Application should be used by a single user.
-
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.
-
A user must be able to work with command-line interface.
-
Should be able to hold up to 1000 food items without a noticeable sluggishness in performance for typical usage.
-
Storage comprises of human editable file.
-
No database management systems used.
-
Application has object-oriented design.
-
Application is platform independent, portable and does not use a remote server or external software.
-
Application has easy to test features.
Appendix F: Product Survey
Product Name
Author: …
Pros:
-
…
-
…
Cons:
-
…
-
…
Appendix G: Instructions for Manual Testing
Given below are instructions to test the app manually.
These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing. |
G.1. Launch and Shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file (for Mac users, navigate to the folder in terminal and run it using the command
java -jar iFridge.jar
)
Expected: Shows the GUI with a set of sample grocery list, template list, waste list and shopping list items. The window size may not be optimum.
-
-
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.
-
G.2. Grocery List Manual Testing
-
Adding a grocery item while all items are listed
-
Prerequisites: List all grocery items in the grocery list using the
glist list
command. The grocery list can be empty or contain some items. -
Test case:
glist add n/Coffee a/200ml e/19/11/2019 t/caffeine
Expected: If the grocery list is empty, a grocery item would be added to the grocery list. Details of the added grocery item would also be shown in the status message.
-
-
Deleting a grocery item while all items are listed
-
Prerequisites: List all grocery items in the grocery list using the
glist list
command. Multiple grocery items exist in the grocery list. -
Test case:
glist delete 1
Expected: First grocery item is deleted from the grocery list. Details of the deleted grocery item is shown in the status message. -
Test case:
glist delete 0
Expected: No grocery item is deleted. Error details is shown in the status message. -
Other incorrect delete commands to try:
glist delete
,glist delete x
(where x is larger than the list size). Expected: Similar to previous.
-
-
Editing a grocery item in the grocery list
-
Prerequisites: List all grocery items in the grocery list using the
glist list
command. Multiple grocery items exist in the grocery list. Item to be edited must not same name and expiry date as any other item in the list. -
Test case:
glist edit 1 n/Papaya
Expected: If the first grocery item has unique name and expiry date in the grocery list, the grocery item’s name is edited to Papaya. Other fields remain the same. Details of the edited grocery item is shown in the status message.
If the first grocery item does not have unique name and expiry date in the grocery list, the grocery item’s name is not edited. Error details is shown in the status message. -
Test case:
glist edit 2 a/500ml
Expected: Error details is shown in the status message as amount field cannot be edited.
-
-
Using a grocery item in the grocery list
-
Prerequisites: List all grocery items in the grocery list using the
glist list
command. Multiple grocery items exist in the grocery list. Item to be used has the same unit type and is not used up completely. Amount left exceeds amount to be used. -
Test case:
glist use 1 a/50ml
Expected: The amount of the first grocery item is deducted by 50ml. Other fields remain the same. Details of the used grocery item is shown in the status message. -
Other invalid use commands to try:
glist use 2 a/400g
(where the item has unit of L),glist use 2 a/30lbs
(where the amount of the item is less than 30lbs).
-
-
Sorting the grocery list
-
Prerequisites: List all grocery items in the grocery list using the
glist list
command. Multiple grocery items exist in the grocery list. -
Test case:
glist sort by/expiry
Expected: The displayed grocery list would be sorted based on the grocery item’s expiry date in ascending order (from earliest to most recent). -
Test case:
glist sort by/alphabetical
Expected: The displayed grocery list would be sorted based on the grocery item’s name in ascending alphabetical order.
-
-
Finding items based on name or tag
-
Prerequisites: List all grocery items in the grocery list using the
glist list
command. Multiple grocery items exist in the grocery list. Name or tag to be found may exist or not exist in any of the grocery items. -
Test case:
glist find apple snack
Expected: The displayed grocery list would now contain items that hasapple
andsnack
as either their name or tag. If no items match, the displayed list would be empty.
-
G.3. Waste List Manual Testing
-
Moving an item into the waste list
-
Prerequisites: List all grocery items in the grocery list using the
glist list
command. The item must exist in the grocery list, and has not been fully consumed (i.e. amount = 0). -
Test case:
glist delete 1
Expected: First grocery item is deleted from the list. Details of the removed grocery item shown in the status message. If item has been fully consumed, it will be permanently removed from iFridge.
-
-
Listing out the waste list for a particular month
-
Prerequisites: Waste list must exist in waste archive.
-
Test case:
wlist list
Expected: The tab for the waste list is shown and is updated to reflect all waste items for the current month. -
Test case:
wlist list m/sep 2019
Expected: The tab for the waste list is shown and is updated to reflect all waste items for the month of September 2019, if such a waste list exists in the waste archive. -
Test case:
wlist list m/last month
Expected: The tab for the waste list is shown and is updated to reflect all waste items for the last month, if such a waste list exists in the waste archive. -
Test case:
wlist list m/invalid
Expected: Error message for invalid command displayed. -
Other invalid test cases:
wlist list m/Decemer 2019
. More details on valid or invalid date formats can be found in our user guide.
-
-
Obtaining predicted food wastage for the current month
-
Test case:
wlist feedback
Expected: Message box displays the current and predicted food wastage. -
You are free to modify the json file
wastearchive.json
to see how our feedback feature performs differently. The estimated food wastage is predicted by taking the weighted average of waste statistics using (at most) the four most recent waste lists.
-
-
Generating a waste report
-
Test case:
wlist report
Expected: iFridge will display a window with 3 charts detailing food wastage statistics. It will attempt to generate a waste report from one year ago till the current month (e.g. if the current month is Nov 2019, it will attempt to generate a report from Nov 2018 to Nov 2019) with sufficient data. If there is insufficient data, it will only display the records starting from the earliest month found in iFridge’s waste archive. -
Test case:
wlist report sm/5 months ago
Expected: iFridge will attempt to generate a report using data from 5 months ago to the current month.
We have a detailed section in our User Guide on the specifications of the starting and ending months along with their expected behaviour -
Test case:
wlist report sm/next month
Expected: Error message displayed suggesting that the start month cannot be later than the current month. -
Test case:
wlist report em/Sep 1990
Expected: Assuming we have no data for the month of Sep 1990, an error message will be displayed suggesting that there is no valid data in the time frame. It also indicates to the user what the earliest record in the waste archive is. -
Other invalid test cases:
wlist report sm/Oct 2019 em/Jul 2019
,wlist report sm/in 12 weeks
-
G.4. Shopping List Manual Testing
-
List all items in shopping list
-
Test case:
slist list
Expected: The shopping list is displayed, with 3 sections (urgent, not urgent and not fully bought, fully bought). Within each of the three sections of the shopping items, items are sorted alphabetically.
-
-
Adding an item to the shopping list
-
Test case:
slist add n/Grapes a/500g
Expected: Shopping item with nameGrapes
and amount500g
is created and added to the shopping list. The details of the added shopping item are displayed. The new shopping item appears after urgent items and before fully bought items in the shopping list. -
Test case:
slist add n/Grapes a/invalidAmount
Expected: Error message displayed indicating invalid amount entered. -
Test case:
slist add n/Grapes
Expected: Error message displayed that indicates that the command format is wrong. The correct format for the add shopping command is also displayed. -
Test case:
slist add a/5g
Expected: Error message displayed that indicates that the command format is wrong. The correct format for the add shopping command is also displayed. -
Test case:
slist add
Expected: Error message displayed that indicates that the command format is wrong. The correct format for the add shopping command is also displayed.
-
-
Editing an item in the shopping list
-
Test case:
slist edit 1 n/Oranges
Expected: First shopping item’s name is edited to 'Oranges'. Details of the edited shopping item are displayed. If some or all of the item was bought, the name of the corresponding bought item is also changed in storage to avoid inconsistencies. -
Test case:
slist edit 1 a/50g
Expected: First shopping item’s amount is edited to 50g. Details of the edited shopping item are displayed. -
Test case:
slist edit 1
Expected: Error message displayed indicating that at least one field to be edited must be provided.
-
-
Deleting an item in the shopping list
-
Test case:
slist delete 1
Expected: First shopping item is deleted from the shopping list. Details of the removed shopping item are displayed.
-
-
Marking a shopping item as urgent
-
Test case:
slist urgent 1
Expected: Marks the first shopping item as urgent. Details of the shopping item marked as urgent are displayed. The shopping item gets anUrgent!
tag and moves towards the upper section of the shopping list (with other urgent items). -
Test case:
slist urgent
Expected: Error message displayed indicating wrong command format. The correct format of an urgent shopping command is also displayed.
-
-
Buying a shopping item (Marking a shopping item as Bought)
-
Test case:
slist bought 1 a/50g e/24/11/2019
Expected: First shopping item is marked as bought. A bought item is created with the name of the shopping item and with the amount and expiry date provided in the command. It gets aPartially Bought
tag if the amount bought is less than the amount of the shopping item, and it gets aFully Bought
tag if the bought amount is greater than or equal to the amount of the shopping item. In either case, the tag also displays the amount of shopping item bought. If an item is fully bought, it moves to the bottom of the shopping list (regardless of whether it is urgent or not). Details of the shopping item marked as bought are also shown. -
Test case:
slist bought 2 a/0g e/24/11/2019
Expected: Error message displayed indicating that the amount specified cannot be 0 or negligible. The guidelines of how to use amount are also specified. -
Test case:
slist bought 1 a/50g
Expected: Error message displayed indicating that the command format is wrong. The correct format for a bought shopping command is also displayed. -
Test case:
slist bought 1 e/23/04/2019
Expected: Error message displayed indicating that the command format is wrong. The correct format for a bought shopping command is also displayed.
-
-
Merging bought items into the grocery list (moving bought items into fridge)
-
Prerequisites
Some of the items in the shopping list must be bought for changes in the lists to take place. -
Test case:
slist mergebought
Expected: All bought items are added to the grocery list according to the following conditions: If a bought item does not have a corresponding grocery item (same name and expiry date) in the grocery list, a new grocery item with the bought item’s details is added to the grocery list. If a bought item has a corresponding grocery item in the grocery list, the grocery item’s amount is added instead of creating a new grocery item.
If a shopping item was fully bought, it is removed from the shopping list while merging. If the item is only partially bought, the quantity that is bought is subtracted from the shopping item’s quantity and the bought tag will be removed.
-
G.5. Template List Manual Testing
-
Adding a template
-
Prerequisites: Template list must contain a template with the name 'Birthday Party'.
-
Test case:
tlist add n/x
(where x is a template name that does not currently exist in the template list) Expected: Template added into the list. The templates in the list are sorted by alphabetical order. -
Test case: 'tlist add n/Birthday Party'
Expected: No template added to the template list. Error details shown in the status message. -
Other incorrect add commands to try:
add
,tlist add
,tlit add
-
-
Deleting a template
-
Prerequisites: There must be at least one template in the template list.
-
Test case:
tlist delete 1
Expected: Template deleted from the list. -
Test case:
tlist delete x
(where x is larger than the template list size) Expected: No template deleted. Error details shown in the status message. -
Other incorrect delete commands to try:
tlist delete
,tlist 0
-
-
Editing a template
-
Prerequisites: There must be at least one template in the template list with no templates named
Monthly Necessities
. -
Test case:
tlist edit 1 n/Monthly Necessities
Expected: Template edited with the nameMonthly Necessities
. -
Test case:
tlist edit 0 n/Monthly Necessities
Expected: No template edited. Error details shown in the status message.
-
-
Adding a template item
-
Prerequisites: Template list must contain at least one template.
-
Test case:
tlist template add 1 n/x a/y
(where x is a item name that does not currently exist in the first template and y is a valid amount for the item). Expected: Template item added into the list. -
Test case:
tlist template add 0 n/x a/y
(where x is a item name that does not currently exist in the first template and y is a valid amount for the item). Expected: Template item not added into the list. Error details shown in status message. -
Other incorrect add template item commands to try:
-
tlist template add 1 n/x a/y
(where x is an item name that already exists in the template) -
tlist template add 1 n/x a/y
(where x is an item name that already exists in another template or list, and y is an invalid amount with a unit type that conflicts that of the other item entry)
-
-
-
Editing a template item
-
Prerequisites: Template list must contain at least one template, which contains at least one item.
-
Test case:
tlist template edit 1 i/1 n/x
(where x is an item name that does not already exist in the template). Expected: Template item added into the template. -
Test case:
tlist template edit 1 n/x
(where x is an item name that does not exist in the template). Expected: Template item not added into the list. Error details shown in the status message. -
Other incorrect edit template item commands to try:
-
tlist template edit 1 i/1 n/x
(where x is an item name that does not exist in the template). -
tlist template edit 1 i/1 n/x a/y
(where x is an item name that already exists in another template or list, and y is an invalid amount with a unit type that conflicts that of the other item entry) -
tlist template edit z i/1 n/x a/y
(where x and y are valid name and amounts and z is greater than the template size.
-
-
-
Deleting a template
-
Prerequisites: Template list must contain at least one template, which contains at least one item.
-
Test case:
tlist template delete 1 i/1
Expected: Template item deleted from the template. -
Test case:
tlist template delete 1 i/0
Expected: Template item not deleted. Error details shown in the status message. -
Other incorrect delete template item commands to try:
tlist template delete x i/1
where x is greater the the template list size,tlist template 1 i/x
where x is greater than the template size.
-
-
Adding a template to the shopping list
-
Prerequisites: Template must contain at least one template with one item with name 'FullFat Milk' and amount '300ml. Grocerylist should have several entries of FullFat Milk with slight variations in name and amount. For e.g.:
-
For name: fullfat milk, Fullfat Milk, FULLFAT MILK
-
For amount: 300ml, 400ml, 1L, 0.3L
-
-
Test case:
slist addTemp 1
Expected: All items in the template that are either not found in the grocery list or are already expired will be added into the shopping list. The amount of the item that is added to the shopping list is the result after subtracting all non-expired grocery item amounts from the amount stated in the template item entry. In the case that the sum in the grocerylist exceeds the required amount, the item will not be added to the shopping list and message will be shown stating all items are in stock. In the case that the shopping list already has FullFat Milk, the result is added to original amount recorded. -
Test case:
slist addTemp 0
Expected: No items added into the shopping list. Error details shown in the status message. -
Other incorrect commands to try:
slist addTemp x
where x is greater than the template list size.
-
G.6. Undo Redo Manual Testing
-
Undo a grocery list command
-
Prerequisites: At least one grocery command have been done which modifies the content of the grocery list.
-
Test case:
glist delete 1
+glist undo
Expected: The tab for waste list is shown if another tab is currently opened and the grocery item which has been removed from grocery list and added to waste list is now removed from waste list and added back to grocery list. -
Test case:
glist add n/potato a/10g e/10/10/2020
+glist undo
Expected: The tab for the waste list is not shown if another tab is currently opened and the grocery item which has just been added to the grocery list is now removed. -
Test case:
glist list
+glist undo
Expected: Error message displayed suggesting not able to undo asglist list
command does not modify the grocery list.
-
-
Undo a template list command
-
Prerequisites: At least one template command (template list or template item command) have been done which modifies the content of the template list or template item respectively.
-
Test case:
tlist delete 1
+tlist undo
Expected: The tab for template list is shown while template item is cleared and the template which has been removed from template list is added back to template list. -
Test case:
tlist template add 1 n/potato a/10g
+glist undo
Expected: The tab for template list is shown along with the specified template being updated and the template item which has been added to the specified template is removed from the template.
-
-
Undo a shopping list command
-
Prerequisites: At least one shopping command have been done which modifies the content of the shopping list.
-
Test case:
slist add n/Milk a/1L
+slist undo
Expected: The tab for shopping list is shown
-
-
Redo grocery, template, or shopping list command
-
Prerequisites: At least 1 undo has been done for the corresponding list.
-
G.7. Reminder Manual Testing
-
Set default reminder settings to determine which food are expiring "soon"
-
Prerequisites: Have at least 1 grocery item in grocery list which has not expired (has an expiry date of at least the current date or after) to see visible results.
-
Test case:
glist remDefault r/10
Expected: Grocery items (in grocery list and waste list) with expiry dates within 10 days from current date will be color coded as orange while grocery items which are not expiring within 10 days will be color coded green. Expired grocery items will still remain red. The color coding will be retained when the app is closed and relaunched.
-
-
Get reminder on food expiring soon
-
Prerequisites: Have at least 1 grocery item in grocery list which has not expired to see visible results.
-
Test case:
glist rem r/0
Expected: Displays all grocery items expiring on the same date as today in grocery list. -
Test case:
glist rem
Expected: Displays all grocery items in grocery list which are expiring within the specified number of days in the default reminder settings. If default reminder settings is not specified yet, number of days in default reminder settings is set to 3 days.
-
G.8. Saving data
-
Dealing with missing/corrupted json files
-
In the event that no json file is found in the data folder for a specific list, our app will initialise with some sample data for that particular list.
-
If a corrupted file is found in the data folder for a specific list, a new file will be created.
-