Overview
By: AY1920S2-CS2103T-W12-4
Since: Feb 2020
Licence: MIT
1. Introduction [Done by Zain Alam]
Welcome to CookBuddy!
For more information about using CookBuddy, consult the CookBuddy User Guide.
CookBuddy is an integrated platform fully customized for users who wish to manage their recipes easily and effectively.
All your recipe information is stored on our simple and clean Graphical User Interface (GUI) with optimization for users who prefer working on a Command Line Interface (CLI).
If you are looking for a way to easily manage your recipes and have quick fingers, then CookBuddy is definitely for you!
2. About this Document [Done by Zain Alam]
This document is a Developer Guide written for developers who wish to contribute to or extend our CookBuddy project. It is technical, and explains the inner workings of CookBuddy and how the different components of our application work together.
We have adopted a "top-down" approach in structuring our Developer Guide with first focusing at the high-level architecture of CookBuddy and then delving into the implementation details of each feature that makes up our application.
Take note of the following symbols and formatting used in this document:
This icon denotes useful tips to note of during development. |
This icon denotes important details to take note of during development. |
3. Overview of Features [Done by Zain Alam]
This section will provide you a short overview of CookBuddy’s features.
-
Manage your recipes easily
-
Include recipe information e.g. ingredients, instructions, calories, difficulty, rating, serving, tags etc.
-
-
Various icons to find information easily and quickly
-
Various icons display short information such as difficulty, serving size, tags etc of a recipe.
-
-
Data is saved onto your disk automatically
-
Any changes made will be saved onto your device so you dont have to worry about the data being lost.
-
4. Setting up
Refer to the guide here.
5. Design
5.1. Architecture
The Architecture Diagram given above explains the high-level design of CookBuddy. A quick overview of each component is given below.
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 the UML 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 CookBuddy’s log file.
The rest of CookBuddy 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.
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
.
delete 1
commandThe sections below give more details of each component.
5.2. UI component
API : Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, RecipeListPanel
, StatusBarFooter
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class.
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
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.
The For more information on JMetro, refer to the JMetro home page. |
5.3. Logic component
API :
Logic.java
-
Logic
uses theRecipeBookParser
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 recipe). -
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.
delete 1
Command
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.
|
5.4. Model component
API : Model.java
The Model
,
-
stores a
UserPref
object that represents the user’s preferences. -
stores the Recipe Book data.
-
exposes an unmodifiable
ObservableList<Recipe>
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.
As a more OOP model, we can store a Tag list in Recipe Book , which Recipe can reference. This would allow Recipe Book to only require one Tag object per unique Tag , instead of each Recipe needing their own Tag object. An example of how such a model may look like is given below. |
5.4.1. The attribute
package
attribute
package, defining each Recipe
's key attributesattribute
defines common attributes for each recipe, such as time taken to cook, serving size, an image of the recipe, and so on.
5.5. Storage component
API : Storage.java
The Storage
component manages the recipe data, the user configuration, preferences, and the image data. To be specific, it:
-
reads and writes
UserPref
objects to and from disk, as.json
format; -
serialises, reads and writes recipe data to and from disk, also as
.json
format; -
passes on the file path for the user-entered image into methods in the
ImageUtil
class. More details are given in Section 6.2.3, “Design Considerations”.
5.6. Common classes
Classes used by multiple components are in the cookbuddy.commons
package; the three over-arching sub-packages are core
, exceptions
, and util
.
5.6.1. core
This package defines classes for user configuration, GUI settings, and even a version number.
5.6.2. exceptions
This package defines exceptions thrown by CookBuddy when it encounters an error state.
5.6.3. util
This package defines utility classes for certain operations, like file I/O, argument validation, and image processing.
6. Implementation details and Possible Enhancements
This section describes some noteworthy details on how certain features are implemented.
Some possible future components are briefly covered, and these may be released in v2.0
.
6.1. Counting recipes [Done by Zain Alam]
We allow users to count the total number of recipes stored in CookBuddy. This section shows how we handle this request from the user.
6.1.1. Implementation
We store every single Recipe
added by the user into an ObservableList<Recipe>
, which is a list object in UniqueRecipeList
. We used an ObservableList
to easily reflect changes to the list by any other component of CookBuddy using the list.
The count
command was implemented as a CountCommand
in the bookbuddy/logic/commands
package.
The count
has the following input format: count
The following sequence diagram shows how the count operation works:
count
command is processed.An incorrect syntax will cause a ParseException
to be thrown by the parser.
Incorrect user input will display Unknown command message. |
We will now demonstrate how a count
command works in CookBuddy
:
Step 1. The user executes the command count to count the total number of recipes stored in CookBuddy.
Step 2. The input is now checked and an attempt to parse the parameter occurs. The CountCommand#execute(Model model)
method is executed.
Step 3. The method Model#count()
will then be called to calculate the total number of recipes stored in CookBuddy.
Step 4. If successful, a success message will be generated by CommandResult
and it will be returned with the generated
success message. Otherwise, an error message is thrown as ParseException
.
Since the user, input in this case, is valid,
the count
command is successfully executed and the total number of recipes currently stored in CookBuddy is displayed.
The following activity diagram summarizes what happens when the user executes count
command to count the total number of recipes:
6.2. Image Management [Done by Sharadh Rajaraman]
CookBuddy allows users to add images to their recipes, which are then saved into the data/images
folder created by CookBuddy (at least, using the default settings). This section elaborates on implementation.
The two key classes allowing image and photo management are ImageUtil
and Photograph
; the former is a utility class written in the singleton pattern; the latter is the attribute that each Recipe
directly contains, as Figure 7, “Structure of the attribute
package, defining each Recipe
's key attributes” details.
6.2.1. From User Command to Image On Screen
The above sequence diagram details how a user-entered command is translated to an image file as displayed on screen. Some initial details are omitted, such as the calls to RecipeBookParser#parseCommand()
(which have already been demonstrated in Section 5.4, “Model component”).
The steps taken are also described step-by-step in the activity diagram below:
6.2.2. Saving Images Into the Data Folder
When saving images, there were a few considerations that needed to be taken into account:
-
The image on disk must contain the recipe name, so as to be reasonably understandable;
-
The image on disk must be stored losslessly, so that repeated read-write cycles do not deplete the quality;
-
If an image already exists on disk, then read/write cycles must not be wasted in overwriting an image with the same data;
-
Even if recipes have the same name, the image file names must be distinct, and yet always resolve to the same.
Therefore, a hashcode is appended to each image file name, and the resulting data is saved to disk as a .png
image, which is lossless. jpeg
formats would require lossy compression at each save, which would progressively degrade image quality.
This entire process is also demonstrated in the activity diagram below:
6.2.3. Design Considerations
ImageUtil
is implemented as a singleton class. In other words, its constructor is declared private
, and the object can only be retrieved by the public static
factory method, ImageUtil.imageUtil()
. Given the class defines several constants using methods, we believed this was the most straightforward direction possible.
ImageUtil
also declares PLACEHOLDER_IMAGE
as several static constant types: a BufferedImage
, an InputStream
, and even as a Path
. The actual image is bundled with the JAR
file, which can be explored at will using an extractor tool like 7zip
.
These constants are loaded when the Photograph class is first called, thus adhering to Java’s Just-In-Time (JIT) principle.
Furthermore, the initial ImageUtil
written as an ordinary static utility class led to the JVM throwing ExceptionInInitializerError
when the built .jar
was run. There were no issues running this from the IDE; hence the singleton pattern.
6.2.4. Possible Improvements
As it is, image processing spans several classes: FileUtil
, ImageUtil
, Photograph
. We would like to simplify this. Furthermore, saving image data requires returning a file path through several methods, which have little relation to one another.
6.3. Finding recipes [Done by Kevin]
The following section describes how the find
command is implemented as well as design considerations that were taken into account during its implementation.
Some possible future improvements are also suggested to improve the functionality of the find
command.
The find
command is implemented in the FindCommand class.
The following activity diagram shows the possible paths CookBuddy can take when a find
command is run.
6.3.1. Implementation
-
When entering the
find
command, the user will specify one attribute to search within as well as the search terms.
Possible attributes to search within are name (n/
), ingredients (ing/
) and instructions (ins/
). -
FindCommandParser ensures that only one attribute is specified and returns a FindCommand with the relevant ContainsKeywordPredicate class.
The following sequence diagram summarizes the execution of the find
command
find
command6.3.2. Design Considerations
As the FindCommand class only takes in a single ContainsKeywordsPredicate object, CookBuddy can only search within a single attribute at a time.
6.3.3. Possible improvements
As it is currently implemented, the find
command only accepts finding via one attribute at a time.
A possible future improvement would enable it to search for recipes using multiple attributes.
This would greatly enhance the usefulness of the find
function in CookBuddy.
For example, running find n/Ham ing/toast
will make CookBuddy search for recipes with Ham in its name, or toast in its ingredients.
6.4. Favouriting recipes [Adarsh]
The following section describes how the fav
command is implemented as well as design considerations that were taken into account during its implementation.
Some possible future improvements are also suggested to improve the functionality of the fav
command.
The fav
command is implemented in the FavCommand class.
The following activity diagram shows the possible paths CookBuddy can take when a fav
command is run.
fav
command6.4.1. Implementation
-
When entering the
fav
command, the user will specify the index of the recipe to be favourited. -
FavCommandParser ensures that index specified is valid and returns a FavCommand.
The following sequence diagram summarizes the execution of the fav
command
fav
command6.4.2. Design Considerations
Aspect: How many indexes should be taken in?
-
Alternative 1 (Chosen): Only 1 index to be specified per use of the command
-
Pros: Less error-prone
-
Cons: Less efficient
-
-
Alternative 2: Multiple indexes can be specified per use of the command
-
Pros: More efficient
-
Cons: More error prone
-
6.4.3. Possible improvements
In the current implementation, you are able to favourite recipes, even if they have already been favourited.
A possible improvement would be to notify users if the recipe they are trying to favourite has already been favourited.
This would greatly enhance the usefulness of the fav
function in CookBuddy.
6.5. Un-favouriting recipes [Adarsh]
The following section describes how the unfav
command is implemented as well as design considerations that were taken into account during its implementation.
Some possible future improvements are also suggested to improve the functionality of the unfav
command.
The unfav
command is implemented in the UnFavCommand class.
The following activity diagram shows the possible paths CookBuddy can take when a unfav
command is run.
unfav
command6.5.1. Implementation
-
When entering the
unfav
command, the user will specify the index of the recipe to be un-favourited. -
UnFavCommandParser ensures that index specified is valid and returns a UnFavCommand.
The following sequence diagram summarizes the execution of the unfav
command
unfav
command6.5.2. Design Considerations
Aspect: How many indexes should be taken in?
-
Alternative 1 (Chosen): Only 1 index to be specified per use of the command
-
Pros: Less error-prone
-
Cons: Less efficient
-
-
Alternative 2: Multiple indexes can be specified per use of the command
-
Pros: More efficient
-
Cons: More error prone
-
6.5.3. Possible improvements
In the current implementation, you are able to un-favourite recipes, even if they are not favourited.
A possible improvement would be to notify users if the recipe they are trying to favourite has not been favourited.
This would greatly enhance the usefulness of the find
function in CookBuddy.
6.6. Marking recipes as done [Adarsh]
The following section describes how the done
command is implemented as well as design considerations that were taken into account during its implementation.
Some possible future improvements are also suggested to improve the functionality of the done
command.
The done
command is implemented in the DoneCommand class.
The following activity diagram shows the possible paths CookBuddy can take when a done
command is run.
done
command6.6.1. Implementation
-
When entering the
done
command, the user will specify the index of the recipe to be mared as done. -
DoneCommandParser ensures that index specified is valid and returns a DoneCommand.
The following sequence diagram summarizes the execution of the done
command
done
command6.6.2. Design Considerations
Aspect: How many indexes should be taken in?
-
Alternative 1 (Chosen): Only 1 index to be specified per use of the command
-
Pros: Less error-prone
-
Cons: Less efficient
-
-
Alternative 2: Multiple indexes can be specified per use of the command
-
Pros: More efficient
-
Cons: More error prone
-
6.6.3. Possible improvements
In the current implementation, you are able to mark recipes as done, even if they are already marked as done.
A possible improvement would be to notify users if the recipe they are trying to favourite has already been marked as done.
This would greatly enhance the usefulness of the done
function in CookBuddy.
6.7. Un-marking recipes as done [Adarsh]
The following section describes how the undo
command is implemented as well as design considerations that were taken into account during its implementation.
Some possible future improvements are also suggested to improve the functionality of the undo
command.
The undo
command is implemented in the UndoCommand class.
The following activity diagram shows the possible paths CookBuddy can take when a undo
command is run.
undo
command6.7.1. Implementation
-
When entering the
undo
command, the user will specify the index of the recipe to be un-favourited. -
UndoCommandParser ensures that index specified is valid and returns a UndoCommand.
The following sequence diagram summarizes the execution of the undo
command
undo
command6.7.2. Design Considerations
Aspect: How many indexes should be taken in?
-
Alternative 1 (Chosen): Only 1 index to be specified per use of the command
-
Pros: Less error-prone
-
Cons: Less efficient
-
-
Alternative 2: Multiple indexes can be specified per use of the command
-
Pros: More efficient
-
Cons: More error prone
-
6.7.3. Possible improvements
In the current implementation, you are able to mark recipes as not attempted, even if they have not been marked as attempted.
A possible improvement would be to notify users if the recipe they are trying to unmark as done has not been attempted.
This would greatly enhance the usefulness of the undo
function in CookBuddy.
6.8. Viewing recipes [Adarsh]
The following section describes how the view
command is implemented as well as design considerations that were taken into account during its implementation.
Some possible future improvements are also suggested to improve the functionality of the view
command.
The view
command is implemented in the ViewCommand class.
The following activity diagram shows the possible paths CookBuddy can take when a view
command is run.
view
command6.8.1. Implementation
-
When entering the
view
command, the user will specify the index of the recipe that they wish to view. -
ViewCommandParser ensures that index specified is valid and returns a ViewCommand.
The following sequence diagram summarizes the execution of the view
command
view
command6.8.2. Design Considerations
Aspect: How should the user specify the recipe they want to view
-
Alternative 1 (Chosen): Using the index of the recipe
-
Pros: Easily identified from the GUI
-
Cons: -
-
-
Alternative 2: Using the name of the recipe
-
Pros: Users may know the name of the recipe better than the index
-
Cons: Less efficient
-
6.8.3. Possible improvements
In the current implementation, the view
command only takes in the index of the recipe.
A possible improvement would be to allow users to input the recipe name they want viewed.
That way, users can input either the recipe name or index.
6.9. Assigning a time to a recipe [Adarsh]
The following section describes how the time
command is implemented as well as design considerations that were taken into account during its implementation.
Some possible future improvements are also suggested to improve the functionality of the time
command.
The time
command is implemented in the TimeCommand class.
The following activity diagram shows the possible paths CookBuddy can take when a time
command is run.
time
command6.9.1. Implementation
-
When entering the
time
command, the user will input the index of the recipe they wish to assign a time, as well as the time they wish to assign to the recipe. The time is to be in the following format (hh:MM:ss). Minutes and seconds are optional, and would be set to 0 if no values are provided for them. -
TimeCommandParser ensures that index specified is valid and returns a TimeCommand.
The following sequence diagram summarizes the execution of the time
command
time
command6.9.2. Design Considerations
Aspect: Should the minutes and seconds be mandatory inputs
-
Alternative 1 (Chosen): No, they can be optional inputs
-
Pros: More efficient
-
Cons: -
-
-
Alternative 2: Yes, they should be mandatory inputs
-
Pros: -
-
Cons: Much less efficient
-
6.9.3. Possible improvements
In the current implementation, we are parsing the hours, minutes and seconds as integers. A possible improvement would be to use the java.util.time class.
6.10. 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 6.11, “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
6.11. Configuration
Certain properties of the application may be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json
).
6.12. Features coming in v2.0
We have some exciting features in line for v2.0
, and some of these include:
-
Converting between units: American users of our application might be more comfortable with pounds, quarts, gallons and such. Therefore, we aim to implement a seamless conversion between US customary and metric units, with a one-command (or click) way to switch between the two.
-
We also note that users may prefer some advanced UNIX-style compressed syntax; hence, we are exploring using the PicoCLI library to implement both the current Windows-style slash-based syntax, as well as UNIX-style dash-based syntax. This is a single class that can either be imported as a dependency, or directly included as source.
We expect that this change would also drastically decrease code length and improve stability and testability, given the current implementation spans not just several classes, but two entire packages:
cookbuddy.logic.parser
, andcookbuddy.logic.command
. As it is now, we have needless object-orientation for the sake of doing so, and we believe in simplicity as much as possible. -
We understand users who cook love to share their creations with friends and family; therefore, we intend to use social media APIs from Facebook, Google, Twitter, Reddit, Instagram, and Snapchat, to allow users to share their recipes to the world.
-
Users might not be comfortable with keeping their computers near the stove, hence, we plan to offer two solutions in
v2.0
:-
We plan to release mobile apps for the two major platforms, Android and iOS.
-
For users more comfortable with paper, we plan to allow printing of recipes to PDF, and directly to printers. This engine is intended to be powered by
LaTeX
.
-
7. Documentation
Refer to the guide here.
8. Testing
Refer to the guide here.
9. Dev Ops
Refer to the guide here.
Appendix A: Product Scope [Done by Zain Alam & Sharadh Rajaraman]
Target user profile: [Done by Sharadh Rajaraman]
-
cooks for oneself on a nearly daily basis, and hence:
-
needs to manage many recipes
-
needs to have a clean interface to view and read recipes
-
experiments with dishes
-
-
prefers desktop apps over other types
-
can type fast
-
prefers typing over mouse input
-
is reasonably familiar with the command-line
-
requires a straightforward means to catalogue and codify dishes and meals without using spreadsheets
Value proposition: [Done by Zain Alam]
-
Store, retrieve, manage and display recipes faster than navigating through websites and bookmarks, with command-line input, but GUI responses.
-
Present a unified interface for recipe management.
-
When managing recipes:
-
allow easier and faster retrieval with attributes like tags, time, difficulty, etc;
-
present a straightforward interface to edit, duplicate and combine recipes into meals
-
-
Overall increase in productivity.
Appendix B: User Stories [Done by Sharadh Rajaraman and Adarsh Chugani]
Priorities: High (must have), Medium (nice to have), Low (unlikely to have)
Priority | As a/an … | I want to … | So that… |
---|---|---|---|
High |
Regular user |
add a recipe |
I can keep track of the recipe |
High |
Regular user |
delete a recipe |
I can stop keeping track of the recipe |
High |
Regular user |
list out all the recipes I have |
I can easily see what recipies I have |
High |
Regular user |
view the recipe |
I can use the recipe |
High |
More experienced user |
duplicate a recipe |
I can modify a copy and keep the original |
High |
User who is inexperienced with software |
use a helper command |
I can see all the commands and how to use them |
High |
Regular user |
add instructions for the recipe |
I know how to cook the dish |
High |
Regular user |
add ingredient to recipe |
I know how much ingredients to use |
High |
Health-focused user |
track the amount of calories a dish has |
I know how healthy a dish is |
High |
Regular user |
add time it takes to prepare / cook recipe |
I know how long it takes to cook the recipe |
High |
Organized user |
tag recipes based on meal time (breakfast/lunch/dinner) |
I can easily refer to them |
High |
User who likes experimenting |
modify a recipe |
I can change the components of the recipe |
High |
Regular user |
add a serving size of a dish |
I know the serving size of the recipe |
High |
Time-strapped user |
see the preparation and cooking time for each recipe |
I can plan my schedule around the time needed |
High |
Health-focused user |
search for a dish based on how many calories i want to consume |
I can eat healthily |
High |
User who is new to cooking |
tag recipes based on difficulty (beginner/intermediate/master) |
I can check if I am skilled enough to cook the dish |
High |
User with many recipes |
tag recipes based on their cuisine (western, chinese, indian etc) |
I can find them easily |
Medium |
User who wants to be efficient |
favourite recipes/dishes |
I can easily refer back to them |
Medium |
User who wants to get rid of ingredients |
search for dishes based on ingredients |
I can use up the ingredients that I want to get rid of |
Medium |
User with many recipes |
search for recipes based on a word in the dish name |
I can find it easily |
Medium |
Organized user |
mark recipe as successfully done |
I can keep track of the recipes I have successfully attempted |
Medium |
Inexperienced user |
view the recipe in a GUI |
I have more visual feedback to work with |
Medium |
Inexperienced user |
view an image of the final dish |
I know what dish I am cooking |
Medium |
Organized user |
have a counter of total recipes in the book |
I can know how many recipes I have |
Medium |
User who likes experimenting |
give me a random recipe that i have added |
I can challenge myself to cook what has been given |
Medium |
Regular user |
give a rating for the dish |
I can tag, search for and sort dishes based on my rating of the dish |
Medium |
User with a limited budget |
find recipes within my budget |
I do not overspend |
Medium |
User with allergies |
tag the dish as dangerous for allergies |
I can avoid cooking the dish |
Medium |
User who not experienced |
highlight instructions in the recipe |
I can follow the recipe more easily |
Medium |
Organized user |
sort my recipes based on criteria (tags) |
I can choose what order to view them |
Medium |
Regular user |
add ingredient prices |
I can tabulate the total cost of cooking dishes |
Low |
User with a limited budget |
view the price of a specific ingredient |
I know how much a ingredient costs |
Low |
User with many friends |
import and combine my friend’s recipes from a file (.txt perhaps) |
I can have access to their recipies |
Low |
User who enjoys challenging themselves |
suggest dish to attempt based on my previous successful attempts |
I can become more skillful |
Low |
Regular user |
choose to only see the basic information for the recipe |
I can easily skim through the instructions and ingredients |
Low |
User on a budget |
check the total price of the dish |
I can check if it is within my budget |
Low |
User cooking for a group / occasion |
scale up/down the recipe |
I can prepare food for different group sizes |
Low |
User cooking for a group / occasion |
find out how much of each ingredient i need |
I can get the ingredients at one go |
Low |
Health-focused user |
add nutrition facts |
I can see how much sugar, salt, fat etc is in the dish prepared |
Low |
User who is more familiar with the metric system |
Convert between metric and imperial sizes. |
I can use the tools I have without needing to convert elsewhere |
Low |
User who usually prepares multiple dishes as sets |
group dishes into sets |
I can be more organised when cooking |
Low |
User who is experienced with the software |
use shorthand commands |
I can navigate the software more efficiently |
Low |
User who wants to challenge myself |
have a timer/stopwatch |
I can time myself when I cook dishes and have a "best time" feature |
Low |
User who doesn’t like screens and prefers paper |
print recipes as pdf/paper |
I can refer to it more easily |
Low |
User who likes sharing my cooking |
post my recipes and dishes on social media |
I can share recipes and images for others to use |
Low |
User who appreciates efficiency |
add a recipe directly from online |
I can be efficient |
Appendix C: Use Cases [Done by Sharadh Rajaraman]
(For all use cases below, the System is CookBuddy
and the Actor is the User
, unless specified otherwise)
Use case: List recipes
MSS
-
User
requests to list recipes -
CookBuddy
displays the list of recipesUse case ends.
Extensions
-
1a. The name cannot be found, or the index is invalid.
-
1a1.
CookBuddy
throws an error message.Use case resumes at step 1.
-
-
2a. The list is empty.
-
2a1.
CookBuddy
displays a message stating the list is emptyUse case ends.
-
Use case: Delete recipe
MSS
-
User
requests to delete a specific recipe by specifying its index -
CookBuddy deletes the recipe
Use case ends.
Extensions
-
1a. The name cannot be found, or the index is invalid.
-
1a1.
CookBuddy
throws an error message.Use case ends.
-
Use case: Modify recipe
MSS
-
User
requests to modify a recipe -
CookBuddy
edits attributes of the recipe, and asks for user confirmation -
User
confirms the editUse case ends.
Extensions
-
1a.
User
does not provide new attributes.-
CookBuddy
throws an error message.Use case resumes at step 1.
-
-
2a.
User
does not confirm.-
2a1.
CookBuddy
does not save the editUse case ends.
-
Appendix D: Non Functional Requirements [Done by Zain Alam]
-
Should work on any mainstream OS as long as it has Java
11
or above installed. -
Should be able to hold up to 1000 recipes without noticeable sluggishness in performance for typical usage.
-
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.
-
Commands should be one-shot commands as opposed to multi-level commands.
-
CookBuddy should be able to function without internet access.
-
A user should be able to familiarise herself with less than 30 minutes of usage.
Appendix E: Glossary [Done by Zain Alam]
- Attributes
-
The information of a recipe. For example, calories, ingredients or instructions etc.
- Mainstream OS
-
Windows, macOS, Linux, UNIX
- Multi-level Commands
-
Commands that require multiple lines of user input for execution.
- One-shot Commands
-
Commands that are executed using only a single line of user input.
- Recipe
-
A list of ingredients followed by a list of instructions, detailing how to prepare a dish.
- Tag
-
A (possibly custom) text marker that users can use to organise their recipes; examples include
vegetarian
,spicy
,Indian
. Tags can themselves be organised into groups, such ascuisines
,diet
,ingredients
,mealtime
, etc.
Appendix F: Product Survey [Done by Zain Alam]
CookBuddy
Author: Zain Alam
Pros:
-
Functionality
-
Ease of recipe management
-
Tracks calories, rating and diffculty
-
-
Non-funtional requirements
-
Well-designed GUI
-
Cross platform
-
Cons:
-
Functionality
-
Unable to find a recipe with more than one parameters at a time
-
Unable to pin recipes when working with multiple meals
-
Unable to translate a recipe from one language to another language
-
-
Non-functional requirements
-
slightly GUI-dependent, some buttons need to be clicked and screens traversed to perform a task
-
Appendix G: Instructions for Manual Testing [Done by Kevin]
Given below are instructions to test the app manually.
These instructions only provide a starting point for testers to work on; testers are advised to do more exploratory testing. |
G.1. Launch and Shutdown
-
Launching CookBuddy
-
Ensure you are using Java 11 by opening a Command Prompt / terminal and run
java -version
. -
Download the latest CookBuddy jar file here and copy it into an empty folder
-
Launch Command Prompt / a terminal, navigate to the folder CookBuddy is in and enter
java -jar CookBuddy.jar
. Do not double-click CookBuddy.jar
Expected: Shows CookBuddy’s GUI with a set of sample recipes. The window size may not be optimum.
-
-
Saving window preferences
-
Resize CookBuddy’s window to an optimum size. Move the window to a different location on the screen. Close the window.
-
Re-launch CookBuddy by entering
java -jar CookBuddy.jar
in a Command Prompt / terminal.
Expected: The most recent window size and location is retained.
-
-
Exiting CookBuddy
-
On Windows, click the Close Window button X on the top-right corner of CookBuddy’s GUI
-
On Mac, click the Close Window button X on the top-left corner of CookBuddy’s GUI
-
Type
exit
in CookBuddy’s command box and press EnterExpected: CookBuddy will shut down.
-
G.2. Adding a recipe
-
Add a recipe with all mandatory fields present. Name (n/), Ingredients (ing/) and Instructions (ins/) are mandatory fields.
-
Prerequisites: The recipe to be added is not present in the recipe book.
-
Test case:
new n/Eggs on Toast ing/bread, 2 slices; egg, 1 ins/toast the 2 slices of bread; scramble the eggs; put eggs on toasted bread; serve
Expected: The Eggs on Toast recipe is added to the recipe list. Details of the newly added recipe is shown in the result pane.
-
-
Add a recipe with one mandatory field missing, Instructions in this case.
-
Test case:
new n/Eggs on Toast ing/bread, 2 slices; egg, 1
Expected: No recipe is added. An "Invalid command format" error message is shown in the result pane.
-
-
Add a recipe with a missing ingredient quantity (egg is missing its quantity)
-
Test Case:
new n/Eggs on Toast ing/bread, 2 slices; egg ins/toast the 2 slices of bread; scramble the eggs; put eggs on toasted bread; serve
Expected: No recipe is added. Error message No quantity has been provided for one or more ingredients! is shown in the result pane.
-
G.3. Modifying a recipe
CookBuddy should contain at least one recipe. If no recipe exists, delete the data folder and re-launch CookBuddy. The recipe book should contain two recipes, Ham Sandwich & Idiot Sandwich. |
The Modify command allows changing multiple attributes in one command.
For example, modify 1 n/Rice cal/250 updates both recipe 1’s name and calories.
|
-
Modifying a recipe’s name
-
Test Case:
modify 1 n/Chicken Rice
Expected: The first recipe’s name is updated to Chicken Rice. -
Test Case:
modify 1 n/
Expected: The first recipe’s name is not updated. Error details are shown in in result pane. -
Test Case:
modify 1 n/!@#abc
Expected: The first recipe’s name is not updated. Error details are shown in in result pane.
-
-
Modifying a recipe’s ingredients
-
Test Case:
modify 1 ing/ing1, qty1; ing2, qty2
Expected: The first recipe’s original ingredients should be overwritten with ing1 & ing2. -
Test Case:
modify 1 ing/ing1, ; ing2, qty2
Expected: The first recipe’s ingredients are not updated due to ing1 missing its quantity. -
Test Case:
modify 1 ing/, qty1; ing2, qty2
Expected: The first recipe’s ingredients are not updated due to ing1 missing its name.
-
-
Modifying a recipe’s instructions
-
Test Case:
modify 1 ins/ins1; ins2
Expected: The first recipe’s original instructions should be overwritten with ins1 & ins2. -
Test Case:
modify 1 ins/
Expected: The first recipe’s instructions should not be updated. Error details are shown in in result pane.
-
-
Modifying a recipe’s calories
-
Test Case:
modify 1 cal/2000
Expected: The first recipe’s calories should be updated to 2000 kCal. -
Test Case:
modify 1 cal/abc
Expected: The first recipe’s calories is not updated. Error details are shown in in result pane.
-
-
Modifying a recipe’s serving size
-
Test Case:
modify 1 s/3
Expected: The first recipe’s serving size should be updated to 3. -
Test Case:
modify 1 s/abc
Expected: The first recipe’s serving size is not updated. Error details are shown in in result pane.
-
-
Modifying a recipe’s difficulty
-
Test Case:
modify 1 d/4
Expected: The first recipe’s difficulty should be updated to 4 on a scale of 1 to 5. -
Test Case:
modify 1 d/6
Expected: The first recipe’s difficulty is not updated. Error details are shown in in result pane. -
Test Case:
modify 1 d/abc
Expected: The first recipe’s difficulty is not updated. Error details are shown in in result pane.
-
-
Modifying a recipe’s rating
-
Test Case:
modify 1 r/5
Expected: The first recipe’s rating should be updated to 5 stars. -
Test Case:
modify 1 r/8
Expected: The first recipe’s rating is not updated. Error details are shown in in result pane. -
Test Case:
modify 1 r/abc
Expected: The first recipe’s rating is not updated. Error details are shown in in result pane.
-
-
Modifying a recipe’s tags
-
Test Case:
modify 1 t/breakfast
Expected: The first recipe’s tags should be updated to contain one tag, breakfast. -
Test Case:
modify 1 t/breakfast, lunch
Expected: The first recipe’s tags should be updated to contain two tags, breakfast & lunch. -
Test Case:
modify 1 t/
Expected: The first recipe’s tags should be updated to contain zero tags.
-
G.4. Finding a recipe
-
Finding recipes by name
-
Prerequisite: CookBuddy contains a recipe with Ham in its name.
Test Case:find n/Ham
Expected: Recipes with the word Ham in their name are listed. -
Prerequisite: CookBuddy contains Ham Sandwich and Idiot Sandwich.
Test Case:find n/Ham Sandwich
Expected: Recipes whose name contains Ham or Sandwich are listed. So both Ham Sandwich and Idiot Sandwich are listed.
-
-
Finding recipes by ingredient
-
Prerequisite: CookBuddy contains a recipe with bread in its ingredients.
Test Case:find ing/bread
Expected: Recipes whose ingredient names contain bread are listed.
-
-
Finding recipes by instruction
-
Prerequisite: CookBuddy contains a recipe with ham in its instructions.
Test Case:find ins/bread
Expected: Recipes whose instructions contain ham are listed.
-
G.5. Marking a recipe as done / not done
CookBuddy should contain at least one recipe.
If no recipe exists, delete the data folder and re-launch CookBuddy.
The recipe book should contain two recipes, Ham Sandwich & Idiot Sandwich.
|
-
Marking a recipe as done
-
Test Case:
done 1
Expected: The first recipe should be marked as done. -
Test Case:
done n
(where n is larger than the list size)
Expected: An error message is shown in the result pane prompting the user to enter a valid list index number. -
Test Case:
done abc
Expected: An error message is shown in the result pane prompting the user to enter a valid integer.
-
-
Marking a recipe as not done
-
Test Case:
undo 1
Expected: The first recipe should be marked as not done. -
Test Case:
undo n
(where n is larger than the list size)
Expected: An error message is shown in the result pane prompting the user to enter a valid list index number. -
Test Case:
undo abc
Expected: An error message is shown in the result pane prompting the user to enter a valid integer.
-
G.6. Marking a recipe as a favourite / not a favourite
CookBuddy should contain at least one recipe.
If no recipe exists, delete the data folder and re-launch CookBuddy.
The recipe book should contain two recipes, Ham Sandwich & Idiot Sandwich.
|
-
Marking a recipe as a favourite
-
Test Case:
fav 1
Expected: The first recipe should be marked as favourite, indicated by the filled heart symbol. -
Test Case:
fav n
(where n is larger than the list size)
Expected: An error message is shown in the result pane prompting the user to enter a valid list index number. -
Test Case:
fav abc
Expected: An error message is shown in the result pane prompting the user to enter a valid integer.
-
-
Un-marking a recipe as a favourite
-
Test Case:
unfav 1
Expected: The first recipe should be un-marked as favourite, indicated by the un-filled heart symbol. -
Test Case:
unfav n
(where n is larger than the list size)
Expected: An error message is shown in the result pane prompting the user to enter a valid list index number. -
Test Case:
unfav abc
Expected: An error message is shown in the result pane prompting the user to enter a valid integer.
-
G.7. Adding a prep time to a recipe
CookBuddy should contain at least one recipe.
If no recipe exists, delete the data folder and re-launch CookBuddy.
The recipe book should contain two recipes, Ham Sandwich & Idiot Sandwich.
|
-
Adding a prep time
-
Test Case:
time 1 00:15
Expected: The first recipe’s prep time should be updated to 15 minutes. -
Test Case:
time 1 00:15:30
Expected: The first recipe’s prep time should be updated to 15 minutes and 30 seconds. -
Test Case:
time 1 00:63
Expected: An error message is shown in the result pane prompting the user to enter a minutes value which is < 60. -
Test Case:
time 1 00:15:65
Expected: Expected: An error message is shown in the result pane prompting the user to enter a seconds value which is < 60.
-
G.8. Deleting a recipe
-
Deleting a recipe while all recipes are listed
-
Prerequisites: List all recipes using the
list
command. Have at least one recipe in the list. -
Test case:
delete 1
Expected: The first recipe is deleted from the list. Details of the deleted recipe is shown in the result pane. -
Test case:
delete 0
Expected: No recipe is deleted. Error message "The recipe index provided is invalid" is shown in the result pane. -
Test case:
delete n
(where n is larger than the list size)
Expected: Similar to previous. -
Test case:
delete
Expected: No recipe is deleted. An error message prompting the user to provide an index is shown in the result pane. -
Test case:
delete abc
Expected: No recipe is deleted. An error message prompting the user to provide a valid integer is shown in the result pane.
-
G.9. Saving data
-
Saving CookBuddy’s recipe book to the save file.
-
Enter any valid command that modifies data in the recipe book.
-
A file named recipebook.json should be created in the data/ folder.
-
-
Dealing with missing/corrupted data in CookBuddy’s save file
-
Edit recipebook.json and delete any recipe’s difficulty parameter and re-launch CookBuddy.
-
The recipe whose difficulty was deleted will have defaulted back to 0 difficulty.
-