Authors: Daryl Tan, Jeff Gan, Jothinandan Pillay, Lin Dehui, Shune Lei

Team: CS2103-AY1819S2-W10-2

Since: January 2019 License: MIT

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

ug notepadpencil

The note pad icon indicates any useful tips or things that users need to take note of while using the Pocket Project application.

ug lightbulb

The light bulb icon indicates any shortcuts that users can use while using the Pocket Project application.

ug exclamation

The exclamation mark icon indicates any warnings that users can take note of while using the Pocket Project application.

ug smart

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

  1. JDK 9 or later

    ug exclamation

    JDK 10 on Windows will fail to run tests in headless mode due to a JavaFX bug. Windows developers are highly recommended to use JDK 9.

  2. IntelliJ IDE

    ug notepadpencil

    IntelliJ by default has Gradle and JavaFx plugins installed.
    Do not disable them. If you have disabled them, go to File > Settings > Plugins to re-enable them.

4.2. Setting up the project in your computer

  1. Fork this repo, and clone the fork to your computer

  2. Open IntelliJ (if you are not in the welcome screen, click File > Close Project to close the existing project dialog first)

  3. Set up the correct JDK version for Gradle

    1. Click Configure > Project Defaults > Project Structure

    2. Click New…​ and find the directory of the JDK

  4. Click Import Project

  5. Locate the build.gradle file and select it. Click OK

  6. Click Open as Project

  7. Click OK to accept the default settings

  8. Open a console and run the command gradlew processResources (Mac/Linux: ./gradlew processResources). It should finish with the BUILD SUCCESSFUL message.
    This will generate all resources required by the application and tests.

  9. Open MainWindow.java and check for any code errors

    1. 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

    2. 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

  10. 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

  1. Run the seedu.address.MainApp and try a few commands

  2. 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,

  1. Go to File > Settings…​ (Windows/Linux), or IntelliJ IDEA > Preferences…​ (macOS)

  2. Select Editor > Code Style > Java

  3. Click on the Imports tab to set the order

    • For Class count to use import with '*' and Names count to use static import with '*': Set to 999 to prevent IntelliJ from contracting the import statements

    • For Import Layout: The order is import static all other imports, import java.*, import javax.*, import org.*, import com.*, import all other imports. Add a <blank line> between each import

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:

  1. Configure the site-wide documentation settings in build.gradle, such as the site-name, to suit your own project.

  2. Replace the URL in the attribute repoURL in DeveloperGuide.adoc and UserGuide.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).

ug notepadpencil

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).

ug notepadpencil

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,

  1. Get some sense of the overall design by reading Section 5.1, “Architecture”.

  2. Take a look at [GetStartedProgramming].

5. Design

5.1. Architecture

Architecture
Figure 1. Architecture Diagram

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.

  • UI: The UI of the App.

  • Logic: The command executor.

  • Model: Holds the data of the App in-memory.

  • Storage: Reads data from, and writes data to, the hard disk.

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.

LogicClassDiagram
Figure 2. Class Diagram of the Logic Component

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.

SDforDeletePerson
Figure 3. Component interactions for delete employee 1 command

The sections below give more details of each component.

5.2. UI component

UiClassDiagram
Figure 4. Structure of the 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

LogicClassDiagram
Figure 5. Structure of the Logic Component

API : Logic.java

  1. Logic uses the PocketProjectParser class to parse the user command.

  2. This results in a Command object which is executed by the LogicManager.

  3. The command execution can affect the Model (e.g. adding a employee).

  4. The result of the command execution is encapsulated as a CommandResult object which is passed back to the Ui.

  5. In addition, the CommandResult object can also instruct the Ui 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.

DeletePersonSdForLogic
Figure 6. Interactions Inside the Logic Component for the delete employee 1 Command

5.4. Model component

ModelClassDiagram
Figure 7. Structure of the 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.

ModelClassBetterOopDiagram

5.5. Storage component

