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
interfacewith the same name as the Component. -
Exposes its functionality using a
{Component Name}Managerclass.
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
Logiccomponent. -
Listens for changes to
Modeldata 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
-
Logicuses theRecipeBookParserclass to parse the user command. -
This results in a
Commandobject 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
CommandResultobject which is passed back to theUi. -
In addition, the
CommandResultobject can also instruct theUito 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
UserPrefobject 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
UserPrefobjects to and from disk, as.jsonformat; -
serialises, reads and writes recipe data to and from disk, also as
.jsonformat; -
passes on the file path for the user-entered image into methods in the
ImageUtilclass. 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
findcommand, 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
favcommand, 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
unfavcommand, 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
donecommand, 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
undocommand, 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
viewcommand, 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
timecommand, 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
logLevelsetting in the configuration file (See Section 6.11, “Configuration”) -
The
Loggerfor a class can be obtained usingLogsCenter.getLogger(Class)which will log messages according to the specified logging level -
Currently log messages are output through:
Consoleand to a.logfile.
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
-
Userrequests to list recipes -
CookBuddydisplays the list of recipesUse case ends.
Extensions
-
1a. The name cannot be found, or the index is invalid.
-
1a1.
CookBuddythrows an error message.Use case resumes at step 1.
-
-
2a. The list is empty.
-
2a1.
CookBuddydisplays a message stating the list is emptyUse case ends.
-
Use case: Delete recipe
MSS
-
Userrequests 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.
CookBuddythrows an error message.Use case ends.
-
Use case: Modify recipe
MSS
-
Userrequests to modify a recipe -
CookBuddyedits attributes of the recipe, and asks for user confirmation -
Userconfirms the editUse case ends.
Extensions
-
1a.
Userdoes not provide new attributes.-
CookBuddythrows an error message.Use case resumes at step 1.
-
-
2a.
Userdoes not confirm.-
2a1.
CookBuddydoes 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
11or 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.jarin 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
exitin 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
listcommand. 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.
-