Authors: Daryl Tan, Jeff Gan, Jothinandan Pillay, Lin Dehui, Shune Lei
Team: CS2103-AY1819S2-W10-2
Since: January 2019
License: MIT
- 1. Introduction
- 2. Background Information
- 3. Before We Begin
- 4. Setting up
- 5. Design
- 6. Implementation of Key Features
- 6.1. Pocket Project Dates (Smart Dates)
- 6.2. Adding Employees and Milestones to a Project
- 6.3. Remove employee/milestone/project task/user story from projects feature
- 6.4. Edit Project feature
- 6.5. Find Employee/Project/Skill/All feature
- 6.6. List Employee/Project feature
- 6.7. Stats feature
- 6.8. User Story feature
- 6.9. Project Task feature
- 6.10. Undo/Redo feature
- 6.11. [Proposed] Data Encryption
- 6.12. Logging
- 6.13. Configuration
- 7. Documentation
- 8. Testing
- 9. Dev Ops
- 10. FAQ
- Appendix A: Product Scope
- Appendix B: User Stories
- Appendix C: Use Cases
- Appendix D: Non Functional Requirements
- Appendix E: Glossary
- 11. Instructions for Manual Testing
- 11.1. Launch and Shutdown
- 11.2. Add Command
- 11.3. Adding a project
- 11.4. Adding a milestone
- 11.5. Adding a project task
- 11.6. Adding a UserStory
- 11.7. Delete Command
- 11.8. Editing an employee
- 11.9. Deleting a project
- 11.10. Removing an employee from a project
- 11.11. Removing a milestone from a project
- 11.12. Removing a project task from a project
- 11.13. Updating status of a project task
- 11.14. Finding an employee/project by keywords in their names
- 11.15. Finding employees with specific skills
- 11.16. Finding projects with specific keywords in their name, description or deadline
- 11.17. Indicating a project as completed
- 11.18. Clearing all data from the app
- 11.19. Exiting from the app
- 11.20. Undoing a data modification
- 11.21. Redoing a data modification that has been undone
1. Introduction
PocketProject is primarily an application for software engineering project managers who are currently in-charge of a large team of employees and many projects. This application employs the use of a Command Line Interface(CLI) to easily navigate through the application which contributes to the efficiency and user-friendliness of the end product. This application allows managers to keep track of all the employees and their related background information such as their GitHub account username and relevant skills. Additionally, it also helps to keep track of all the projects that the manager is currently involved with and key details of the project such the client, deadline and milestones can also be stored. Through the combination of the two main components, the application allows the storing and viewing of all the employees working on particular project and all the projects currently under a single employee among other functionalities.
2. Background Information
When first seeing our application, many of you may wonder what is the significance behind this project. Well, the current issues cannot be seen at the surface level and requires a deeper look. To present all the information in a nutshell, our application provides everything that a manager will ever need at the tip of his fingertips. Being able to better handle project and man management leads to a more organized workflow and inevitably, a more productive environment which can set a strong foundation for the lifecycle of various projects.
In addition, the inability to track the progress of a project has been cited as one of the top reasons as to why a product fails, and thus our application aims to potentially solve this problem by having both a milestones feature and a task manager to mainly see not only what has been completed, but also the proposed schedule for the weeks ahead until the project is due for completion.
3. Before We Begin
3.1. Symbols
The following section details and previews a few symbols that will be used throughout the developer guide. These symbols are used to represent special information such as tips and warnings.
Symbol | Meaning |
---|---|
The note pad icon indicates any useful tips or things that users need to take note of while using the Pocket Project application. |
|
The light bulb icon indicates any shortcuts that users can use while using the Pocket Project application. |
|
The exclamation mark icon indicates any warnings that users can take note of while using the Pocket Project application. |
|
The graduation cap icon indicates any advanced usages or extra technical information about how a particular command works should the users be interested to know. |
3.2. Glossary
The following section details a few key technical terms that are used through the course of the Developer Guide.
Term | Meaning |
---|---|
Alphanumeric |
Only contains either digits (0-9) or letters of the English alphabet (A-Z). |
Command Line Interface (CLI) |
A means of interacting with a computer program where the user issues commands to the program in the form of successive lines of text. |
Lexicographic |
Ordering of words based on how it would appear in a dictionary. |
Milestone |
A key event that is completed during the entire timeline of the project. |
Project Task |
Events which are completed during a milestone to achieve the next milestone. |
Regex |
Short-form for regular expression. A regular expression is a pattern used to match character combinations in strings. Basically it is used to check if a given input matches the prescribed pattern or format. |
One-Based Indexing |
Way of numbering in which the initial element of a sequence is assigned the index 1. |
Zero-Based Indexing |
Way of numbering in which the initial element of a sequence is assigned the index 0. |
4. Setting up
4.1. Prerequisites
-
JDK
9
or laterJDK
10
on Windows will fail to run tests in headless mode due to a JavaFX bug. Windows developers are highly recommended to use JDK9
. -
IntelliJ IDE
IntelliJ by default has Gradle and JavaFx plugins installed.
Do not disable them. If you have disabled them, go toFile
>Settings
>Plugins
to re-enable them.
4.2. Setting up the project in your computer
-
Fork this repo, and clone the fork to your computer
-
Open IntelliJ (if you are not in the welcome screen, click
File
>Close Project
to close the existing project dialog first) -
Set up the correct JDK version for Gradle
-
Click
Configure
>Project Defaults
>Project Structure
-
Click
New…
and find the directory of the JDK
-
-
Click
Import Project
-
Locate the
build.gradle
file and select it. ClickOK
-
Click
Open as Project
-
Click
OK
to accept the default settings -
Open a console and run the command
gradlew processResources
(Mac/Linux:./gradlew processResources
). It should finish with theBUILD SUCCESSFUL
message.
This will generate all resources required by the application and tests. -
Open
MainWindow.java
and check for any code errors-
Due to an ongoing issue with some of the newer versions of IntelliJ, code errors may be detected even if the project can be built and run successfully
-
To resolve this, place your cursor over any of the code section highlighted in red. Press ALT+ENTER, and select
Add '--add-modules=…' to module compiler options
for each error
-
-
Repeat this for the test folder as well (e.g. check
HelpWindowTest.java
for code errors, and if so, resolve it the same way)
4.3. Verifying the setup
-
Run the
seedu.address.MainApp
and try a few commands -
Run the tests to ensure they all pass.
4.4. Configurations to do before writing code
4.4.1. Configuring the coding style
This project follows oss-generic coding standards. IntelliJ’s default style is mostly compliant with ours but it uses a different import order from ours. To rectify,
-
Go to
File
>Settings…
(Windows/Linux), orIntelliJ IDEA
>Preferences…
(macOS) -
Select
Editor
>Code Style
>Java
-
Click on the
Imports
tab to set the order-
For
Class count to use import with '*'
andNames count to use static import with '*'
: Set to999
to prevent IntelliJ from contracting the import statements -
For
Import Layout
: The order isimport static all other imports
,import java.*
,import javax.*
,import org.*
,import com.*
,import all other imports
. Add a<blank line>
between eachimport
-
Optionally, you can follow the UsingCheckstyle.adoc document to configure Intellij to check style-compliance as you write code.
4.4.2. Updating documentation to match your fork
After forking the repo, the documentation will still have the SE-EDU branding and refer to the se-edu/pocketproject
repo.
If you plan to develop this fork as a separate product (i.e. instead of contributing to se-edu/pocketproject
), you should do the following:
-
Configure the site-wide documentation settings in
build.gradle
, such as thesite-name
, to suit your own project. -
Replace the URL in the attribute
repoURL
inDeveloperGuide.adoc
andUserGuide.adoc
with the URL of your fork.
4.4.3. Setting up CI
Set up Travis to perform Continuous Integration (CI) for your fork. See UsingTravis.adoc to learn how to set it up.
After setting up Travis, you can optionally set up coverage reporting for your team fork (see UsingCoveralls.adoc).
Coverage reporting could be useful for a team repository that hosts the final version but it is not that useful for your personal fork. |
Optionally, you can set up AppVeyor as a second CI (see UsingAppVeyor.adoc).
Having both Travis and AppVeyor ensures your App works on both Unix-based platforms and Windows-based platforms (Travis is Unix-based and AppVeyor is Windows-based) |
4.4.4. Getting started with coding
When you are ready to start coding,
-
Get some sense of the overall design by reading Section 5.1, “Architecture”.
-
Take a look at [GetStartedProgramming].
5. Design
5.1. Architecture
The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.
The .pptx files used to create diagrams in this document can be found in the diagrams folder. To update a diagram, modify the diagram in the pptx file, select the objects of the diagram, and choose Save as picture .
|
Main
has only one class called MainApp
. It is responsible for,
-
At app launch: Initializes the components in the correct sequence, and connects them up with each other.
-
At shut down: Shuts down the components and invokes cleanup method where necessary.
Commons
represents a collection of classes used by multiple other components.
The following class plays an important role at the architecture level:
-
LogsCenter
: Used by many classes to write log messages to the App’s log file.
The rest of the App consists of four components.
Each of the four components
-
Defines its API in an
interface
with the same name as the Component. -
Exposes its functionality using a
{Component Name}Manager
class.
For example, the Logic
component (see the class diagram given below) defines it’s API in the Logic.java
interface and exposes its functionality using the LogicManager.java
class.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete employee 1
.
delete employee 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
, SideTabPanel
, StatusBarFooter
, DetailsPanel
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class.
The UI
component uses JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files that are in the src/main/resources/view
folder. For example, the layout of the MainWindow
is specified in MainWindow.fxml
The UI
component,
-
Executes user commands using the
Logic
component. -
Listens for changes to
Model
data so that the UI can be updated with the modified data.
5.3. Logic component
API :
Logic.java
-
Logic
uses thePocketProjectParser
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 employee). -
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 employee 1
Command5.4. Model component
API : Model.java
The Model
,
-
stores a
UserPref
object that represents the user’s preferences. -
stores the Pocket Project data.
-
exposes an unmodifiable
ObservableList<Employee>
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 Skill list in Pocket Project , which Employee can reference. This would allow Pocket Project to only require one Skill object per unique Skill , instead of each Employee needing their own Skill object. An example of how such a model may look like is given below. |
5.5. Storage component
API : Storage.java
The Storage
component,
-
can save
UserPref
objects in json format and read it back. -
can save the Pocket Project data in json format and read it back.
5.6. Common classes
Classes used by multiple components are in the seedu.address.commons
package.
6. Implementation of Key Features
This section describes some noteworthy details on how certain features are implemented.
6.1. Pocket Project Dates (Smart Dates)
6.1.1. Overview
As dates are widely used throughout the application, it is important that the user is able to easily input any target date but at the same time retain some flexibility so that it is more user-friendly. Therefore, the dates used in the Pocket Project supports 2 main formats as shown below.
Fixed Date Format
Format(s):
1. DD/MM/YYYY
Flexible Date Format
Format(s):
1.today/tomorrow/yesterday
2.this/next/last week DAY_OF_WEEK
3.this/next/last month DAY_OF_MONTH
6.1.2. How it Works
The section details how a fixed and flexible date format is parsed and processed.
Refer to the Activity Diagram above while reading the summary below so as to have a visual representation of what happens.
To simplify the explanation, the process can be summarized into the following key points:
1. A check is first made to determine if the input is a fixed or flexible date format. This is done by
checking for the presence of a /
in the input.
2. If it is a fixed format input, a check is made to determine if it conforms to the DD/MM/YYYY
format.
3. If it is a flexible format input, the input is parsed and the PocketProjectParser
identifies keywords to determine the appropriate methods to call from the model. The target
date is then formatted into the DD/MM/YYYY
format.
4. Regardless of the initial format of the input, the current string would represent the form
of DD/MM/YYYY
at this stage. The validity of the date is then checked.
Refer to the code snippet below to see how the validity of the date is verified.
As can be seen above, the code not only checks if the selected day falls within the maximum number of days in a month, but it also checks for leap years. This ensures that only valid calendar dates are accepted as a viable input.
6.1.3. Design Considerations
Potential Design 1
User keys in Wednesday
, next Wednesday
, last Wednesday
to denote the current, next and last week’s Wednesday respectively
Potential Design 2 (Selected Implementation)
User keys in this week 3
, next week 3
, last week 3
to denote the current, next and last week’s Wednesday respectively
The second design was chosen as the first one is subjective to an individual’s language
use. For example, if today was Monday, and a person was to mention next Wednesday
, some people may be thinking of the Wednesday in 2 days time
whereas others may be thinking of next week’s Wednesday. Thus to remove confusion, the keyword this/next/last was added. In addition, instead of spelling out the days,
users can key in the day number instead. This speeds things up and also reduces errors due to spelling mistakes in the name of the day.
6.2. Adding Employees and Milestones to a Project
6.2.1. Overview
This feature focuses on the adding of employees and milestones to a selected project. It supports two commands which are explained below.
-
addto PROJECT_NAME employee EMPLOYEE_INDEX
Adds the employee at indexEMPLOYEE_INDEX
to the list of employees in the project namedPROJECT_NAME
. -
addto PROJECT_NAME milestone m/MILESTONE_DESCRIPTION d/MILESTONE_DATE
Adds the specified milestone to the list of milestones in project namedPROJECT_NAME
.
In addition, the AddToEmployeeCommand
class and AddToMilestoneCommand
class is
abstracted into a AddToCommand
class which inherits from Command
class. This allows for
further functionalities to be added while conforming to the Open-Closed Principle.
Refer to the Class Diagram below for a better visualization of the inheritance relationship.
6.2.2. How it Works
The section details how a AddToCommand
is parsed and processed.
Refer to the sequence diagram above to better understand how the AddEmployeeTo
Command
works. The diagram shows the sequence when a addto Apollo employee 1
is executed.
To simplify the explanation, the process can be summarized into the following key points:
1. The PocketProjectParser
parses the string received and uses the addto
keyword to identify that the input
is linked with the AddToCommand
class.
2. The AddToCommandParser
then identifies the type of AddToCommand
that is being executed and the arguments involved.
3. The AddToCommandParser
then creates the AddEmployeeToCommand
/AddMilestoneToCommand
object and this is passed on to the LogicManager
for execution.
4. The command execution will check the validity of the arguments and then call the methods of the Model
component to add the corresponding
employee/milestone to the project.
The main difference between the 2 commands is deciding the object to be added (Employee or Milestone) from model based on the user input. |
6.2.3. Design Considerations
Potential Design 1
The idea is to have only 1 parser ,PocketProjectParser
, which receives and parses the whole input string
before constructing the relevant command.
Potential Design 2 (Selected Implementation)
The idea is to have a total of 2 parsers where the first parser, PocketProjectParser
identifies the addto
key word
and the rest of the input string is then parsed by the corresponding second parser, AddToCommandParser
.
The 2nd design was chosen as there is better abstraction of the details and it also allows further functionality
to be add on top of the implemented parser. If future developers want to add more objects to the project, they can simply
make use of this AddToCommandParser
to handle different inputs. Choosing this design was a good choice as it helped with the
implementation of adding user stories and project tasks to a project after this was initially constructed.
6.2.4. Future Planned Implementations
The following additional feature is scheduled to be implemented in future versions.
-
Add an alias for the arguments in the addto commands so that it is more user-friendly for users of this application. Users can key in the two above mentioned commands by replacing
employee
withe
andmilestone
withms
. The commands can be input as such:-
addto PROJECT_NAME e EMPLOYEE_INDEX
instead ofaddto PROJECT_NAME employee EMPLOYEE_INDEX
-
addto PROJECT_NAME ms m/MILESTONE_DESCRIPTION d/MILESTONE_DATE
instead ofaddto PROJECT_NAME milestone m/MILESTONE_DESCRIPTION d/MILESTONE_DATE
-
The commands will be processed in the same way without any other changes.
6.3. Remove employee/milestone/project task/user story from projects feature
6.3.1. Current Implementation
The removing of employee,milestone or user story from projects is facilitated by the model component of the PocketProject. This feature currently supports these three commands:
-
removefrom [project name] employee [employee index]
— removes the employee at index[employee index]
in the list of employees in the project named[project name]
. -
removefrom [project name] milestone [milestone index]
— removes the milestone at index[milestone index]
in the list of milestones in the project named[project name]
. -
removefrom [project name] projecttask [milestone index] [project task index]
— removes the project task at index[project task index]
in the list of tasks under the milestone specified by[milestone index]
in the project named[project name]
. -
removefrom [project name] userstory [userstory index]
— removes the user story at index[userstory index]
in the list of user stories in the project named[project name]
.
These operations are supported by the methods in the Model
interface: Model#removeEmployeeFrom(Project, Employee)
, Model#removeMilestoneFrom(Project, Milestone)
, Model#removeProjectTaskFrom(Project, Milestone, ProjectTask)
and Model#removeUserStoryFrom(Project, UserStory)
.
The methods does not take in indices as arguments since the corresponding Employee, Milestone, ProjectTask or UserStory object associated with the Project object would be found by RemoveEmployeeFromCommand#excute()
, RemoveMilestoneFromCommand#execute()
, RemoveProjectTaskFromCommand#execute()
or RemoveUserStoryFromCommand#execute()
before the methods of Model
are called.
The sequence diagram for the execution of the removing of employee from a project is as follows, the sequence for the removal of milestone, project tasks and user stories are similar:
removefrom Apollo employee 1
.Given below is an example usage scenario and how the removal of employee/milestone/project task/user story feature behaves at each step.
Step 1. The user enters the command view project Apollo'. The app displays the list of employees and milestones in the project named "Apollo" by executing the `view
command.
Step 2. The user enters removefrom Apollo employee 1
. The LogicManager
passes the entered string to the PocketProjectParser
. The PocketProjectParser
parses the string received and identifies the command as falling under the class of RemoveFromCommand
(which constitutes of RemoveEmployeeFromCommand
and RemoveMilestoneFromCommand
by the removefrom
keyword and passes the rest of the string to the RemoveFromCommandParser
to identify which type of RemoveFromCommand
is being executed and what are the arguments.
The RemoveFromCommandParser
then creates command object and passes it to the LogicManager
to be executed. The command execution will check the validity of the arguments and then call the methods of the Model
component to remove the corresponding objects.
Step 3. The user executes 'removefrom Apollo milestone 2'. The execution of this command is similar to step 2, just that the type of object changes from Employee
to Milestone
.
The |
6.3.2. Design Considerations
Aspect: How the command string (e.g. removefrom Apollo employee 1
) is parsed
Alternative 1: Let PocketProjectParser
handle the whole string and construct the command.
Alternative 2: Having 2 parsing stages where the PocketProjectParser
identify that the command string is trying to execute a RemoveFromCommand
from the removefrom
key word, then passes
the rest of the string to another specialized RemoveFromCommandParser
. (current implementation)
Using alternative 2 is better as it provides better abstraction as the details of the 2 different types of RemoveFromCommand
will be hidden away, hence it is more in line with OOP principles.
There will also be less clutter in PocketProjectParser
as there are already a lot of other commands being parsed.
6.4. Edit Project feature
6.4.1. Current Implementation
This feature allows editing of several components which are under project and is mainly facilitated by the model component. This feature supports 3 main commands:
-
edit project PROJECT_NAME info [n/name] [c/client] [d/deadline] [desc/description]
- allow editing of project’s name, deadline, description -
edit project PROJECT_NAME milestone MILESTONE_INDEX [m/milestone] [d/date]
- allow editing of details of project milestone such as milestone description and date -
edit project PROJECT_NAME userstory USERSTORY_INDEX STORY
- allow editing of details of project’s userstory (explained here Section 6.8.2.3, “Edit user story command”)
The EditProjectCommand Parser
differentiate these 3 commands based on the COMMAND_KEYWORD
which are info, milestone and userstory.
EditCommand
All these 3 commands are inherited from the EditProjectCommand
as shown in the diagram above. This allows flexibility as more edit project command can be easily added when there are new components added to the project.
The following sequence diagram shows how edit project info
command works:
edit project Apollo info n/Gemini d/12/05/2019
Given below is the explanation of what happens when the user enter the edit project Apollo info n/Gemini d/12/05/2019
command based on the diagram above:
-
User executes
edit project Apollo info n/Gemini d/12/05/2019
to edit name and deadline of the project named Apollo. -
PocketProjectParser
will identify the command as anEditCommand
based on the wordedit
and pass on the argument to the EditCommandParser. -
Similarly the arguments will continue to parse through
EditCommandParser
andEditProjectCommandParser
which will identify the command asEditProjectInfoCommand
and return it back to theLogicManager
-
LogicManager
then execute the command. Validity of the arguments are checked here as well. The methodModel#setProject(projectToEdit, editedProject)
is called to replace the old project with the edited project which contains the new parameters. This method also update the list of project names in the employees who are assigned to project Apollo. -
Finally, the project Apollo is edited and the updated details are shown on the UI.
If the arguments provided are invalid, a |
The working mechanism behind EditProjectMilestoneCommand
is similar as well. Instead of replacing the whole project, only the milestone list in the project is edited by replacing the milestone at the given index through the Model#setMilestone(milestoneToEdit, editedMilestone)
method.
6.4.2. Design Consideration
Aspect how to structure the classes under edit command
Alternative 1: Have a single edit project command that allow users to edit all the parts of the project in one command
Alternative 2: Have several separate commands that edit different parts of the project (current implementation)
For alternative 1, the user will not need to remember many commands just to edit the project. However since there are a lot of components in the project, different prefixes will be needed for different components so that the parser can identify which component to edit. There are also overlapping attributes in the components such as milestone date and project deadline or milestone description and project description. Therefore it is going to be messy in terms of code as well as in terms of usage of the command.
Even though alternative 2 involves having to remember different commands, it can be implemented in a way so that the commands are intuitive to the user. For instance,
the command format for current implementation is quite intuitive. The user just need to specify edit project
then add in name of the project to edit and the components the user wish to edit.
Thus, alternative 2 is chosen as it is less confusing both in term of code and usage and can be tweaked to make the command user-friendly.
6.5. Find Employee/Project/Skill/All feature
6.5.1. Current Implementation
For the current find
feature, there are 5 main commands that the user can execute:
-
find employee [KEYWORDS]
- display employees with name containing keywords -
find project [KEYWORDS]
- display projects with name containing keywords -
find skill [KEYWORDS]
- display employees who has skills matching the keywords -
find all [KEYWORDS]
- display projects which contains words matching the keywords -
find deadline KEYWORD
- display projects which contains deadline before the keyword
The FindCommandParser
differentiates these 5 commands based on the COMMAND_KEYWORDS
entered by the users (e.g. employee/project/skill/all/deadline) as illustrated in the diagram below.
FindCommandParser
The following sequence diagram shows how the find employee
command works:
find employee John
commandUsage Scenario example for find employee
:
-
User executes
find employee John
to look for employees whose names contains the word 'John'. -
PocketProjectParser
will parse and identify the command as aFindCommand
and pass on the argumentemployee John
toFindCommandParser
. -
FindCommandParser
identify the command based on theCOMMAND_KEYWORD
'employee'. -
find employee
command is executed. Employees with name consisting the keywords are filtered out from the employeelist. The filtering is done through the use ofProjectNameContainsKeywordPredicate
that checks through the names of the employee int the application. -
Finally, the
filteredEmployees
list which is the list displayed on the ui is updated.
The working mechanism for find project
is similar to find employee
. Instead of updating the filteredEmployees
, filteredProjects
is updated instead to display the list of projects with name consisting the keywords.
For find all
command, the predicate is used to check for the matching keywords in the project name , description and client, thereby filtering out any projects that contains the keyword in these components of the project.
For find skill
command, the List<Skills>skills
from the employee is retrieved as a String
to match against the keywords. Then the matched employees are filtered and displayed on the ui.
find deadline
uses the ProjectContainsDeadlinePredicate
to compare the deadline of the project against the supplied deadline and filter out the projects with deadline earlier or same as the deadline supplied by the user.
6.5.2. Design Considerations
Aspect: How find
command is parsed
Alternative 1: Have a separate FindCommandParser
to parse the command (current implementation)
Alternative 2: Let PocketProjectParser
handle parsing of all the find
commands
Using Alternative 1 is better because it provides better abstraction as the details of the 5 different find commands will be hidden away as just a single FindCommand.
Hence it is more in line with OOP principles. There will also be less clutter in PocketProjectParser
as there are already a lot of other commands being parsed.
6.6. List Employee/Project feature
6.6.1. Current implementation
For the current list feature, there are 2 main commands that the user can execute:
-
list employee
- displays all employees -
list project
- displays all projects
The ListCommandParser
will parse the user input based on the COMMAND_KEYWORD
entered by the user, and then execute the appropriate command based on the keyword given.
The following sequence diagram shows how the list employee command works:
list employee
commandUsage Scenario example for list employee
:
-
User executes
list employee
to list all employees in PocketProject. -
PocketProjectParser
will parse and identify the command as aListCommand
and pass the argument employee toListCommandParser
. -
ListCommandParser
identifies the command to execute based on theCOMMAND_KEYWORD
and returns aListEmployeeCommand
. -
LogicManager
then executesListEmployeeCommand
. All the employees in PocketProject will be returned by thefilteredEmployees
list.
The mechanism for list project
is similar to list employee
, apart from the fact that a ListProjectCommand
is executed instead.
6.6.2. Design Considerations
Aspect: How list command
is parsed
Alternative 1: Have a separate command parser for all list
commands (current implementation)
Alternative 2: Let PocketProjectParser
handle parsing of all the list
commands
Using Alternative 1 is better as it provides better abstraction as the listCommandParser
will handle all list
commands. It also reduces the cluttering in the main PocketProjectParser
.
6.7. Stats feature
6.7.1. Implementation
The displaying of statistics in Pocket Project will be facilitated by the model component. This feature is planned to support 2 main commands:
-
stats
— Displays an overview of all the projects: the number of ongoing projects, deadlines etc. -
stats PROJECT_INDEX
orstats PROJECT_NAME
— Display a summary of the progress of the project with the given PROJECT_INDEX or PROJECT_NAME.
The operation will be supported by the methods in the Model
interface: Model#overallStats()
and Model#individualStats(Project)
.
Model#overallStats()
will retrieve the data on all the projects/employees to pass to StatsUtil
, an utility class to produce a string which describes
the status of all projects. Model#individualStats(Project)
passes the given project to StatsUtil
to produce a string in a similar fashion.
The following sequence diagrams show how the stats command will work:
Overview of all projects:
stats
stats 1
Usage Scenario example for stats
:
-
User executes
stats
/stats PROJECT_INDEX
/stats PROJECT_NAME
to view project statistics in Pocket Project. -
PocketProjectParser
will parse and identify the command as aIndividualStatsCommand
orOverallStatsCommand
, parse any additional argument accordingly and return the command object. -
LogicManager
then executes the returned command, calling theModel#individualStats()
orModel#overallStats(Project)
accordingly to obtain the string describing the status of concern. -
The returned string is used to construct the result of the command.
6.7.2. Design Considerations
Aspect: How the string is constructed.
Alternative 1: Retrieve all the relevant project(s), find out the relevant information and construct the string in the execute()
method
of the command object.
Alternative 2: Do the construction in the model.
Alternative 3: Do it somewhere else.
I have decided to use alternative 3 and create a specialized helper class to scrap the relevant information from the list of projects/employees to produce the string. This is chosen because I have decided to have several helper methods to construct the different parts of the string(e.g. about the number of ongoing projects, project with closest deadline etc..). It would be inappropriate to put these methods under the command class or the model because they are not very related.
6.8. User Story feature
6.8.1. General Implementation
The implementation of user stories in Pocket Project is facilitated by the model
component, and in particular, the Project
class
which will store the relevant user stories as a SortedUserStoryList
.
Currently, the user stories feature supports the following commands:
-
addto PROJECT_NAME userstory i/STORY_IMPORTANCE STORY
— Adds the user story specified inSTORY
to the list of user stories in the project with namePROJECT_NAME
-
removefrom PROJECT_NAME userstory STORY_INDEX
— Removes the user story at indexSTORY_INDEX
in the list of user stories in the project namedPROJECT_NAME
. -
edit project PROJECT_NAME userstory STORY_INDEX STORY
— Edits the user story at indexSTORY_INDEX
in the list of user stories in the project namedPROJECT_NAME
. -
update PROJECT_NAME userstory STORY_INDEX STATUS
— Updates the status of the user story at theSTORY_INDEX
in the list of user stories in the project namedPROJECT_NAME
.
In addition, the SortedUserStoryList
maintains a sorted order of user stories according to descending importance level of the user story, followed by ascending lexicographical order of the UserStoryUser
name.
For example, suppose we have 3 user stories with the following importance level and user names:
Importance |
User name |
1 |
John |
2 |
David |
2 |
Alan |
In the SortedUserStoryList
these user stories would appear in the following order and index:
Index |
Importance |
User name |
1 |
2 |
Alan |
2 |
2 |
David |
3 |
1 |
John |
Since the user stories with users David and Alan have a higher importance level than John, they will appear above John in the sorted list. Afterwards, since Alan is lexicographically smaller than David, it appears before David in the list.
This is to faciliate users to find important user stories by ensuring a neatly ordered list by relevance of the user story.
6.8.2. Implementation of individual commands
Add user story to project command
-
addto PROJECT_NAME userstory i/STORY_IMPORTANCE STORY
— adds the user story specified inSTORY
to the list of user stories in the project with namePROJECT_NAME
This operation uses the Model#addUserStoryTo(Project, UserStory)
and the Model#getProjectWithName(Name)
methods in the Model
interface.
It takes in the project and user story as arguments. After checking that the PROJECT_NAME
is valid and STORY
is created, the AddUserStoryToCommand#execute()
method is executed to add the STORY
into the project.
Given below is an example usage scenario and how the addition of user story to a project behaves at each step.
Step 1. The user enters the command list project
. The app displays the list of projects in the Pocket Project by executing the list project
command.
Step 2. The user enters addto Apollo userstory i/1 as a user i want to view user stories so that i can track them
. The LogicManager
passes the string into the PocketProjectParser
which detects it as a AddToCommand
. It then passes the string to the AddToCommandParser
which creates an AddUserStoryTo
command. The LogicManager
then checks for the validity of the user story and executes the Model#addUserStoryTo(Project, UserStory)
method to add the new user story.
The |
Remove user story from project command
-
removefrom PROJECT_NAME userstory STORY_INDEX
— removes the user story at indexSTORY_INDEX
in the list of user stories in the project namedPROJECT_NAME
.
This operation uses the Model#removeUserStoryFrom(Project, UserStory)
and the Model#getProjectWithName(Name)
methods in the Model
interface.
It does not require the user story as an argument since the corresponding user story object can be found by the specified STORY_INDEX
. After checking that the PROJECT_NAME
and user story is valid, the AddUserStoryToCommand#execute()
method is executed to remove the user story from the project.
The sequence diagram for the execution of the removing of a user story from a project is as follows:
removefrom Apollo userstory 1
.Given below is an example usage scenario and how the removal of a user story behaves at each step.
Step 1. The user enters the command view project Apollo'. The app displays the list of details of the project named "Apollo" by executing the `view
command.
Step 2. The user can use the buttons in the details panel to scroll to the panel showing the user stories.
Step 3. The user enters removefrom Apollo userstory 1
. The LogicManager
passes the string into the PocketProjectParser
which detects it as a RemoveFromCommand
.
It then passes the string to the RemoveFromCommandParser
which creates an RemoveUserStoryFrom
command. The LogicManager
then checks for the validity of the user
story and project and executes the Model#removeUserStoryFrom(Project, UserStory)
method to remove the user story.
The |
Edit user story command
-
edit project PROJECT_NAME userstory STORY_INDEX
— edits the user story at indexSTORY_INDEX
in the list of user stories in the project namedPROJECT_NAME
.
This operation uses the Project#setUserStory(UserStory, UserStory)
method in the Project
class as well as the Model#getProjectWithName(Name)
method in the Model
class. It takes
in as arguments firstly, the old user story to edit, and secondly the new user story to replace it with. The EditProjectUserStoryCommand
checks for the validity of the old and new user stories
before the Project#setUserStory(UserStory, UserStory)
method is called.
The sequence diagram for the execution of the editing of a user story in a project is as follows:
edit project Apollo userstory 1 as a user I want to login
.Given below is an example usage scenario and how the editing of a user story behaves at each step.
Step 1. The user enters the command view project Apollo
. The app displays the list of details of the project named "Apollo" by executing the view
command.
Step 2. The user can use the buttons in the details panel to scroll to the panel showing the user stories.
Step 3. The user enters edit project Apollo userstory 1 as a user i want to login
. The LogicManager
passes the string into the PocketProjectParser
which detects it as a EditCommand
.
It then passes the string to the EditCommandParser
. The EditCommandParser
detects the keyword project
and passes the string to the EditProjectCommandParser
which creates a EditUserStory
command. The LogicManager
then checks for the validity of the user
story and project and edits the user story using the Project#setUserStory(UserStory, UserStory)
method.
The |
Update user story command
-
update PROJECT_NAME userstory STORY_INDEX STATUS
— Updates the status of the user story at theSTORY_INDEX
in the list of user stories in the project namedPROJECT_NAME
.
This operation uses the UserStory#UpdateStatus(Status)
method in the UserStory
class as well as the Model#getProjectWithName(Name)
method in the Model
class.
It takes in as arguments the new status of the user story. The UpdateUserStoryCommand
checks for the validity of the arguments and locates the specified user story from the project. It then calls the UserStory#UpdateStatus(status)
method.
The sequence diagram for the execution of updating a user story status is as follows:
update Apollo userstory 1 ongoing
.Given below is an example usage scenario of how the updating of a user story behaves at each step.
Step 1. The user enters the command view project Apollo
. The app displays the list of details of the project named "Apollo" by executing the view
command.
Step 2. The user can use the buttons in the details panel to scroll to the panel showing the user stories.
Step 3. The user enters update Apollo userstory 1 ongoing
. The LogicManager
passes the string to the PocketProjectParser
which detects the string as a UpdateCommand
. The PocketProjectParser
passes the rest of the string to the UpdateCommandParser
.
The UpdateCommandParser
then detects the keyword userstory
and creates a UpdateUserStory
command object and passes it to the LogicManager
to be executed. The LogicManager
then checks for the validity of the user story and project and updates the user story’s status using the UserStory#UpdateStatus(Status)
method.
The |
6.8.3. Design Considerations
Aspect: How to structure the user story details to be inputted into the project
Alternative 1: Use a regex
to indicate the importance/priority of a user story, then have the user key in the user story in the specified format as a…i want to…so that…
(Current implementation)
Alternative 2: Use only regex
to denote the different parts of a user story. For example, i/
to denote the importance level, u/
to denote user etc…
Alternative 3: Store the entire string as given by the user as it is and not parse the input.
Using alternative 3 is the simplest and most straight forward way to handle the user input, but it does not provide much functionality. As user stories should be organised and easy to read as a list,
we will need to use some sort of TableView
or ListView
to view the stories. Thus, using alternative 3 will only allow the entire string to be generated and is not user friendly.
Between alternative 2 and alternative 1, alternative 2 provides an easier way for the program to generate and partition the input using regex
expressions. However, as there are many parts to a user
story, having to remember 4 different regex
expressions may be hard for a user to remember and may be inconvenient. Using alternative 1 is a mix of both 2 and 3, which allows abit more flexibility
and smoothness for a user by allowing them to type in full sentences how they would normally do for a user story, while allowing proper classification of the components of the story to be able to
be displayed in the UI component as a TableView
.
Aspect: How to show/store the list of user stories
Alternative 1: Sort the user stories only by decreasing priority.
Alternative 2: Sort the user stories by the sequence it is added.
Alternative 3: Sort the user stories only by the names of the target user.
Alternative 4: Sort the user stories by decreasing priority, followed by the name of the target user. (Current implementation)
Using alternative 2 is the simplest and most straightforward approach, but does not provide any value adding to the user. Both alternative 1 and 3 are useful, hence we decided to combine them to produce alternative 4, which allows not only the important user stories to be listed first, but also provides better readability as similar user stories are grouped together.
6.8.4. Future Planned Enhancements
The following additional features are scheduled to be implemented in future version.
-
Allow more varied types of sorting for the users. Since there is no one-size-fit-all solution when deciding which user stories are more relevant, the user should be able to decide how he/she wants them arranged. Hence this proposed feature will allow users to be able to click the user stories table and customise the order in which user stories are shown.
-
Provide even greater flexibility when parsing user stories. Currently, user stories require specific keywords
as a
,i want to
,so that
. In future, users should be able to type sentences naturally and it can still be parsed. This will be made available by widening the range of keywords the parser is able to detect as well as the different sentence structures possible.
6.9. Project Task feature
6.9.1. Current Implementation
This project task feature enhances the usage of the milestone feature in Pocket Project for keeping track of a project’s schedule by providing you with a list of tasks which needs to be done between milestones.
The project task feature is mainly facilitated
by the model component, and in particular, the Milestone
class which stores the relevant project tasks in a UniqueProjectTaskList
.
This feature supports three main commands:
-
addto [project name] projecttask n/PROJECT_TASK_DESCRIPTION m/MILESTONE_INDEX
— Adds the project task with the given[PROJECT_TASK_DESCRIPTION]
to the milestone specified by[milestone index]
in the project named[project name]
. -
removefrom [project name] projecttask [milestone index] [project task index]
— Removes the project task at the specified[project task index]
from the milestone specified by[milestone index]
in the project with name[proejct name]
. -
update [project name] projecttask [milestone index] [project task index] [status]
— Updates the status of the project task at the specified[project task index]
in the milestone specified by[milestone index]
in the project with name[project name]
.
Project tasks contain statuses to help you oversee its progress, whether its "Ongoing", "On hold" or "Complete".
6.9.2. Implementation of project task commands
The project task commands are supported by the methods in the Model
interface: Model#addProjectTaskTo(Project, Milestone, ProjectTask)
, Model#removeProjectTaskFrom(Project, Milestone, ProjectTask)
and Model#updateProjectTask(Project, Milestone, ProjectTask, Status)
.
These three methods take in Project
, Milestone
and ProjectTask
as common arguments. Hence, the correct project/milestone/project task which the commands act on are first located through
AddProjectTaskToCommand#excute()
, RemoveProjectTaskFromCommand#execute()
or UpdateProjectTaskCommand#execute()
before the methods of Model
acting on the milestone/project task are called.
Update status of project task
Given below is an example usage scenario and a showcase of how a project task status is updated in a project’s milestone at each step.
-
update [project name] projecttask [milestone index] [project task index] [status]
— Updates the status of the project task at the specified[project task index]
in the milestone specified by[milestone index]
in the project with name[project name]
.
The sequence diagram for the execution of updating a project task status is as follows:
update Apollo projecttask 2 1 Complete
Step 1. The user enters the command update Apollo projecttask 2 1 Complete
.
The LogicManager
then passes the entered string to the PocketProjectParser
. The PocketProjectParser
parses the string received and identifies the command as falling under the class of UpdateCommand
and passes the rest of the string to the UpdateCommandParser
to identify which type of UpdateCommand
is being executed and what are the arguments.
Step 2. The UpdateCommandParser
then identifies the "projecttask" keyword and creates an UpdateProjectTaskCommand
and passes it to the LogicManager
to be executed.
Step 3. On execution of the command, the validity of the arguments are checked and then call the methods of the Model
component to locate and obtain the necessary objects.
Step 4. The Model
component then searches for the project with name Apollo
. After which, it searches for the milestone at index 2 of the project’s milestone list. Then, it retrieves the specified project task at index 1 in the milestone’s project task list.
In each of these 3 searches for the specified object, after the object is found, it is returned to the UpdateProjectTaskCommand
object and used for the next search.
Step 5. The update status method of the retrieved task is then called with "Complete" as an argument. This updates the project task status to "Complete" and execution of the UpdateProjectTaskCommand
ends.
The |
6.9.3. Design Considerations
In this section, I will talk about certain alternatives that could have been taken when designing this feature and why I did or did not use them.
Aspect: How should project task objects be stored within a project
Alternative 1: Store project tasks in a UniqueProjectTaskList
which is in turn stored under a specified milestone. (Current implementation)
-
Pros: Only milestone objects are in direct contact with the project tasks through the
UniqueProjectTaskList
container class and checks to ensure project tasks work as they should only need to be done within the milestone instead of in the entire project itself. -
Cons: Somewhat harder to implement as it requires finding the correct milestone in a project first before anything can be done for the project task specified in the user’s command.
Alternative 2: Store project tasks directly in a project and keep a reference to the milestone which it should be under.
-
Pros: Easy to implement and will have similar behaviour to existing implementations of other objects stored directly in a project.
-
Cons: It can be confusing in the backend as the user can have tasks under different milestones with the same project task descriptions. This also goes against the Object-Oriented Programming(OOP) Guideline, Law of Demeter as project tasks only need to be in direct contact with milestones but not necessarily with projects themselves.
Based on the above pros and cons for each alternative, I decided on Alternative 1 for 2 reasons:
-
As it was in line with the OOP guidelines and principle.
-
As it allowed me to implement a more robust and efficient checking system for project tasks which was constrained within a milestone itself.
6.9.4. Future planned enhancements
The following features are scheduled to be implemented in a future version of Pocket Project:
-
Allow the assigning of project tasks to employees in a project which gives you a better overview of who is in charge of doing what task during the project’s duration.
-
Include the completion date of a project task when it is completed, allowing you to backtrack from the completion date of the project task to see what was done for the project task’s completion.
6.10. Undo/Redo feature
6.10.1. Current Implementation
The undo/redo mechanism is facilitated by VersionedPocketProject
.
It extends PocketProject
with an undo/redo history, stored internally as an pocketProjectStateList
and currentStatePointer
.
Additionally, it implements the following operations:
-
VersionedPocketProject#commit()
— Saves the current pocket project state in its history. -
VersionedPocketProject#undo()
— Restores the previous pocket project state from its history. -
VersionedPocketProject#redo()
— Restores a previously undone pocket project state from its history.
These operations are exposed in the Model
interface as Model#commitPocketProject()
, Model#undoPocketProject()
and Model#redoPocketProject()
respectively.
Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
Step 1. The user launches the application for the first time. The VersionedPocketProject
will be initialized with the initial pocket project state, and the currentStatePointer
pointing to that single pocket project state.
Step 2. The user executes delete 5
command to delete the 5th employee in the pocket project. The delete
command calls Model#commitPocketProject()
, causing the modified state of the pocket project after the delete 5
command executes to be saved in the pocketProjectStateList
, and the currentStatePointer
is shifted to the newly inserted pocket project state.
Step 3. The user executes add n/David …
to add a new employee. The add
command also calls Model#commitPocketProject()
, causing another modified pocket project state to be saved into the pocketProjectStateList
.
If a command fails its execution, it will not call Model#commitPocketProject() , so the pocket project state will not be saved into the pocketProjectStateList .
|
Step 4. The user now decides that adding the employee was a mistake, and decides to undo that action by executing the undo
command. The undo
command will call Model#undoPocketProject()
, which will shift the currentStatePointer
once to the left, pointing it to the previous Pocket Project state, and restores the Pocket Project to that state.
If the currentStatePointer is at index 0, pointing to the initial Pocket Project state, then there are no previous Pocket Project states to restore. The undo command uses Model#canUndoPocketProject() to check if this is the case. If so, it will return an error to the user rather than attempting to perform the undo.
|
The following sequence diagram shows how the undo operation works:
The redo
command does the opposite — it calls Model#redoPocketProject()
, which shifts the currentStatePointer
once to the right, pointing to the previously undone state, and restores the Pocket Project to that state.
If the currentStatePointer is at index pocketProjectStateList.size() - 1 , pointing to the latest Pocket Project state, then there are no undone Pocket Project states to restore. The redo command uses Model#canRedoPocketProject() to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
|
Step 5. The user then decides to execute the command list
. Commands that do not modify the Pocket Project, such as list
, will usually not call Model#commitPocketProject()
, Model#undoPocketProject()
or Model#redoPocketProject()
. Thus, the pocketProjectStateList
remains unchanged.
Step 6. The user executes clear
, which calls Model#commitPocketProject()
. Since the currentStatePointer
is not pointing at the end of the pocketProjectStateList
, all pocket project states after the currentStatePointer
will be purged. We designed it this way because it no longer makes sense to redo the add n/David …
command. This is the behavior that most modern desktop applications follow.
The following activity diagram summarizes what happens when a user executes a new command:
6.10.2. Design Considerations
Aspect: How undo & redo executes
-
Alternative 1 (current choice): Saves the entire Pocket Project.
-
Pros: Easy to implement.
-
Cons: May have performance issues in terms of memory usage.
-
-
Alternative 2: Individual command knows how to undo/redo by itself.
-
Pros: Will use less memory (e.g. for
delete
, just save the employee being deleted). -
Cons: We must ensure that the implementation of each individual command are correct.
-
Aspect: Data structure to support the undo/redo commands
-
Alternative 1 (current choice): Use a list to store the history of Pocket Project states.
-
Pros: Easy for new Computer Science student undergraduates to understand, who are likely to be the new incoming developers of our project.
-
Cons: Logic is duplicated twice. For example, when a new command is executed, we must remember to update both
HistoryManager
andVersionedPocketProject
.
-
-
Alternative 2: Use
HistoryManager
for undo/redo-
Pros: We do not need to maintain a separate list, and just reuse what is already in the codebase.
-
Cons: Requires dealing with commands that have already been undone: We must remember to skip these commands. Violates Single Responsibility Principle and Separation of Concerns as
HistoryManager
now needs to do two different things.
-
6.11. [Proposed] Data Encryption
{Explain here how the data encryption feature will be implemented}
6.12. 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.13, “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.13. Configuration
Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json
).
7. Documentation
We use asciidoc for writing documentation.
We chose asciidoc over Markdown because asciidoc, although a bit more complex than Markdown, provides more flexibility in formatting. |
7.1. Editing Documentation
See UsingGradle.adoc to learn how to render .adoc
files locally to preview the end result of your edits.
Alternatively, you can download the AsciiDoc plugin for IntelliJ, which allows you to preview the changes you have made to your .adoc
files in real-time.
7.2. Publishing Documentation
See UsingTravis.adoc to learn how to deploy GitHub Pages using Travis.
7.3. Converting Documentation to PDF format
We use Google Chrome for converting documentation to PDF format, as Chrome’s PDF engine preserves hyperlinks used in webpages.
Here are the steps to convert the project documentation files to PDF format.
-
Follow the instructions in UsingGradle.adoc to convert the AsciiDoc files in the
docs/
directory to HTML format. -
Go to your generated HTML files in the
build/docs
folder, right click on them and selectOpen with
→Google Chrome
. -
Within Chrome, click on the
Print
option in Chrome’s menu. -
Set the destination to
Save as PDF
, then clickSave
to save a copy of the file in PDF format. For best results, use the settings indicated in the screenshot below.
7.4. Site-wide Documentation Settings
The build.gradle
file specifies some project-specific asciidoc attributes which affects how all documentation files within this project are rendered.
Attributes left unset in the build.gradle file will use their default value, if any.
|
Attribute name | Description | Default value |
---|---|---|
|
The name of the website. If set, the name will be displayed near the top of the page. |
not set |
|
URL to the site’s repository on GitHub. Setting this will add a "View on GitHub" link in the navigation bar. |
not set |
|
Define this attribute if the project is an official SE-EDU project. This will render the SE-EDU navigation bar at the top of the page, and add some SE-EDU-specific navigation items. |
not set |
7.5. Per-file Documentation Settings
Each .adoc
file may also specify some file-specific asciidoc attributes which affects how the file is rendered.
Asciidoctor’s built-in attributes may be specified and used as well.
Attributes left unset in .adoc files will use their default value, if any.
|
Attribute name | Description | Default value |
---|---|---|
|
Site section that the document belongs to.
This will cause the associated item in the navigation bar to be highlighted.
One of: * Official SE-EDU projects only |
not set |
|
Set this attribute to remove the site navigation bar. |
not set |
7.6. Site Template
The files in docs/stylesheets
are the CSS stylesheets of the site.
You can modify them to change some properties of the site’s design.
The files in docs/templates
controls the rendering of .adoc
files into HTML5.
These template files are written in a mixture of Ruby and Slim.
Modifying the template files in |
8. Testing
8.1. Running Tests
There are three ways to run tests.
The most reliable way to run tests is the 3rd one. The first two methods might fail some GUI tests due to platform/resolution-specific idiosyncrasies. |
Method 1: Using IntelliJ JUnit test runner
-
To run all tests, right-click on the
src/test/java
folder and chooseRun 'All Tests'
-
To run a subset of tests, you can right-click on a test package, test class, or a test and choose
Run 'ABC'
Method 2: Using Gradle
-
Open a console and run the command
gradlew clean allTests
(Mac/Linux:./gradlew clean allTests
)
See UsingGradle.adoc for more info on how to run tests using Gradle. |
Method 3: Using Gradle (headless)
Thanks to the TestFX library we use, our GUI tests can be run in the headless mode. In the headless mode, GUI tests do not show up on the screen. That means the developer can do other things on the Computer while the tests are running.
To run tests in headless mode, open a console and run the command gradlew clean headless allTests
(Mac/Linux: ./gradlew clean headless allTests
)
8.2. Types of tests
We have two types of tests:
-
GUI Tests - These are tests involving the GUI. They include,
-
System Tests that test the entire App by simulating user actions on the GUI. These are in the
systemtests
package. -
Unit tests that test the individual components. These are in
seedu.address.ui
package.
-
-
Non-GUI Tests - These are tests not involving the GUI. They include,
-
Unit tests targeting the lowest level methods/classes.
e.g.seedu.address.commons.StringUtilTest
-
Integration tests that are checking the integration of multiple code units (those code units are assumed to be working).
e.g.seedu.address.storage.StorageManagerTest
-
Hybrids of unit and integration tests. These test are checking multiple code units as well as how the are connected together.
e.g.seedu.address.logic.LogicManagerTest
-
8.3. Troubleshooting Testing
Problem: HelpWindowTest
fails with a NullPointerException
.
-
Reason: One of its dependencies,
HelpWindow.html
insrc/main/resources/docs
is missing. -
Solution: Execute Gradle task
processResources
.
9. Dev Ops
9.1. Build Automation
See UsingGradle.adoc to learn how to use Gradle for build automation.
9.2. Continuous Integration
We use Travis CI and AppVeyor to perform Continuous Integration on our projects. See UsingTravis.adoc and UsingAppVeyor.adoc for more details.
9.3. Coverage Reporting
We use Coveralls to track the code coverage of our projects. See UsingCoveralls.adoc for more details.
9.4. Documentation Previews
When a pull request has changes to asciidoc files, you can use Netlify to see a preview of how the HTML version of those asciidoc files will look like when the pull request is merged. See UsingNetlify.adoc for more details.
9.5. Making a Release
Here are the steps to create a new release.
-
Update the version number in
MainApp.java
. -
Generate a JAR file using Gradle.
-
Tag the repo with the version number. e.g.
v0.1
-
Create a new release using GitHub and upload the JAR file you created.
9.6. Managing Dependencies
A project often depends on third-party libraries. For example, Pocket Project depends on the Jackson library for JSON parsing. Managing these dependencies can be automated using Gradle. For example, Gradle can download the dependencies automatically, which is better than these alternatives:
-
Include those libraries in the repo (this bloats the repo size)
-
Require developers to download those libraries manually (this creates extra work for developers)
10. FAQ
Q: How do I transfer my data to another Computer?
A: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous Pocket Project folder.
Appendix A: Product Scope
Target user profile:
-
has a need to manage a significant number of employees and software engineering projects
-
prefer desktop apps over other types
-
can type fast
-
prefers typing over mouse input
-
is reasonably comfortable using CLI apps
Value proposition: manage employees and projects faster than a typical mouse/GUI driven application which enhances administrative procedures and improves efficiency.
Appendix B: User Stories
Priorities: High (must have) - * * *
, Medium (good to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
First-Time User Related Stories |
|||
|
first-time user |
see the usages of different instructions |
refer to it if I forget the format and purpose of different commands |
|
first-time user |
be able to read a detailed but simple the user guide |
easily understand how to use the features of the application |
|
first-time user |
see a list of available instructions |
navigate and use the application effectively by knowing what commands are available to me |
|
first-time user |
clear the application and remove all data |
trial the very various features and reset the application after |
General User Related Stories |
|||
|
general user |
have a help function |
refer to it if I forget the format and purpose of different features and commands |
|
general user |
to be able to undo/revert my commands |
quickly revert back and forth any of my latest commands |
|
general user |
to be able to have flexibility when keying in dates |
can improve speed and efficiency. |
Project Manager Related Stories |
|||
|
project manager |
be able to add/delete employees in the application |
keep track of any new employees and remove employees who have left |
|
project manager |
be able to view personal details such as contact number and email of my employees in the application |
easily retrieve certain information that would be useful in handling administrative matters. |
|
project manager |
be able to add/delete projects in the application |
keep track of any new projects and remove unnecessary entries |
|
project manager |
be able to view details of the project such as description and client in the application |
easily view important project details that would be useful in handling administrative matters. |
|
project manager |
see all the current ongoing projects listed by deadline |
keep track of which projects require immediate attention |
|
project manager |
assign employees to project |
keep track of all employees working on particular project |
|
project manager |
keep track of all projects a particular employee is working on |
better allocate or re-allocate any workload to achieve better balance |
|
project manager |
be able to find a particular employee/project |
quickly refer or retrieve details of a particular employee/project |
|
project manager |
be able to edit a particular employee/project |
update or change details of a particular employee/project |
|
project manager |
be able to clear all the date in the application |
quickly reset and have an empty application should I change team or company |
|
project manager |
to be able to have flexibility when keying in dates |
can have greater efficiency in keying inputs and speed up administrative procedures. |
|
project manager |
see total number of projects listed as completed and ongoing |
keep track of how many projects have been successfully completed and the number of ongoing projects at a glance |
|
project manager |
sort the employees by total number of projects contributed |
keep track of each employees contribution to the company. |
|
project manager |
sort the employees by name |
find an employee more easily. |
|
project manager |
sort the project by name |
find a project more easily. |
|
project manager |
sort the project by deadline |
see which projects need to be more urgently completed. |
Software Engineering Project Manager Related Stories |
|||
|
Software engineering project manager |
add/delete skills/frameworks to an employee |
know what sort of background knowledge he has and what tasks he is suitable for. |
|
Software engineering project manager |
add/delete skills/frameworks to a project |
know what are the relevant skills required to complete a particular project. |
|
Software engineering project manager |
find all employees that have a certain skill |
assign the right people with the required skills to the right projects |
|
Software engineering project manager |
add/delete milestones to a project |
keep track of major completion points during the course of the project |
|
Software engineering project manager |
add/delete tasks to a milestone |
keep track of all the tasks associated with a particular milestone |
|
Software engineering project manager |
add/delete user stories to a project |
formulate ideas and prioritize the features that need to be implemented. |
|
Software engineering project manager |
edit milestones in a project |
update any changes in my current milestone |
|
Software engineering project manager |
edit tasks in a milestone |
update any changes in my current tasks. |
|
Software engineering project manager |
edit user stories in a project |
update any changes in my current user stories |
Appendix C: Use Cases
(For all use cases below, the System is the PocketProject
and the Actor
is the user
, unless specified otherwise)
C.1. Use case: Delete Command
C.1.1. Deleting an employee
MSS
-
User requests to list employees
-
PocketProject shows a list of employees
-
User requests to delete a specific employee in the list
-
PocketProject deletes the employee
Use case ends.
Extensions
-
The list is empty.
Use case ends.
-
The given index is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
C.1.2. Deleting a project
MSS
-
User requests to list projects
-
PocketProject shows a list of projects
-
User requests to delete a specific project in the list
-
PocketProject deletes the project
Use case ends.
Extensions
-
The list is empty.
Use case ends.
-
The given index is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
-
The project name specified is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
C.2. Use case: Add Employee/Milestone/UserStory/Task To Project Command
C.2.1. Adding an employee to project
MSS
-
User requests to list employees
-
PocketProject shows a list of employees
-
User requests to add a specific employee in the list to the project
-
PocketProject adds the employee to the project specified.
Use case ends.
Extensions
-
The list is empty.
Use case ends.
-
The given index is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
-
The project name given is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
-
The employee is already in the project.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
C.2.2. Adding a milestone to a project
MSS
-
User requests to add a milestone to the project
-
PocketProject adds the milestone to the project specified.
Use case ends.
Extensions
-
The milestone to be added is already specified in the project.
-
PocketProject shows an error message.
Use case ends.
-
C.2.3. Adding a task to a milestone in a project
MSS
-
User requests to add a project task to the project
-
PocketProject adds the project task to the project specified.
Use case ends.
Extensions
-
The project task to be added is already specified in the project.
-
PocketProject shows an error message.
Use case ends.
-
C.2.4. Adding an user story to a project
MSS
-
User requests to add a user story to the project
-
PocketProject adds the user story to the project specified.
Use case ends.
Extensions
-
The user story to be added is already specified in the project.
-
PocketProject shows an error message.
Use case ends.
-
C.3. Use case: Remove Employee/Milestone/UserStory/Task From Project Command
C.3.1. Removing an employee from a project
MSS
-
User requests to view employees in a project
-
PocketProject shows a list of employees in the project
-
User requests to delete a specific employee in the list
-
PocketProject deletes the employee from the project
Use case ends.
Extensions
-
The list is empty.
Use case ends.
-
The given index is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
-
The project name given is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
C.3.2. Removing a milestone from a project
MSS
-
User requests to view milestones in a project
-
PocketProject shows a list of milestones in the project
-
User requests to delete a specific milestone in the list
-
PocketProject deletes the milestone from the project
Use case ends.
Extensions
-
The list is empty.
Use case ends.
-
The given index is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
-
The project name given is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
C.3.3. Removing a project task from a milestone in a project
MSS
-
User requests to view project tasks in a project
-
PocketProject shows a list of project tasks in the project in the specific milestone
-
User requests to delete a specific task in the list
-
PocketProject deletes the task from the project
Use case ends.
Extensions
-
The list is empty.
Use case ends.
-
The given milestone index is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
-
The project name given is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
C.3.4. Removing an user story from a project
MSS
-
User requests to view user stories in a project
-
PocketProject shows a list of user stories in the project
-
User requests to delete a specific user story in the list
-
PocketProject deletes the user story from the project
Use case ends.
Extensions
-
The list is empty.
Use case ends.
-
The given index is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
-
The project name given is invalid.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
C.4. Use case: Edit Command
C.4.1. Editing an employee’s details
MSS
-
User requests to view an employee in a project
-
PocketProject shows the employee details
-
User requests to edit an employee details
-
PocketProject edits the employee’s details
Use case ends.
Extensions
-
The new employee has the exact same details as another employee.
-
PocketProject shows an error message.
Use case resumes at step 2.
-
C.5. Use case: Find Command
C.5.1. Finding all keywords in project
MSS
-
User requests to find all occurences of a keyword in a project
-
PocketProject returns any project found with the keyword specified
Use case ends.
Appendix D: Non Functional Requirements
-
Should work on any mainstream OS as long as it has Java
9
or higher installed. -
Should be able to hold up to 1000 employees without a noticeable sluggishness in performance for typical usage.
-
Should be user-friendly for software engineering project managers and should help them manage their projects more efficiently and effectively.
-
Should have automated tests to do regression testing whenever an existing feature is enhanced or a new feature is added.
-
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.
-
The system should respond to user input within 2 seconds, whether it is valid or invalid input.
11. Instructions for Manual Testing
Given below are instructions to test the app manually.
These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing. |
11.1. Launch and Shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file
Expected: Shows the GUI with a set of sample employees and projects. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to a different location. Close the window.
-
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-
{ more test cases … }
11.2. Add Command
11.2.1. Adding an employee
Assuming that the employees added here do not exist in the app beforehand.
-
Test case:
add employee n/John p/12345678 e/a@gmail.com g/abc.com
Expected: An employee named 'John', with phone number '12345678', email 'a@gmail.com' and github address 'abc.com' is added. -
Test case:
add employee n/John p/12a345678 e/a@gmail.com g/abc.com
Expected: Adding of employees fails. Message about phone numbers can only contain numbers is returned. -
Test case:
add employee n/Peter p/12345678 e/a@gmail.com g/abc.com
twice in a row
Expected: The second addition fails because the employee already exists. -
Test case:
add employee n/Jack p/12345678 e/a.gmail.com g/abc.com
Expected: Addition failed because of lack of '@' in the given email.
11.3. Adding a project
-
Adding a new project
-
Prerequisite: Project list doesn’t already contain a project named 'Apollo'.
-
Test case:
add project n/Apollo c/SymbCorp d/23/11/2020
Expected: A new project is added to the list. Details of the added project shown in the status message. Timestamp in the status bar is updated. -
Test case:
add project n/Ap.ollo c/SymbCorp d/23/11/2020
Expected: No new project is added. Invalid project name error details shown in the status message. Status bar remains the same. -
Test case:
add project n/Apollo c/Symb.Corp d/23/11/2020
Expected: No new project is added. Invalid client name error details shown in the status message. Status bar remains the same. -
Test case:
add project n/Apollo c/SymbCorp d/30/02/2020
Expected: No new project is added. Invalid date error details shown in the status message. Status bar remains the same. -
Test case:
add project c/SymbCorp d/23/11/2020
Expected: No new project is added. Invalid command format error details shown in the status message. Status bar remains the same. -
Test case:
add project n/Apollo d/23/11/2020
Expected: No new project is added. Invalid command format error details shown in the status message. Status bar remains the same. -
Test case:
add project n/Apollo c/SymbCorp
Expected: No new project is added. Invalid command format error details shown in the status message. Status bar remains the same.
-
-
Adding a new project that has at most 1 field different from an existing project.
-
Prerequisite: This test case assumes that the command
add project n/Apollo c/SymbCorp d/23/11/2020
has been entered successfully at least once before. -
Test case:
add project n/Apollo c/SymbCorp d/23/11/2020
Expected: No new project is added. Duplicate project error details shown in status message. Status bar remains the same. -
Test case:
add project n/Apollo1 c/SymbCorp d/23/11/2020
Expected: A new project is added to the list. Details of the added project shown in the status message. Timestamp in the status bar is updated. -
Test case:
add project n/Apollo c/SymbCorp1 d/23/11/2020
Expected: No new project is added. Duplicate project error details shown in status message. Status bar remains the same. -
Test case:
add project n/Apollo c/SymbCorp d/10/11/2020
Expected: No new project is added. Duplicate project error details shown in status message. Status bar remains the same.
-
11.4. Adding a milestone
-
Adding a milestone to a project
-
Prerequisite: The project list contains a project with name 'Apollo' but not a project with name 'Not Found'. 'Apollo' doesn’t already contain milestones with names 'Finished UserGuide' and 'Finished DevGuide'.
-
Test case:
addto Apollo milestone Finished UserGuide 23/04/2019
Expected: A new milestone is added to 'Apollo'. Details of the added milestone shown in the status message. Timestamp in the status bar is updated. -
Test case:
addto Not Found milestone Finished UserGuide 23/04/2019
Expected: No new milestone is added. Invalid project name error details shown in status message. Status bar remains the same. -
Test case:
addto Apollo milestone 23/04/2019
Expected: No new milestone is added. Invalid command format error details shown in status message. Status bar remains the same. -
Test case:
addto Apollo milestone Finished UserGuide 234/04/2019
Expected: No new milestone is added. Invalid command format error details shown in status message. Status bar remains the same.
-
-
Adding a new milestone that has at most 1 field different from an existing milestone in a project.
-
Prerequisite: This test case assumes that the command
addto Apollo milestone Finished UserGuide 23/04/2019
has been entered successfully at least once before. -
Test case:
addto Apollo milestone Finished UserGuide 23/04/2019
Expected: No new milestone is added. Duplicate milestone error details shown in status message. Status bar remains the same. -
Test case:
addto Apollo milestone Finished DevGuide 23/04/2019
Expected: A new milestone is added to 'Apollo'. Details of the added milestone shown in the status message. Timestamp in the status bar is updated. -
Test case:
addto Apollo milestone Finished UserGuide 11/04/2019
Expected: A new milestone is added to 'Apollo'. Details of the added milestone shown in the status message. Timestamp in the status bar is updated.
-
11.5. Adding a project task
-
Adding a project task to a project’s milestone
-
Prerequisite: Project list has a project named 'Apollo' and has only 2 existing milestone in it.
-
Test case:
addto Apollo projecttask n/Create feature XYZ m/1
Expected: A new project task with description "Create feature XYZ" is added to the first milestone in project named 'Apollo'. Details of the added project task shown in status message. Timestamp in the status bar is updated. -
Test case:
addto Apollo projecttask n/Create feature XYZ m/2
Expected: A new project task with description "Create feature XYZ" is added to the second milestone in project named 'Apollo'. Details of the added project task shown in status message. Timestamp in the status bar is updated. -
Test case:
addto Apollo projecttask n/Create feature XYZ m/1
Expected: No new project task is added. Duplicate project task error details shown in status message. Status bar remains the same. -
Test case:
addto Apollo projecttask n/Create feature XYZ m/3
Expected: No new project task is added. Invalid milestone index error details shown in status message. Status bar remains the same. -
Test case:
addto Apollo projecttask n/Create feature XYZ
Expected: No new project task is added. Invalid command format error details shown in status message. Status bar remain the same. -
Test case:
addto Apollo projecttask m/1
Expected: No new project task is added. Invalid command format error details shown in status message. Status bar remain the same.
-
11.6. Adding a UserStory
-
Adding a new user story to a project
-
Prerequisites: The project list contains a project with name 'Apollo' but not a project with name 'Not Found'.
-
Test case:
addto Apollo userstory as a project manager i want to add employees into a project so that i can track which employees are in a project i/2
Expected: A new user story is added to 'Apollo'. Details of the added user story shown in the status message. Timestamp in the status bar is updated. -
Test case:
addto Apollo userstory as a project manager i want to add employees into a project so that i can track which employees are in a project i/4
Expected: No new user story is added. Invalid command format error details shown in status message. Status bar remains the same. -
Test case:
addto Project Apollo userstory as a project manager i want to add employees into a project so that track which employees are in a project
Expected: No new user story is added. Invalid command format error details shown in status message. Status bar remains the same.
-
11.7. Delete Command
11.7.1. Deleting an employee
Deleting a employee while all employees are listed
-
Prerequisites: List all employees using the
list
command. Multiple employees in the list. -
Test case:
delete employee 1
Expected: First employee is deleted from the list. Details of the deleted employee shown in the status message. Timestamp in the status bar is updated. -
Test case:
delete employee 0
Expected: No employee is deleted. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete employee
,delete employee y
, (where y is not a positive integer),delete employee x
, (where x is larger than the list size)
Expected: Similar to previous.
11.7.2. Deleting a project
Deleting a project while all projects are listed
-
Prerequisites: List all projects using the
list projects
command. Multiple projects in the list. -
Test case:
delete project 1
Expected: First project is deleted from the list. Details of the deleted project shown in the status message. Timestamp in the status bar is updated. -
Test case:
delete project p
Expected: project with the name 'p' is deleted if it exists in the app and the details of the deleted project shown in the status message. If no project with the name 'p' exists, error details shown in the status message. Status bar remains the same. -
Test case:
delete project 0
Expected: No project is deleted. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete
,delete x
(where x is larger than the list size or is negative)
Expected: Similar to previous.
11.8. Editing an employee
-
Assumption: Two addition of employee commands has been called on a blank pocket project:
add employee n/Peter p/12345678 e/a@gmail.com g/abc.com
+ andadd employee n/John p/87654321 e/b@gmail.com g/cba.com
. Peter is the first in the display list and John second.-
edit 1 n/Peter p/22345678 e/a@gmail.com g/abc.com
Expected: Command is executed successfully and the phone number of peter is changed. -
edit 1 n/John p/22345678 e/a@gmail.com g/abc.com
Expected: Command fails as John already exists. -
edit 3 n/Alice p/32345678 e/c@gmail.com g/ccc.com
Expected: Command fails as there is no employee at index 3.
-
11.9. Deleting a project
-
Deleting a project while all projects are listed
-
Prerequisites: List all projects using the
list projects
command. Multiple projects in the list. -
Test case:
delete project 1
Expected: First project is deleted from the list. Details of the deleted project shown in the status message. Timestamp in the status bar is updated. -
Test case:
delete project p
Expected: project with the name 'p' is deleted if it exists in the app and the details of the deleted project shown in the status message. If no project with the name 'p' exists, error details shown in the status message. Status bar remains the same. -
Test case:
delete project 0
Expected: No project is deleted. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete
,delete x
(where x is larger than the list size or is negative)
Expected: Similar to previous.
-
11.10. Removing an employee from a project
-
Prerequisites: Project with the name 'Apollo' exists and has 3 employees in it.
-
Test case:
removefrom Apollo employee 1
Expected: First employee in Apollo is removed from it. Details of the removed employee is shown in the status message and timestamp in the status bar is updated. -
Test case:
removefrom Apollo employee 4
Expected: No employee is removed. Error details shown in the status message. Status bar remains the same. -
Test case:
removefrom Apollo employee x
where x is not a positive integer
Expected: No employee is removed. Error details shown in the status message. Status bar remains the same. -
Test case:
removefrom X employee 1
where no project in the app has the name 'X'
Expected: No employee is removed. Error details shown in the status message. Status bar remains the same.
-
11.11. Removing a milestone from a project
-
Prerequisites: Project with name 'Apollo' exists and has 1 milestone in it.
-
Test case:
removefrom Apollo milestone 1
where the project named 'Apollo' exists in app and is ongoing and there is at least one
milestone for the project. Expected: The first milestone in the list of milestones for the project is removed. -
Test case:
remove from Apollo milestone 0
Expected: Command fails and an error message is returned. -
Test case:
remove from invalid milestone 1
where no project named 'invalid' exists
Expected: Command fails and an error message is returned.
11.12. Removing a project task from a project
-
Prerequisites: Project with name 'Apollo' exists and has only 1 milestone with only 1 project task in it.
-
Test case:
removefrom Apollo projecttask 1 1
Expected: The first project task of the first milestone in the milestones and tasks list is removed. Details of the removed project task is shown in the status message and the timestamp in the status bar is updated. -
Test case:
removefrom Apollo projecttask 1 2
Expected: No project task is removed. Invalid project task index error details shown in the status message. Status bar remains the same. -
Test case:
removefrom Apollo projecttask 2 1
Expected: No project task is removed. Invalid milestone index error details shown in the status message. Status bar remains the same. -
Test case:
removefrom Apollo projecttask 1
Expected: No project task is removed. Invalid command format error details shown in the status message. Status bar remains the same.
11.13. Updating status of a project task
-
Prerequisite: Project with name 'Apollo' exists and has only 1 milestone with at least 1 project task in it.
-
Test case:
update Apollo projecttask 1 1 complete
Expected: Status of the first project task in the first milestone displayed in 'Apollo' milestones and tasks list updated to complete. Project task updated success message is shown in status message and the timestamp in the status bar is updated. -
Test case:
update Apollo projecttask 1 1 on hold
Expected: Status of the first project task in the first milestone displayed in 'Apollo' milestones and tasks list updated to on hold. Project task updated success message is shown in status message and the timestamp in the status bar is updated. -
Test case:
update Apollo projecttask 1 1 ongoing
Expected: Status of the first project task in the first milestone displayed in 'Apollo' milestones and tasks list updated to ongoing. Project task updated success message is shown in status message and the timestamp in the status bar is updated. -
Test case:
update Apollo projecttask 1 1 invalid
Expected: Status of project task is not updated. Invalid command format error displayed in status message. Status bar remains the same. -
Test case:
update Apollo projecttask 1 complete
Expected: Status of project task is not updated. Invalid command format error displayed in status message. Status bar remains the same. -
Test case:
update Apollo projecttask 2 1 complete
Expected: Status of project task is not updated. Invalid milestone index format error displayed in status message. Status bar remains the same. -
Test case:
update Apollo projecttask 1 2 complete
Expected: Status of project task is not updated. Invalid project task index format error displayed in status message. Status bar remains the same.
11.14. Finding an employee/project by keywords in their names
-
Test case:
find project a b c
Expected: projects with 'a', 'b' or 'c' in their names as separate words would be listed -
Test case:
find employee x y z
Expected: employees with 'x', 'y' or 'z' in their names as separate words would be listed -
Test case
find abc
Expected: error will be returned
11.15. Finding employees with specific skills
-
Test case:
find skill java
Expected: All employees with the skill java will be listed -
Test case:
find abc java
Expected: error will be returned
11.16. Finding projects with specific keywords in their name, description or deadline
-
Test case:
find all software food
Expected: Returns a list of projects containing the word 'software' or 'food' or both in their name, description or deadline.
11.17. Indicating a project as completed
-
Test case:
complete 1 11/11/2011
where there this at least one project shown in the list of projects
Expected: The first project in the list is removed from the list of ongoing projects and indicated as completed. Timestamp shown in the status bar is updated. -
Test case:
complete x 11/11/2011
where x is not the index of a displayed project
Expected: Error detail shown. The Timestamp in the status bar is not updated.
11.18. Clearing all data from the app
-
Test case:
clear
Expected: All data of employees and projects are deleted from the app. -
Test case:
clear q23rfdq3w
Expected: All data cleared. The string of characters after the word clear is ignored. -
Test case:
clear
with leading and trailing whitespaces
Expected: Data still cleared. Leading and trailing spaces are ignored. -
Test case:
abc clear
Expected: Error message about unrecognized command is returned.
11.19. Exiting from the app
-
Test case:
exit
Expected: The window of the app should close. The effect is the same as clicking on the cross icon on the top right. -
Test case:
exit q23rfdq3w
Expected: The app ends. The string of characters after the word clear is ignored. -
Test case:
exit
with leading and trailing whitespaces
Expected: The app ends. Leading and trailing spaces are ignored. -
Test case:
abc exit
Expected: Error message about unrecognized command is returned.
11.20. Undoing a data modification
Assumption: all the objects being manipulated in these test cases exist in the app.
-
Test case:
delete employee 1
followed byundo
Expected: The first command will delete the first employee in the list from the app while the undo command will restore it. -
Test case:
delete employee 1
followed bylist employee
followed byundo
Expected: The first employee in the list is deleted by the delete command. The list command lists all the remaining employees. The undo command
restores the deleted employee. The undo command ignores the list command which does not modify internal data and will only undo the last data modifying command. -
Test case:
undo
is entered as the first command on start-up
Expected: Output Messages says that there is no more command to undo. -
Test case:
delete employee 1
is followed by repetitions ofundo
andredo
Expected: Theundo
andredo
can go on forever because redo is a data modification that can be undone.
11.21. Redoing a data modification that has been undone
Assumption: all the objects being manipulated in these test cases exist in the app.
-
Test case:
delete employee 1
followed byundo
followed byredo
Expected: The first command will delete the first employee in the list from the app while the undo command will restore it. The redo command deletes it again. -
Test case:
redo
is entered as the first command on start-up
Expected: Output error message. There is no undone command to redo.