StorageClassDiagram
Figure 8. Structure of the 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.

dg activitydiagdate
Figure 9. Activity Diagram: Showing 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.

dg codesnippet
Figure 10. Code snippet showing verification of a validity of a date.

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.

  1. addto PROJECT_NAME employee EMPLOYEE_INDEX
    Adds the employee at index EMPLOYEE_INDEX to the list of employees in the project named PROJECT_NAME.

  2. addto PROJECT_NAME milestone m/MILESTONE_DESCRIPTION d/MILESTONE_DATE
    Adds the specified milestone to the list of milestones in project named PROJECT_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.

dg addtoclassdiagram
Figure 11. Class Diagram: Showing inheritance relationship between the commands.

6.2.2. How it Works

The section details how a AddToCommand is parsed and processed.

dg addemployeeto
Figure 12. Sequence Diagram: How the Add Employee To Command Works

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.

ug lightbulb

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 with e and milestone with ms. The commands can be input as such:

    • addto PROJECT_NAME e EMPLOYEE_INDEX instead of addto PROJECT_NAME employee EMPLOYEE_INDEX

    • addto PROJECT_NAME ms m/MILESTONE_DESCRIPTION d/MILESTONE_DATE instead of addto 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:

remove employee from sequence diagram
Figure 13. Sequence diagram showing execution of 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.

ug lightbulb

The [project name] entered must be valid and exists in the app. The [employee index], [milestone index], [project task index] or [user story index] given must refer to some existing employee or milestone. If not, exceptions would be thrown during the execution of the command.

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:

  1. edit project PROJECT_NAME info [n/name] [c/client] [d/deadline] [desc/description] - allow editing of project’s name, deadline, description

  2. edit project PROJECT_NAME milestone MILESTONE_INDEX [m/milestone] [d/date] - allow editing of details of project milestone such as milestone description and date

  3. 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.

width:"300"
Figure 14. Class diagram showing inheritance for 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:

width:"800"
Figure 15. Sequence diagram for 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:

  1. User executes edit project Apollo info n/Gemini d/12/05/2019 to edit name and deadline of the project named Apollo.

  2. PocketProjectParser will identify the command as an EditCommand based on the word edit and pass on the argument to the EditCommandParser.

  3. Similarly the arguments will continue to parse through EditCommandParser and EditProjectCommandParser which will identify the command as EditProjectInfoCommand and return it back to the LogicManager

  4. LogicManager then execute the command. Validity of the arguments are checked here as well. The method Model#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.

  5. Finally, the project Apollo is edited and the updated details are shown on the UI.

ug notepadpencil

If the arguments provided are invalid, a CommandException will be thrown and error message will be shown.

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:

  1. find employee [KEYWORDS] - display employees with name containing keywords

  2. find project [KEYWORDS] - display projects with name containing keywords

  3. find skill [KEYWORDS] - display employees who has skills matching the keywords

  4. find all [KEYWORDS] - display projects which contains words matching the keywords

  5. 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.

find parser activity
Figure 16. Activity diagram on behavior of FindCommandParser

The following sequence diagram shows how the find employee command works:

findcommand sequence diagram
Figure 17. Sequence diagram for find employee John command

Usage Scenario example for find employee:

  1. User executes find employee John to look for employees whose names contains the word 'John'.

  2. PocketProjectParser will parse and identify the command as a FindCommand and pass on the argument employee John to FindCommandParser.

  3. FindCommandParser identify the command based on the COMMAND_KEYWORD 'employee'.

  4. find employee command is executed. Employees with name consisting the keywords are filtered out from the employeelist. The filtering is done through the use of ProjectNameContainsKeywordPredicate that checks through the names of the employee int the application.

  5. 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:

  1. list employee - displays all employees

  2. 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:

listcommand sequence diagram
Figure 18. Sequence diagram for list employee command

