Developer Guide for NUSMaze
Table Of Contents
-
Introduction
1.1. Overview
1.2. Setting up and getting started -
Design
2.1. Architecture
2.2. UIManager Component
2.3. Parser Component
2.4. Command Component
2.5. Router Component
2.6. Data Component
2.7. Storage Component -
Implementation
3.1. Finding The Shortest Route Feature
3.1.1. Current implementation
3.1.2. Routing
3.2. Daily Route Planning Feature
3.2.1. Current implementation
3.2.2. Adding daily route
3.2.3. Showing daily route
3.2.4. Deleting daily route
3.3. Favourite Routes Feature
3.3.1. Current implementation
3.3.2. Loading of saved favourite routes
3.3.3. Adding of favourite routes
3.3.4. Reviewing saved favourite routes
3.3.5. Repeating favourite route
3.3.6. Deleting favourite route
3.4. Custom Aliases Feature
3.4.1. Current implementation
3.4.2. Adding of custom aliases
3.4.3. Showing custom aliases
3.4.4. Deleting a custom alias
3.4.5. Example for alias feature
3.4.6. Design consideration
3.5. History Feature
3.5.1. Current implementation
3.5.2. Loading of saved history
3.5.3. Showing past searches
3.5.4. Repeat past searches
3.5.5. Clear past searches
3.5.6. Design consideration
3.6. Save Feature
3.6.1. Current implementation
3.6.2. Saving/Loading Data
3.6.3. Design consideration -
Appendix: Requirements
4.1. Product Scope
4.2. User Stories
4.3. Use Cases
4.4. Non-functional Requirements
4.5. Glossary -
Appendix: Instructions for manual testing
5.1. Launch and shutdown
5.2. Viewing help
5.3. Viewing venues in NUSMaze
5.4. Routing
5.5. History
5.6. Alias
5.7. Daily Route
5.8. Favourites
5.9. Notes
1. Introduction
1.1. Overview
NUSMaze is a Command Line Interface (CLI) based application that aims to simplify NUS Engineering students’ journey from one point to another within the Engineering and Computing faculties of NUS. The application allows users to find the best route from one block to another, add favourite locations, locate the nearest eatery and much more.
The purpose of this developer guide is to aid any curious or interested contributor in developing NUSMaze further by providing more insight on how the features were implemented.
1.2. Setting up and getting started
- Ensure that Java 11 and IntelliJ Idea (or your preferred Java IDE) are installed in your computer.
- Fork the NUSMaze repo from here, and clone the fork into your computer.
- Configure the JDK in IntelliJ Idea to use JDK 11 by following instructions from here.
- Import the project as a Gradle project.
- If you had previously disabled the Gradle plugin, go to
File → Settings → Plugins
to re-enable them. - Click on Import Project and select the build.gradle file.
- Navigate to the NUSMaze class via the path
src → main → java → seedu.duke → NUSMaze
and right click on it. - Press run on the
Main()
method of NUSMaze.
If the set up process had been completed successfully, you should see the following message:
2. Design
2.1. Architecture
The Architecture Diagram above depicts the high-level design of the NUSMaze. You can always refer to this diagram
to understand how the different components of NUSMaze interact with each other.
The class NusMaze
is where the main()
method belongs and is responsible for:
- When the app launches, initialise and connect different components of the NUSMaze in correct sequence.
- When the app terminates, shut down all the components.
Architecture Components of NUSMaze:
-
UIManager
: The user interface of the app -
Parser
: Processes commands inputted by the user -
Command
: Executes the user command -
Router
: Searches the shortest route -
Data
: Holds the data of the app to be used -
Storage
: Reads app data from and writes the app data to created text files -
Text Files
: Holds the data of the app in memory
Explanations on how each component is designed and how it functions are further elaborated in the following
chapters of the developer guide.
2.2. UIManager Component
The UI of the application is managed by the UiManager
class as shown by the class diagram above. The individual UI classes for each feature such as AliasUi
, DailyRouteUi
and
FavouriteUi
extend the UiManager
class. The UiManager class consists of the methods that are used to display recurrent messages on the CLI and also the utilities to get the user’s inputs.
The UiManager
requires the static string variables from the CommonMessages
class to obtain the commonly used messages that
such as the divider and input headers.
The individual UI classes contain the methods that are used to get user inputs specific to the needs of the specific feature that
it is responsible for. For example, when the routing feature is to be executed, the UI will need to prompt the user to obtain 2
inputs, namely the from block
and the to block
. Hence, the RouterUi
contains the getRoutingInfo()
method which will prompt
the user for these two inputs using the utility methods from the UiManager. Methods to get user input are called upon directly from the command classes of the specific feature command.
The UiManager
Component:
- displays messages in the CLI.
- provides the Ui classes of the respective features with the utilities to obtain user input specific to their needs.
2.3. Parser Component
As shown above in the class diagram, Parser component is made out of the Parser
class.
After the UiManager
reads in the user command, NusMaze
makes use of the Parser
to interpret
the user command and it will instantiate a new Command object to execute the command.
The Sequence diagram shown below is of a scenario where the user inputs an invalid input
. It will allow you to
get a better understanding of how the Parser
class interacts with NusMaze
and UiManager
.
2.4. Command Component
The class diagram above may seem complicated at first glance but it actually isn’t.
The Command Component of NUSMaze is made out of Command
class, which is the parent class of
all the other classes in the component (eg. GoCommand
, ByeCommand
). Depending on which command the user inputs, the
Parser
creates different Command
class to execute the task.
Each Command
class has:
- A distinct
execute()
method which is overrides the parent class, therefore tailored to execute the given command. - An
ui
specifically for taking in further user input in order to carry out the command.
2.5. Router Component
The Router Component consist of the Router
class which is responsible for finding the shortest route to get from
one location to another. In finding the shortest route, it utilises the breath-first-search algorithm, which will be
further elaborated in the implementation section.
As shown in the diagram above, Router
is used by the following classes:
GoCommand
RepeatHistoryCommand
RepeatFavouriteCommand
ShowDailyRouteCommand
2.6. Data Component
The Data Component is where all the data that are needed to execute a command is stored. For example when "go"
command is executed, the GoCommand
object will use data stored in NusMap
, EateryList
and BlockAlias
in order to find
the shortest route.
On the other hand, the Storage Component is responsible for saving from and loading data into stored in the Data Component. This will be
further elaborated in the following section.
2.7. Storage Component
The Storage Component reads app’s data from the objects of the Data Component and writes to the Text File component.
It reads the app’s data from the Text File component and writes the app’s data into the objects of the Data component.
The Storage Component:
- loads the app’s data from the relevant text file using the
filepath
into thenusMap
,blockAlias
,history
,favourite
, ordailyRoute
objects. - saves the app’s data from
nusMap
,blockAlias
,history
,favourite
, ordailyRoute
objects into the relevant text file using thefilepath
.
3. Implementation
3.1. Finding The Shortest Route Feature
3.1.1. Current Implementation
The current implementation of finding the shortest route is facilitated by the Router
class which uses data stored in NusMap
, Block
, and BlockAlias
class to return the shortest path.
The GoCommand
class extends the Command
class and overrides the execute
method to run the routing algorithm.
The image below depicts how the GoCommand
is implemented.
3.1.2. Routing
Given below is an example scenario of how the routing algorithm functions.
- User executes
GoCommand
and theRouterUi
reads in the starting location and destination.
- The input is changed to the name of the block if applicable.
- The blocks are then checked to see if they are valid blocks.
-
GoCommand
will then check if the second entry is eatery. If it is not “EATERY”, step 3 and 4 are skipped for step 5.
-
GoCommand
will then create an instance ofEateryList
and invokes its methodsortEateriesByDistance()
which returns a list of eateries in order of the closest distance.
-
GoCommand
then takes in the selection of eatery that the user is chosen and sets the destination.
- The Router will then run the
findShortestRoute()
method which is a routing algorithm based on breath-first search. This returns the shortest route as a string
- The
RouterUi
will then show the shortest route to the user throughshowMessageWithDivider()
method.
Shown below is the sequence diagram when a valid block is entered for the starting location and destination.
3.2. Daily route planning feature
3.2.1. Current Implementation
The current implementation is facilitated by DailyRoute
class, with the AddDailyRouteCommand
, ShowDailyRouteCommand
and DeleteDailyRouteCommand
subclasses invoking methods that the DailyRoute
class provides.
AddDailyRouteCommand
, ClearDailyRouteCommand
and DeleteDailyRouteCommand
extend Command
(superclass).
AddDailyRouteCommand
implements the feature of adding the schedule of the day to the DailyRoute
object. ShowDailyRouteCommand
accesses the DailyRoute
object to retrieve an ArrayList with the location schedule provided from the AddDailyRouteCommand
and run the routing algorithm present in the Router
object. DeleteDailyRouteCommand
clears the schedule mapped to the selected day.
Additionally, DailyRoute
implements the following operations:
addDailyRoute(String ,ArrayList<String>)
— Maps the inputted day string to the inputted ArrayList of the schedule of the day in a hashmap .
getDailyRoute(String)
— Returns the schedule of the day that is mapped to the inputted day.
getSelectableDays()
— Returns the current days that have schedules mapped to them.
getValidDays()
— Returns the days of the week.
These operations are exposed in the DailyRoute
class as DailyRoute#addDailyRoute()
, DailyRoute#getDailyRoute(String)
, DailyRoute#getSelectableDay()
, DailyRoute#getValidDay()
.
3.2.2. Adding daily route
Given below is an example usage scenario and how the addDailyRoute mechanism behaves at each step.
- The user launches the application.
- The user executes
add daily route
command. UI will then prompt the userSelect entry to add:
to input a day index.
- The UI then prompts the user to input the next block that is in the day’s schedule.
The inputted location will be appended to an ArrayList.
- Repeat step 3 until the word
END
is input by the user.
- The inputted day, and the filled Arraylist from step 3 is then passed into the DailyRoute object
This done using the addDailyRoute method from the DailyRoute class. The selectableDay boolean flag for the selected day is also set to true.
- The day and filled Arraylist passed in step 5 is then saved in a hashmap that the DailyRoute object contains.
The following image shows the sequence diagram in which the addDailyRoute command is executed.
3.2.3. Showing daily route
Given below is an example usage scenario and how the showDailyRoute mechanism behaves at each step.
- The user launches the application.
- The user executes
show daily route
command. UI will then prompt the userSelect entry:
to input a day index. This returns an arraylist of the day’s schedule.
- The routing algorithm is now performed for each of the blocks in the array list in order. Each execution of the routing algorithm returns a string which is then appended to the end of an Array list.
- The arraylist of the days schedule, and the arraylist that contains the routes from the routing algorithm are then output through Daily Route Ui
The following image shows the sequence diagram in which the showDailyRoute command is executed.
3.2.4. Deleting daily route
Given below is an example usage scenario and how the deleteDailyRoute mechanism behaves at each step.
- The user launches the application.
- The user executes
delete daily route
command. UI will then show the selectable days if applicable and prompt the userSelect entry:
to input a day index. If there are no days scheduled, the UI will print"There are no daily routes planned!"
- The
addDailyRoute(day, schedule)
method is then called with the selected day as day, and an empty array list as the schedule. The selectable day boolean flag for the day is set to false in the DailyRoute object, and the schedule mapped to the day is cleared.
- The String
"Got it! Successfully cleared [DAY]'s schedule!"
is output through Daily Route Ui
The following image shows the sequence diagram in which the deleteDailyRoute command is executed.
3.3. Favourite Routes feature
3.3.1. Current Implementation
The favourite routes feature acts as an independent storage of the user’s favourites routes,
allowing the user to call of the route without going through the hassle of the go
command.
The start and destination of the favourite routes are saved within an ArrayList named favourites
.
The contents of favourites
will be stored into a text file named favouritesList.txt
when NUSMaze terminates.
3.3.2. Loading of saved favourite routes
When NUSMaze launches, the contents of the text file favouritesList.txt
will be read,
and stored into favourites
.
Refer to the section on Storage for more information.
3.3.3. Adding of favourite route
The command to add a favourite route is add favourite
.
Upon calling the add favourite
command, the user will be prompted to enter the starting block,
followed by the destination block. If valid blocks are given,
the route from the starting block to destination block will be added into favourites
.
If any invalid block is given, InvalidBlockException
will be thrown.
3.3.4. Reviewing saved favourite routes
The command to display all the saved favourite routes is show favourite
.
If there are no saved routes, EmptyFavouriteException
will be thrown.
If there are any saved favourite routes, a numbered list of the saved routes will be shown to the user.
3.3.5. Repeating favourite route
The command to repeat a favourite route is repeat favourite
.
Upon calling the repeat favourite
command, the user would be shown a numbered list of saved favourite routes.
Otherwise, EmptyFavouriteException
will be thrown.
After the numbered list of saved favourite routes is shown, the user would be prompted to enter the index of the favourite
route to be executed. Any invalid input such as decimals or alphabets will result in
InvalidIndexException
to be thrown.
3.3.6. Deleting favourite route
The command to delete a favourite route is delete favourite
.
If there are no saved favourite routes, EmptyFavouriteException
will be thrown.
If there are any saved favourite routes, a numbered list of the saved routes will be shown to the user.
The user is then prompted to enter the index of the route to be deleted.
Any invalid input such as decimals or alphabets will result in
InvalidIndexException
to be thrown.
3.4. Custom aliases feature
3.4.1. Current Implementation
The following diagram illustrates the class diagram for implementation of the alias feature:
The command entered by the user in the Main()
function of NUSMaze will be parsed by the Parser
class. Thereafter, the parser will decide which of the 3 alias commands,
if applicable, was the command that the user wanted to execute.
The three command classes, namely AddCustomAliasCommand
, ShowCustomAliasCommand
and DeleteCustomAliasCommand
extend the Command
class, and they all depend on the AliasUi
class to obtain inputs and display outputs.
Another thing to note is that the NUSMaze
class has an AliasStorage
class that facilitates the storage of the aliases so that the user can access their aliases even after they close and reopen the application.
The data model for this feature is facilitated by the BlockAlias
class which contains the hashmap of custom aliases and block pairs.
The hashmap will have the custom alias name
as the key
and the block name
as the value
for each key-value pair. The
BlockAlias
class also depends on the NusMap
class to ensure that valid blocks are input by the user.
3.4.2. Adding of custom aliases
The user can enter add alias
invoke an instance of AddCustomAliasCommand
which will prompt them for the
alias and block names. If the alias name already exists, or the alias name conflicts
with a block name, the application will display an error message and the addition of the custom alias will not be executed. If there
were no errors, the alias and block pair would be added to the hashmap in the instance of the BlockAlias
class and it will also be
stored in the AliasStorage
.
3.4.3. Showing custom aliases
The user can enter show alias
to invoke an instance of ShowCustomAliasCommand
to view all the alias and block pairs that have been stored previously by them.
If there are no alias and block pairs, then the message You haven't set any aliases yet!
will be displayed to the user. If there
are valid alias and block pairs stored in the application, then the list of alias and block pairs will be displayed.
3.4.4. Deleting a custom alias
The user can enter delete alias
to invoke an instance of DeleteCustomAliasCommand
which will prompt them for the alias name that they
wish to delete. If the entered alias name exists in the alias hashmap stored in the instance of BlockAlias
, then that alias will be removed.
However, if the alias does not exist in the hashmap, then an invalid alias error message will be displayed.
3.4.5. Example for alias feature
Given below is an example usage scenario and how the add/view/delete mechanism behaves at each step:
-
The user launches the application for the first time. If there is a storage file with pre-existing alias-block pairs, then the hashmap in
BlockAlias
class will be initialized with those data, or an empty hashmap if it does not exist. -
The user executes
add alias
command. The user input will be parsed by theParser
which will create a newAddCustomAliasCommand
command. This will invoke the UI which will prompt the userEnter the block:
to input the block name andEnter the alias name:
to input the alias name that the user wants. The UI parser will then check if the entered block and alias are valid and throw an exception if they are not. -
The entered alias and block pair will then be put into a temporary hashmap which will then be merged with the main hashmap in the instance of the BlockAlias.
-
The user executes
show alias
command. The user input will be parsed by theParser
which will create a newShowCustomAliasCommand
command. The new command will then invoke the UI which will printIt seems that you do not have any aliases
if the hashmap is empty, or it will print the alias-block pairs in new lines when the hashmap has been previously populated. -
The user executes
delete alias
command. The user input will be parsed by theParser
which will create a newDeleteCustomAliasCommand
command. The new command will then invoke the UI which will prompt the userEnter the alias name that you wish to delete:
where the user will enter the alias name that the user wishes to remove. The user input for the alias to be removed will be checked against the hashmap and return an exception if the key does not exist. If the alias to be removed exists in the hashmap, the key-value pair will be removed, and a success message will be displayed to the user.
Shown below is the sequence diagram when a valid block name and alias are added:
3.4.6. Design Consideration
Current choice: Saves the alias and block names in a hashmap stored within a data model class which is the BlockAlias
class.
- Pros: Easy to implement.
- Cons: The same instance of
BlockAlias
needs to be shared among the other classes that may use the alias feature.
3.5. History feature
3.5.1. Current Implementation
Whenever the user inputs the go
command, and enters a valid start and destination address, a String consisting the start and end block is created and stored in historyList
.
The contents of the historyList
will be stored into a text file named historyList.txt
when NUSMaze terminates.
3.5.2. Loading of saved history
When NUSMaze starts running, any contents from historyList.txt
file would be loaded and stored into historyList
.
Refer to the section on Storage for more information.
3.5.3. Showing past searches
The user can enter the command history
, and a numbered list of past searches will be shown to the user.
If there were no past searches, a line of text "Oops! You have no past history!"
will be shown to the user.
3.5.4. Repeat past searches
The user can enter the command repeat history
to request for a repeat of past searches.
If there are no past searches, a line of text "Oops! You have no past history!"
will be shown to the user.
If there is at least one entry in historyList
, then all past searches would be shown to the user, in a numbered list format.
(Only the starting location and destination location will be shown.)
The user is then prompted to enter the index of the past search to repeat.
3.5.5. Clear past searches
The user can enter the command clear history
to delete all the contents of historyList
.
A message: "Your history has been successfully cleared"
will be shown to the user upon successful deletion of the contents of historyList
.
3.5.6. Design Consideration
Alternative 1 (current choice): Each command to add, view and delete are implemented using separate classes.
Pros: Easy to understand and each command is standalone.
Cons: Might have to repeat some code fragments.
Alternative 2: Place all commands (add, view, delete) as functions in 1 command class.
Pros: Less code to be written and hashmap can be shared by the 3 commands in 1 class.
Cons: Might be confusing since there is less distinction between each command.
3.6. Save feature
3.6.1. Current Implementation
The save mechanism is facilitated by AliasStorage
, DailyRouteStorage
, FavouriteStorage
, HistoryStorage
and NotesStorage
subclasses. </br>
They extend Storage
(superclass) with a feature to save the blocks’ aliases, daily routes, favourite locations, history of visited routes and tagged notes, stored internally as aliasList
, dailyRouteList
, favouriteList
, history
, noteList
text files.
Additionally, they implement the following operations:
-
AliasStorage#saveData()
— Saves all aliases given by user to blocks intoaliasList
.
-
AliasStorage#loadData()
— Restores all aliases given by user to blocks fromaliasList
.
-
DailyRouteStorage#saveData()
— Saves all the daily routes that user wants to see for each day of the week intodailyRouteList
.
-
DailyRouteStorage#loadData()
— Restores all the daily routes that user wants to see fromdailyRouteList
.
-
FavouriteStorage#saveData()
— Saves the current list of all the routes that the users are interested in keeping infavouriteList
.
-
FavouriteStorage#loadData()
— Restores the previous list of all the routes that the users are interested in keeping fromfavouriteList
.
-
HistoryStorage#saveData()
— Saves the current list of the 10 most recently visited routes in its history intohistory
.
-
HistoryStorage#loadData()
— Restores the previous list of the 10 most recently visited routes in its history fromhistory
.
-
NotesStorage#saveData()
— Saves all notes tagged to a location intonoteList
.
-
NotesStorage#loadData()
— Restores all notes tagged to a location fromnoteList
.
These ‘saveData()’ operations are exposed in the DataEncoder
interface as DataEncoder#encodeAlias(:BlockAlias)
, DataEncoder#encodeDailyRoute(:DailyRoute)
, DataEncoder#encodeFavourite(:Favourite)
, DataEncoder#encodeHistory(:History)
and DataEncoder#encodeNotes(:NusMap)
respectively.
These ‘loadData()’ operations are exposed in the DataDecoder
interface as DataDecoder#decodeAliasAndNoteData()
, DataDecoder#decodeDailyRouteData()
and DataDecoder#decodeHistoryAndFavouriteData()
.
3.6.2. Saving/Loading data
Given below is an example usage scenario and how the save mechanism behaves at each step.
- The user launches the application for the first time.
AliasStorage
,DailyRouteStorage
,FavouriteStorage
,HistoryStorage
andNotesStorage
objects will be initialized with the filepaths ofaliasList
,dailyRouteList
,favouriteList
,history
andnoteList
text files respectively.
TheblockAlias
,dailyRoute
,favourite
,history
ornusMap
object inNusMaze
class will be initialised using the initial state of the respective text file, by callingAliasStorage#loadData()
,DailyRouteStorage#loadData()
,FavouriteStorage#loadData()
HistoryStorage#loadData()
andNotesStorage#loadData()
.
This is done only once for each time the application is launched.
- For all valid commands called before the last user input ‘bye’ or before program is terminated, the following process is executed continuously.
AliasStorage#saveData()
,DailyRouteStorage#saveData()
,FavouriteStorage#saveData()
,HistoryStorage#saveData()
,NotesStorage#saveData()
are called. When#saveData()
for each of the storage objects are called, data from theblockAlias
,dailyRoute
,favourite
,history
ornusMap
object is saved into the respective text file.
AliasStorage#saveData()
, DailyRouteStorage#saveData()
, FavouriteStorage#saveData()
, HistoryStorage#saveData()
, NotesStorage#saveData()
will be executed,
but not all text files will be modified. * The
history
text file is modified by the go
, clear history
and repeat history
commands. * The
aliasList
text file is modified by the add alias
and delete alias
commands. * The
dailyRouteList
text file is modified by the add daily route
and delete daily route
commands. * The
noteList
text file is modified by the add note
and delete note
commands. * The
favouriteList
text file is modified by the add favourite
, repeat favourite
and delete favourite
commands If a command fails its execution, it will not call #saveData()
for all the storage objects,
so the content from the nusMap
, blockAlias
, history
, favourite
, or dailyRoute
objects will not be saved into the text files.
3.6.3. Design Consideration
Current choice: Saves the entire list of block aliases, visited routes, tagged notes, daily routes and favourite locations.
- Pros: Easy to implement.
- Cons: Only highly effective when limited to use of one user.
4. Appendix: Requirements
4.1. Product Scope
NUSMaze is targeted at NUS engineering freshmen, to help new students find their way to their destination blocks.
The engineering block is extremely huge, and the layout of the blocks may be confusing for new students. To reduce the time wasted on navigating the numerous blocks in Engineering, NUSMaze will provide the shortest route available for students to take.
4.2. User Stories
Below is our analysis of our target user and the importance in which he/she would place on the potential user stories we have chosen.
Version | As a … | I want to … | So that I … | Importance |
---|---|---|---|---|
v1.0 | new user | see usage instructions | can refer to them when I forget how to use the application | HIGH |
v1.0 | user | have a clear path to my destination | will not get lost | HIGH |
v1.0 | user | be able to pin a note to certain locations as a reminder | do not forget | MEDIUM |
v1.0 | user | keep track of my search history | don’t have to repeatedly search for the same route. | MEDIUM |
v1.0 | user | have a clear interface in which I can enter my commands | can have a good user experience | HIGH |
v2.0 | user | find the nearest eatery | do not have to starve for longer than necessary | HIGH |
v2.0 | user | have a list of favorite locations | can access directions to them quickly | MEDIUM |
v2.0 | user | have my list of favourites and history stored | can access it every time I start the app | MEDIUM |
v2.0 | user | be able to set custom aliases to blocks | can access the blocks more conveniently | MEDIUM |
v2.0 | user | be able to store my routing for my daily activities | can access it easily | MEDIUM |
4.3. Use Cases
4.4. Non-Functional Requirements
-
Should work on any mainstream OS as long as it has Java 11 or above installed.
-
Should be able to hold up to 1000 history, notes, favourites and block alias entries without a 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.
4.5. Glossary
- CLI - Command Line Interface
- IntelliJ - An Integrated Development Environment (IDE) designed for Java software development.
- UML - Unified Modeling Language.
- Terminal/PowerShell - Any operating system shell with a command-line interface.
- Mainstream OS - Windows, mainstream distributions of Linux, and macOS.
- JDK - Java Development Kit.
5. Appendix: Instructions for manual testing
5.1 Launch and shutdown
- Initial launch
1.1. Download the latest jar file from here and copy it into an empty folder.
1.2. Open the terminal/powershell console and navigate to the folder in which the.jar
file was saved.
Expected: Greeting message of NUSMaze to be shown
- Exiting the application
2.1 Enterbye
and press enter
Expected: The application shows thank you message and exits successfully.
5.2 Viewing help
- Viewing help for NUSMaze
1.1 Enterhelp
Expected: A list of all the commands that can be used in NUSMaze should be displayed.
5.3 Viewing venues in NUSMaze
- Viewing all the blocks in NUSMaze (Currently only the Engineering and Computing blocks)
1.1 Entershow venues
Expected: A table of all the blocks that have been pre-loaded into NUSMaze.
5.4 Routing
- Routing with valid blocks
1.1 Launch the application and type ‘Go’ followed by the enter key.
1.2 Test case: Starting block →E1
, Destination block →E7
Expected:Route: E1 -> LT5 -> E3 -> E4 -> E4A -> EW2 -> E6 -> E7
should be displayed
1.3 Test case: Starting block →e4
, Destination block →techno edge
Expected:Route: E4 -> E3 -> LT5 -> TECHNO EDGE
should be displayed
- Routing with invalid blocks
2.1 Test case: Starting block →E20
, Destination block →E7
Expected:Invalid block! Please try again with a block that exists :(
should be displayed
2.2 Test case: Starting block →Invalid block
, Destination block →Invalid block
Expected: Similar to previous
- Routing to an eatery
3.1 Test case: Starting block →e3
, Destination block →eatery
, Select entry to go →5
Expected:Route: E3 -> E2 -> EA -> SPINELLI COFFEE
should be displayed
3.2 Test case: Starting block →e3
, Destination block →spinelli coffee
Expected: Similar to previous
5.5 History
- Viewing history when routing has not been used or history has been cleared
1.1 Enterhistory
Expected:Oops! You have no past history!
- Viewing history when routing has been previously used
2.1 Enterhistory
Expected: A list of the past routing history will be displayed (Capped at 10)
- Repeating history when history is empty
3.1 Enterrepeat history
Expected:Oops! You have no past history!
- Repeating history when there is 1 record in the history
4.1 Test case:repeat history
→1
Expected: The result of the routing will be displayed
4.2 Test case:repeat history
→2
Expected:Oops! You must enter an Integer that is within the bounds :(
- Clearing history
5.1 Enterclear history
Expected:Your history has been successfully cleared
5.6 Alias
- Adding an alias that is a block name
1.1 Enteradd alias
→ Enter block →e3
, Enter the alias name →e4
Expected: The error message for invalid alias will be displayed
- Adding an alias that already exists
2.1 Enteradd alias
→ Enter block →e1
, Enter the alias name →alias that already exists
Expected: Similar to previous
- Showing aliases when there are no aliases that were set prior.
3.1 Entershow alias
Expected:You haven't set any aliases yet!
- Showing aliases when aliases have been previously set.
4.1 Entershow alias
Expected: A list of alias and block pairs will be displayed
- Deleting an alias that was not previously set
5.1 Enterdelete alias
→alias that does not exist
Expected:Invalid alias! Please enter an alias name that exists!
- Deleting an alias that was previously set
6.1 Enterdelete alias
→alias that exists
Expected:Got it! Successfully deleted ALIAS THAT EXISTS from alias list!
5.7 Daily Route
- Viewing daily route when the user haven’t scheduled any daily route.
1.1 Entershow daily route
Expected:Oops! You haven't planned any daily routes yet :(
- Adding daily route
2.1 Test case:add daily route
→1
→ea
→end
Expected:Got it! Successfully added MONDAY's schedule!
2.2 Test case:add daily route
→8
Expected:Oops! You must enter an Integer that is within the bounds :(
- Deleting daily route when only Monday’s schedule is planned
3.1 Test case:delete daily route
→1
Expected:Got it! Successfully cleared MONDAY's schedule!
3.2 Test case:delete daily route
→2
Expected:Oops! You must enter an Integer that is within the bounds :(
5.8 Favourites
- Adding favourite routes
1.1 Test case: Starting block →E1
, Destination block →E7
Expected:Got it! Successfully added new favourite route!
1.2 Test case: Starting block →E1
, Destination block →Invalid
ExpectedInvalid block! Please try again with a block that exists :(
- Showing favourite routes when favourites have not been set before
2.1 Entershow favourite
Expected:You haven't set any favourite routes yet!
- Showing favourite routes when favourites have been set before
3.1 Entershow favourite
Expected: A list of all the favourite routes that have been previously set will be displayed
- Deleting favourite routes
4.1 Test casedelete favourite
→VALID_FAVOURITE_INDEX
Expected:Got it! Successfully deleted favourite route :)
4.2 Test casedelete favourite
→INVALID_FAVOURITE_INDEX
Expected:Oops! You must enter an Integer that is within the bounds :(
5.9 Notes
- Adding note to blocks
1.1 Test case:add note
→e1
→crowded
Expected:Got it! Successfully added and tagged note to E1
1.2 Test case:add note
→e20
→crowded
Expected:Invalid block! Please try again with a block that exists :(
1.3 Test case:add note
→e1
→""
Expected:Your note description cannot be empty or contain "/". Please try the command again :)
1.4 Test case:add note
→e1
→very/crowded
Expected:Your note description cannot be empty or contain "/". Please try the command again :)
- Viewing notes tagged to specific block
2.1 Test case:show note
→e1
Expected: Show a list of notes tagged to e1
2.2 Test case:show note
→e20
Expected:Invalid block! Please try again with a block that exists :(
- Deleting note tagged to a specific block
3.1 Test case:delete note
→e1
→1
(When there is at least one note tagged to e1)
Expected:Got it! Successfully deleted note tagged to E1
3.2 Test case:delete note
→e1
→1
(When there are no notes tagged to e1)
Expected:Oops! There are no notes tagged to E1