Usage Scenario example for list employee:

  1. User executes list employee to list all employees in PocketProject.

  2. PocketProjectParser will parse and identify the command as a ListCommand and pass the argument employee to ListCommandParser.

  3. ListCommandParser identifies the command to execute based on the COMMAND_KEYWORD and returns a ListEmployeeCommand.

  4. LogicManager then executes ListEmployeeCommand. All the employees in PocketProject will be returned by the filteredEmployees 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 or stats 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:

overallStatsSequenceDiagram
Figure 19. Sequence diagram showing execution of stats
individualStatsSequenceDiagram
Figure 20. Sequence diagram showing execution of stats 1

Usage Scenario example for stats:

  1. User executes stats/stats PROJECT_INDEX/stats PROJECT_NAME to view project statistics in Pocket Project.

  2. PocketProjectParser will parse and identify the command as a IndividualStatsCommand or OverallStatsCommand, parse any additional argument accordingly and return the command object.

  3. LogicManager then executes the returned command, calling the Model#individualStats() or Model#overallStats(Project) accordingly to obtain the string describing the status of concern.

  4. 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 in STORY to the list of user stories in the project with name PROJECT_NAME

  • removefrom PROJECT_NAME userstory STORY_INDEX — Removes the user story at index STORY_INDEX in the list of user stories in the project named PROJECT_NAME.

  • edit project PROJECT_NAME userstory STORY_INDEX STORY —  Edits the user story at index STORY_INDEX in the list of user stories in the project named PROJECT_NAME.

  • update PROJECT_NAME userstory STORY_INDEX STATUS — Updates the status of the user story at the STORY_INDEX in the list of user stories in the project named PROJECT_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 in STORY to the list of user stories in the project with name PROJECT_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.

ug exclamation

The PROJECT_NAME entered must be valid and the STORY added needs to be of the correct format. Else, exceptions would be thrown.

Remove user story from project command
  • removefrom PROJECT_NAME userstory STORY_INDEX — removes the user story at index STORY_INDEX in the list of user stories in the project named PROJECT_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:

remove user story from sequence diagram
Figure 21. Sequence diagram showing execution of 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.

ug exclamation

The PROJECT_NAME entered must be valid and exists in the app. The STORY_INDEX given must refer to some existing user story. If not, exceptions would be thrown during the execution of the command.

Edit user story command
  • edit project PROJECT_NAME userstory STORY_INDEX — edits the user story at index STORY_INDEX in the list of user stories in the project named PROJECT_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 user story sequence diagram
Figure 22. Sequence diagram showing execution of 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.

ug exclamation

The PROJECT_NAME entered must be valid and exists in the app. The STORY_INDEX given must refer to some existing user story and the new STORY must be valid. If not, exceptions would be thrown during the execution of the command.

Update user story command
  • update PROJECT_NAME userstory STORY_INDEX STATUS — Updates the status of the user story at the STORY_INDEX in the list of user stories in the project named PROJECT_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 user story sequence diagram
Figure 23. Sequence diagram showing execution of 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.

ug exclamation

The PROJECT_NAME entered must be valid and exists in the app. The STORY_INDEX given must refer to some existing user story and the new STATUS must be valid. If not, exceptions would be thrown during the execution of the command.

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.

  1. 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.

  2. 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:

UpdateProjectTaskSequenceDiagram
Figure 24. Sequence diagram showing execution of 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.

ug exclamation

The [project name] entered must be valid and exists in the app. The [milestone index] and [project task index] given must refer to some existing milestone and project task. Also, the status to be updated to needs to be of the correct format. If not, exceptions would be thrown during the execution of the command.

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:

  1. As it was in line with the OOP guidelines and principle.

  2. 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:

  1. 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.

  2. 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.

UndoRedoStartingStateListDiagram

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.

UndoRedoNewCommand1StateListDiagram

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.

UndoRedoNewCommand2StateListDiagram
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.

UndoRedoExecuteUndoStateListDiagram
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:

UndoRedoSequenceDiagram

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.

UndoRedoNewCommand3StateListDiagram

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.

UndoRedoNewCommand4StateListDiagram

The following activity diagram summarizes what happens when a user executes a new command:

UndoRedoActivityDiagram

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 and VersionedPocketProject.

  • 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 using LogsCenter.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.

  1. Follow the instructions in UsingGradle.adoc to convert the AsciiDoc files in the docs/ directory to HTML format.

  2. Go to your generated HTML files in the build/docs folder, right click on them and select Open withGoogle Chrome.

  3. Within Chrome, click on the Print option in Chrome’s menu.

  4. Set the destination to Save as PDF, then click Save to save a copy of the file in PDF format. For best results, use the settings indicated in the screenshot below.

chrome save as pdf
Figure 25. Saving documentation as PDF files in Chrome

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.
Table 1. List of site-wide attributes
Attribute name Description Default value

site-name

The name of the website. If set, the name will be displayed near the top of the page.

not set

site-githuburl

URL to the site’s repository on GitHub. Setting this will add a "View on GitHub" link in the navigation bar.

not set

site-seedu

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.
Table 2. List of per-file attributes, excluding Asciidoctor’s built-in attributes
Attribute name Description Default value

site-section

Site section that the document belongs to. This will cause the associated item in the navigation bar to be highlighted. One of: UserGuide, DeveloperGuide, LearningOutcomes*, AboutUs, ContactUs

* Official SE-EDU projects only

not set

no-site-header

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 docs/templates requires some knowledge and experience with Ruby and Asciidoctor’s API. You should only modify them if you need greater control over the site’s layout than what stylesheets can provide. The SE-EDU team does not provide support for modified template files.

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 choose Run '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:

  1. GUI Tests - These are tests involving the GUI. They include,

    1. System Tests that test the entire App by simulating user actions on the GUI. These are in the systemtests package.

    2. Unit tests that test the individual components. These are in seedu.address.ui package.

  2. Non-GUI Tests - These are tests not involving the GUI. They include,

    1. Unit tests targeting the lowest level methods/classes.
      e.g. seedu.address.commons.StringUtilTest

    2. 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

    3. 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 in src/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.

  1. Update the version number in MainApp.java.

  2. Generate a JAR file using Gradle.

  3. Tag the repo with the version number. e.g. v0.1

  4. 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:

  1. Include those libraries in the repo (this bloats the repo size)

  2. 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

  1. User requests to list employees

  2. PocketProject shows a list of employees

  3. User requests to delete a specific employee in the list

  4. PocketProject deletes the employee

    Use case ends.

Extensions

  1. The list is empty.

    Use case ends.

  2. The given index is invalid.

    • PocketProject shows an error message.

      Use case resumes at step 2.

C.1.2. Deleting a project

MSS

  1. User requests to list projects

  2. PocketProject shows a list of projects

  3. User requests to delete a specific project in the list

  4. PocketProject deletes the project

    Use case ends.

Extensions

  1. The list is empty.

    Use case ends.

  2. The given index is invalid.

    • PocketProject shows an error message.

      Use case resumes at step 2.

  3. 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

  1. User requests to list employees

  2. PocketProject shows a list of employees

  3. User requests to add a specific employee in the list to the project

  4. PocketProject adds the employee to the project specified.

    Use case ends.

Extensions

  1. The list is empty.

    Use case ends.

  2. The given index is invalid.

    • PocketProject shows an error message.

      Use case resumes at step 2.

  3. The project name given is invalid.

    • PocketProject shows an error message.

      Use case resumes at step 2.

  4. 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

  1. User requests to add a milestone to the project

  2. PocketProject adds the milestone to the project specified.

    Use case ends.

Extensions

  1. 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

  1. User requests to add a project task to the project

  2. PocketProject adds the project task to the project specified.

    Use case ends.

Extensions

  1. 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

  1. User requests to add a user story to the project

  2. PocketProject adds the user story to the project specified.

    Use case ends.

Extensions

  1. 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

  1. User requests to view employees in a project

  2. PocketProject shows a list of employees in the project

  3. User requests to delete a specific employee in the list

  4. PocketProject deletes the employee from the project

    Use case ends.

Extensions

  1. The list is empty.

    Use case ends.

  2. The given index is invalid.

    • PocketProject shows an error message.

      Use case resumes at step 2.

  3. 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

  1. User requests to view milestones in a project

  2. PocketProject shows a list of milestones in the project

  3. User requests to delete a specific milestone in the list

  4. PocketProject deletes the milestone from the project

    Use case ends.

Extensions

  1. The list is empty.

    Use case ends.

  2. The given index is invalid.

    • PocketProject shows an error message.

      Use case resumes at step 2.

  3. 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

  1. User requests to view project tasks in a project

  2. PocketProject shows a list of project tasks in the project in the specific milestone

  3. User requests to delete a specific task in the list

  4. PocketProject deletes the task from the project

    Use case ends.

Extensions

  1. The list is empty.

    Use case ends.

  2. The given milestone index is invalid.

    • PocketProject shows an error message.

      Use case resumes at step 2.

  3. 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

  1. User requests to view user stories in a project

  2. PocketProject shows a list of user stories in the project

  3. User requests to delete a specific user story in the list

  4. PocketProject deletes the user story from the project

    Use case ends.

Extensions

  1. The list is empty.

    Use case ends.

  2. The given index is invalid.

    • PocketProject shows an error message.

      Use case resumes at step 2.

  3. 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

  1. User requests to view an employee in a project

  2. PocketProject shows the employee details

  3. User requests to edit an employee details

  4. PocketProject edits the employee’s details

    Use case ends.

Extensions

  1. 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

  1. User requests to find all occurences of a keyword in a project

  2. PocketProject returns any project found with the keyword specified

    Use case ends.

Appendix D: Non Functional Requirements

  1. Should work on any mainstream OS as long as it has Java 9 or higher installed.

  2. Should be able to hold up to 1000 employees without a noticeable sluggishness in performance for typical usage.

  3. Should be user-friendly for software engineering project managers and should help them manage their projects more efficiently and effectively.

  4. Should have automated tests to do regression testing whenever an existing feature is enhanced or a new feature is added.

  5. 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.

  6. The system should respond to user input within 2 seconds, whether it is valid or invalid input.

Appendix E: Glossary

Mainstream OS

Windows, Linux, Unix, OS-X

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

  1. Initial launch

    1. Download the jar file and copy into an empty folder

    2. Double-click the jar file
      Expected: Shows the GUI with a set of sample employees and projects. The window size may not be optimum.

  2. Saving window preferences

    1. Resize the window to an optimum size. Move the window to a different location. Close the window.

    2. 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.

  1. 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.

  2. 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.

  3. 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.

  4. 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

  1. Adding a new project

    1. Prerequisite: Project list doesn’t already contain a project named 'Apollo'.

    2. 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.

    3. 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.

    4. 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.

    5. 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.

    6. 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.

    7. 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.

    8. 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.

  2. Adding a new project that has at most 1 field different from an existing project.

    1. 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.

    2. 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.

    3. 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.

    4. 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.

    5. 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

  1. Adding a milestone to a project

    1. 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'.

    2. 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.

    3. 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.

    4. 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.

    5. 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.

  2. Adding a new milestone that has at most 1 field different from an existing milestone in a project.

    1. Prerequisite: This test case assumes that the command addto Apollo milestone Finished UserGuide 23/04/2019 has been entered successfully at least once before.

    2. 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.

    3. 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.

    4. 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

  1. Adding a project task to a project’s milestone

    1. Prerequisite: Project list has a project named 'Apollo' and has only 2 existing milestone in it.

    2. 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.

    3. 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.

    4. 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.

    5. 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.

    6. 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.

    7. 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

  1. Adding a new user story to a project

    1. Prerequisites: The project list contains a project with name 'Apollo' but not a project with name 'Not Found'.

    2. 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.

    3. 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.

    4. 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

  1. Prerequisites: List all employees using the list command. Multiple employees in the list.

  2. 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.

  3. Test case: delete employee 0
    Expected: No employee is deleted. Error details shown in the status message. Status bar remains the same.

  4. 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

  1. Prerequisites: List all projects using the list projects command. Multiple projects in the list.

  2. 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.

  3. 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.

  4. Test case: delete project 0
    Expected: No project is deleted. Error details shown in the status message. Status bar remains the same.

  5. 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

  1. 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 + and add employee n/John p/87654321 e/b@gmail.com g/cba.com. Peter is the first in the display list and John second.

    1. 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.

    2. edit 1 n/John p/22345678 e/a@gmail.com g/abc.com
      Expected: Command fails as John already exists.

    3. 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

  1. Deleting a project while all projects are listed

    1. Prerequisites: List all projects using the list projects command. Multiple projects in the list.

    2. 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.

    3. 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.

    4. Test case: delete project 0
      Expected: No project is deleted. Error details shown in the status message. Status bar remains the same.

    5. 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

  1. Prerequisites: Project with the name 'Apollo' exists and has 3 employees in it.

    1. 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.

    2. Test case: removefrom Apollo employee 4
      Expected: No employee is removed. Error details shown in the status message. Status bar remains the same.

    3. 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.

    4. 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

  1. Prerequisites: Project with name 'Apollo' exists and has 1 milestone in it.

  2. 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.

  3. Test case: remove from Apollo milestone 0
    Expected: Command fails and an error message is returned.

  4. 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

  1. Prerequisites: Project with name 'Apollo' exists and has only 1 milestone with only 1 project task in it.

  2. 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.

  3. 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.

  4. 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.

  5. 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

  1. Prerequisite: Project with name 'Apollo' exists and has only 1 milestone with at least 1 project task in it.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. 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.

  8. 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

  1. Test case: find project a b c
    Expected: projects with 'a', 'b' or 'c' in their names as separate words would be listed

  2. Test case: find employee x y z
    Expected: employees with 'x', 'y' or 'z' in their names as separate words would be listed

  3. Test case find abc
    Expected: error will be returned

11.15. Finding employees with specific skills

  1. Test case: find skill java
    Expected: All employees with the skill java will be listed

  2. Test case: find abc java
    Expected: error will be returned

11.16. Finding projects with specific keywords in their name, description or deadline

  1. 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

  1. 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.

  2. 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

  1. Test case: clear
    Expected: All data of employees and projects are deleted from the app.

  2. Test case: clear q23rfdq3w
    Expected: All data cleared. The string of characters after the word clear is ignored.

  3. Test case: clear with leading and trailing whitespaces
    Expected: Data still cleared. Leading and trailing spaces are ignored.

  4. Test case: abc clear
    Expected: Error message about unrecognized command is returned.

11.19. Exiting from the app

  1. 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.

  2. Test case: exit q23rfdq3w
    Expected: The app ends. The string of characters after the word clear is ignored.

  3. Test case: exit with leading and trailing whitespaces
    Expected: The app ends. Leading and trailing spaces are ignored.

  4. 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.

  1. Test case: delete employee 1 followed by undo
    Expected: The first command will delete the first employee in the list from the app while the undo command will restore it.

  2. Test case: delete employee 1 followed by list employee followed by undo
    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.

  3. Test case: undo is entered as the first command on start-up
    Expected: Output Messages says that there is no more command to undo.

  4. Test case: delete employee 1 is followed by repetitions of undo and redo
    Expected: The undo and redo 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.

  1. Test case: delete employee 1 followed by undo followed by redo
    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.

  2. Test case: redo is entered as the first command on start-up
    Expected: Output error message. There is no undone command to redo.