By: Team W09-1
Since: Feb 2019
Licence: MIT
- 1. Introduction
- 2. Setting up
- 3. Design
- 4. Implementation
- 4.1. Adding a homework:
add-hw
- 4.2. Delete homework feature
- 4.3. Edit homework feature
- 4.4. Find module feature
- 4.5. Adding a note :
add-note
- 4.6. Deleting a note :
delete-note
- 4.7. Editing and Saving a note :
edit-note
save-note
- 4.8. Editing a Cap Entry :
edit-cap
- 4.9. Deleting a Cap Entry :
delete-cap
- 4.10. Logging
- 4.11. Configuration
- 4.1. Adding a homework:
- 5. Documentation
- 6. Testing
- 7. Dev Ops
- Appendix A: Product Scope
- Appendix B: User Stories
- Appendix C: Use Cases
- Appendix D: Non Functional Requirements
- Appendix E: Glossary
- Appendix F: Product Survey
- Appendix G: Instructions for Manual Testing
- G.1. Launch and Shutdown
- G.2. Opening a manager
- G.3. Adding a homework
- G.4. Deleting a homework entry
- G.5. Editing a homework entry
- G.6. Finding homework entries of which contains this module
- G.7. List all homework entries
- G.8. Adding a note
- G.9. Deleting a note
- G.10. Editing a Note
- G.11. Saving a Note
- G.12. Adding a cap entry
- G.13. Deleting a cap entry
- G.14. Editing a cap entry
1. Introduction
Welcome to UltiStudent! UltiStudent is a student application that effectively tackles the problem of having too many applications to manage their school life. To improve the quality of student life in computing, UltiStudent provides a centralised platform for them to manage their homework, cumulative average point and notes. UltiStudent is a desktop-based application intended for students.
This Developer Guide is written for anyone who wishes to contribute to our project. In here, you will find information to help you to set up our project and information to help you understand the architecture behind UltiStudent and how our key features work.
If you would like to help to improve this project by contributing, do contact us for more information!
1.1. Callouts & Symbols
Before proceeding, do refer to the below callout signs that will be used across this document. Familiarising yourself with them will definitely prove to be helpful.
This callout shares note-worthy information with you. Do read them for a better understanding of the document. |
This callout shares helpful tips with you. Not to worry, tips can be good to know but are not vital. Information found here are additional and can prove to be handy for you. |
This callout indicates that there is worth being cautioned of. You are encouraged to the read information in here. If you are not careful, you may encounter problems. |
2. Setting up
Do follow the instructions in order to set up our project on your device.
2.1. Prerequisites
-
JDK
9
or laterJDK 10
on Windows will fail to run tests in headless mode due to a JavaFX bug. Windows developers are highly recommended to use JDK9
. -
IntelliJ IDE
IntelliJ by default has Gradle and JavaFx plugins installed.
Do not disable them. If you have disabled them, go toFile
>Settings
>Plugins
to re-enable them.
2.2. Setting up the project in your computer
-
Fork this repo, and clone the fork to your computer
-
Open IntelliJ (if you are not in the welcome screen, click
File
>Close Project
to close the existing project dialog first) -
Set up the correct JDK version for Gradle
-
Click
Configure
>Project Defaults
>Project Structure
-
Click
New…
and find the directory of the JDK
-
-
Click
Import Project
-
Locate the
build.gradle
file and select it. ClickOK
-
Click
Open as Project
-
Click
OK
to accept the default settings -
Open a console and run the command
gradlew processResources
(Mac/Linux:./gradlew processResources
). It should finish with theBUILD SUCCESSFUL
message.
This will generate all resources required by the application and tests. -
Open
MainWindow.java
and check for any code errors-
Due to an ongoing issue with some of the newer versions of IntelliJ, code errors may be detected even if the project can be built and run successfully
-
To resolve this, place your cursor over any of the code section highlighted in red. Press ALT+ENTER, and select
Add '--add-modules=…' to module compiler options
for each error
-
-
Repeat this for the test folder as well (e.g. check
HelpWindowTest.java
for code errors, and if so, resolve it the same way)
2.3. Verifying the setup
-
Run the
seedu.ultistudent.MainApp
and try a few commands -
Run the tests to ensure they all pass.
2.4. Configurations to do before writing code
2.4.1. Configuring the coding style
This project follows oss-generic coding standards. IntelliJ’s default style is mostly compliant with ours but it uses a different import order from ours. To rectify,
-
Go to
File
>Settings…
(Windows/Linux), orIntelliJ IDEA
>Preferences…
(macOS) -
Select
Editor
>Code Style
>Java
-
Click on the
Imports
tab to set the order-
For
Class count to use import with '*'
andNames count to use static import with '*'
: Set to999
to prevent IntelliJ from contracting the import statements -
For
Import Layout
: The order isimport static all other imports
,import java.*
,import javax.*
,import org.*
,import com.*
,import all other imports
. Add a<blank line>
between eachimport
-
Optionally, you can follow the UsingCheckstyle.adoc document to configure Intellij to check style-compliance as you write code.
2.4.2. Setting up CI
Set up Travis to perform Continuous Integration (CI) for your fork. See UsingTravis.adoc to learn how to set it up.
After setting up Travis, you can optionally set up coverage reporting for your team fork (see UsingCoveralls.adoc).
Coverage reporting could be useful for a team repository that hosts the final version but it is not that useful for your personal fork. |
Optionally, you can set up AppVeyor as a second CI (see UsingAppVeyor.adoc).
Having both Travis and AppVeyor ensures your App works on both Unix-based platforms and Windows-based platforms (Travis is Unix-based and AppVeyor is Windows-based) |
2.4.3. Getting started with coding
When you are ready to start coding,
-
Get some sense of the overall design by reading Section 3.1, “Architecture”.
-
Take a look at [GetStartedProgramming].
3. Design
3.1. Architecture
The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.
The .pptx files used to create diagrams in this document can be found in the diagrams folder. To update a diagram, modify the diagram in the pptx file, select the objects of the diagram, and choose Save as picture .
|
Main
has only one class called MainApp
. It is responsible for,
-
At app launch: Initializes the components in the correct sequence, and connects them up with each other.
-
At shut down: Shuts down the components and invokes cleanup method where necessary.
Commons
represents a collection of classes used by multiple other components.
The following class plays an important role at the architecture level:
-
LogsCenter
: Used by many classes to write log messages to the App’s log file.
The rest of the App consists of four components.
Each of the four components
-
Defines its API in an
interface
with the same name as the Component. -
Exposes its functionality using a
{Component Name}Manager
class.
For example, the Logic
component (see the class diagram given below) defines it’s API in the Logic.java
interface and exposes its functionality using the LogicManager.java
class.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete 1
.
delete 1
commandThe sections below give more details of each component.
3.2. UI component
API : Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, PersonListPanel
, StatusBarFooter
, BrowserPanel
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.
3.3. Logic component
API :
Logic.java
-
Logic
uses theUltiStudentParser
class to parse the user command. -
This results in a
Command
object which is executed by theLogicManager
. -
The command execution can affect the
Model
(e.g. adding a homework). -
The result of the command execution is encapsulated as a
CommandResult
object which is passed back to theUi
. -
In addition, the
CommandResult
object can also instruct theUi
to perform certain actions, such as displaying help to the user.
Given below is the Sequence Diagram for interactions within the Logic
component for the execute("delete 1")
API call.
delete 1
Command3.4. Model component
API : Model.java
The Model
,
-
stores a
UserPref
object that represents the user’s preferences. -
stores the UltiStudent data.
-
exposes an unmodifiable
ObservableList<Homework>
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.
3.5. Storage component
API : Storage.java
The Storage
component,
-
can save
UserPref
objects in json format and read it back. -
can save the UltiStudent data in json format and read it back.
3.6. Common classes
Classes used by multiple components are in the seedu.ultistudent.commons
package.
4. Implementation
This section describes some noteworthy details on how certain features are implemented.
4.1. Adding a homework: add-hw
The add homework feature is a core feature to the Homework Manager of UltiStudent. Which allows the users to create a homework object in UltiStudent. |
4.1.1. Overview
The add homework add-hw
mechanism is facilitated by AddHomeworkCommand
and AddHomeworkCommandParser
.
It takes in the following input from the user: ModuleCode
, HomeworkName
and Date
, which will
construct individual objects that construct a Homework
object.
The AddHomeworkCommandParser
implements Parser
with the following operation:
-
AddHomeworkCommandParser#parse()
- This operation will take in aString
input from the user that will create individual objects based on the prefixes 'mc/', 'hw/' and 'd/'. TheString
value after the individual prefixes will create the respective object: 'mc/' forModuleCode
, 'hw/' forHomeworkName
and 'd/' forDate
. A validation check will be imposed upon the creation of each object. Any checks that fails the validation would prompt the user on the failed component. For example:-
ModuleCode
would useParserUtil#parseHomeworkModuleCode()
to ensure that user has input 2 letters followed by 4 digits with an option to include a optional letter after the 4 digits. -
HomeworkName
would useParserUtil#parseHomeworkName()
to ensure that homework name is not a null. -
Date
would useParserUtil#parseDate()
to ensure that user has entered a date that is either a present or future date.
-
-
After validation checks are completed with no errors, a
Homework
object is then constructed withModuleCode
,HomeworkName
andDate
as the parameters -
AddHomeworkCommandParser
would then return aAddHomeworkCommand
object with theHomework
as the parameter
Take a look at the code snippet of AddHomeworkCommandParser below for an illustration:
4.1.2. Example
Given below is an example usage scenario of how add-hw
mechanism behaves at each step.
Step 1: The user executes add-hw mc/CS1101S hw/Tutorial 1 d/01/05/2019
to add a CS1101S Tutorial 1
homework with the deadline on 1st May 2019.
Step 2: LogicManager
would use UltiStudentParser#parse()
to parse the input from the user.
Step 3: UltiStudentParser
would determine which command is being used and creates the respective
parser. In this case, AddHomeworkCommandParser is being created and the user’s input would be pass in
as a parameter.
Step 4: AddHomeworkCommandParser
would do a validation check on the user’s input before creating
and returning a AddHomeworkCommand
object with Homework
as the parameter.
Step 5: LogicManager
would use AddHomeWorkCommand#execute()
to add the
ModuleCode
and Homework
into the Model
which is handled by ModelManager
Step 6: AddHomeworkCommand
would return a CommandResult
to the LogicManager
which would then
be return back to the user.
The image below illustrates the scenario of when the user executes add-hw mc/CS1101S hw/Tutorial 1
d/01/05/2019
:
add-hw
4.2. Delete homework feature
This feature allows the user to delete a homework entry from the homework manager through its index.
The delete homework feature is facilitated by the DeleteHomeworkCommandParser
and the DeleteHomeworkCommand
.
The delete command is part of the logic component of our application. It interacts with the model and the storage components of our application.
4.2.1. Overview
The DeleteHomeworkCommandParser
implements Parser
with the following operation:
-
DeleteHomeworkCommandParser#parse()
- This operation will take in aint
input from the user which will delete the homework entry at the index which has entered. Any invalid format of the command will be prompted by the command parser.
4.2.2. Current Implementation
The delete homework feature is executed by the DeleteHomeworkCommand
. Currently, the
deletion of any homework entry is done based on the INDEX
of the homework entry.
During the design of our delete function, we considered between two alternatives.
Design Consideration | Pros and Cons |
---|---|
Deletion by Index (Current Choice) |
Pros: Since each homework has a unique index, any deletion by the index is less prone to bugs and easier to implement. Cons: User will have to scroll for the homework entry and look for its index which can be inconvenient |
Deletion by Homework Name |
Pros: It may be more intuitive for users to delete a homework through the name of the homework. Cons: Homework for different modules can have different names. For example, two different homework entries for two different modules can be called 'Tutorial 1'. |
We have decided to opt for the first option primarily because it reduces the number of potential bugs and the complexities involved when taking into account the different cases upon using deletion by homework name.
4.3. Edit homework feature
This feature allows the user to edit any attribute of the homework entries. This is a core feature because the user may have to update deadline or make corrections to mistakes, such as typographical errors, when adding a homework entry. There are a total of three attributes for each entry, the module code, the homework name and the deadline. The user can edit at least one and up to three attributes.
The edit homework feature is facilitated by the EditHomeworkCommandParser
and the EditHomeworkCommand
.
The edit command is part of the logic component of our application. It interacts with the model component of our software architecture.
4.3.1. Overview
The EditHomeworkCommandParser
implements Parser
with the following operation:
-
EditHomeworkCommandParser#parse()
- This operation will take in anint
input and one to threeString
input(s) from the user that will alter the attributes of current homework entries based on the prefixes 'mc/', 'hw/' and 'd/'. TheString
value after the individual prefixes will alter the respective attribute it corresponds to: 'mc/' forModuleCode
,'hw/' forHomeworkName
and 'd/' forDate
. A validation check will be imposed upon editing of each object. Any checks that fails the validation would prompt the user on the failed component.
4.3.2. Current Implementation
Here is an example of a step-by-step process on how the edit command alters an attribute of the homework entry.
For each step, you may follow the activity diagram at the end of this section to better understand the flow of events
within UltiStudent when an edit-hw
command is inputted.
Step 1. The user launches the application and opens the homework manager. There is a list of existing homework entries in the homework manager.
Step 2. The user then wishes to alter the homework deadline of the third entry in the homework list to 10 May 2019.
He then types edit-hw d/10/05/2019
into the Command Line Interface (CLI) and executes it.
Step 3. The UltiStudentParser (refer to logic) then reads in these attributes that have been inputted and proceeds to alter the attributes of the homework entry in the given index. Each attribute will be validated.
Step 4. The UltiStudentParser then creates a new EditHomeworkCommand based on the input of the user. When the EditHomeworkCommand is executed, it interacts with the Model architecture by calling the setHomework method. The setHomework method replaces the current homework entry with the a new homework entry containing all the desired attributes. The homework entry is now updated.
Step 5. If the module code for any homework entry has been edited to a module code that is not in the module code list, the EditHomeworkCommand will add the new module code into the module code list. The updated module code list will be displayed on our User Interface.
edit-hw
In designing the edit homework feature, we considered if we should use an alternative data structure to update the list of module codes. We considered using a hash map to map the module code to the number of homework with the modules to check if the module code list has to be updated for each edit.
Design Consideration | Pros and Cons |
---|---|
Update ModuleList by iteration (Current Choice) |
Pros: Protects the abstraction layers and modularity by restricting the usage to the existing data structures already present in our code. Cons: Less efficient in terms of time and actual time taken can be long when number of entries is large. |
Update ModuleList using help from other data structures. |
Pros: Faster expected performance. Cons: Introducing a new data structure can disrupt the existing abstractions of our code. |
To sum up our justification of our choice of design, we decided to opt for the first option because we prioritised the existing design abstractions in our code over the efficiency of our code.
4.4. Find module feature
This feature allows the user to only display homework belonging to one or more module codes which is user has specified. The find module feature is exceptionally useful to shorten the displayed list of homework.
The find module feature is facilitated by the FindModuleCommandParser
and the FindModuleCommand
.
It interacts with the model component of our architecture to retrieve the list homework.
4.4.1. Overview
The FindModuleCommandParser
implements Parser
with the following operation:
-
FindModuleCommandParser#parse()
- This operation will take in at least oneString
input from the user and display any of the homework entries with matches any of list of[KEYWORDS]
that the user has inputted. Each keyword is separated by a white space. Any homework entry that matches with the list of keywords will be displayed on the homework list.
4.4.2. Current Implementation
The find module feature is facilitated by the FindModuleCommand
.
Here is a sequence of steps on how the find module feature works. We will use an example here to help you understand the flow of events. In the steps below, we will make references to the diagram at the end of the section to help you visualise the sequence of events better.
Step 1. The user first launches the application and enters the homework manager. There are already existing homework entries within the homework list.
Step 2. Currently, there are a total of twelve homework entries belonging to four modules.
(Do note that this is an arbitrary state of the storage in the homework manager and is meant to serve as an example.)
Now the user inputs find mod CS1101S
. Referring to the diagram below, UltiStudentCommandParser
parses the command find-mod
together with the list of keywords.
Step 3. The FindModuleParser then creates a FindModuleCommand and then returns it to the LogicManager, which are illustrated by the blue arrows pointing from the command parsers back to the LogicManger.
Step 4. Now, the Logic Manager then executes this command. When the find command is executed, it called the method updateFilteredList, which then returns a list of homework that has the module codes which matches any of the key words inputted back to the Logic Manager as indicated by the purple arrows pointing back to the Logic Manager’s blue block.
find-mod
4.5. Adding a note : add-note
The add homework feature is a core feature to the Homework Manager of UltiStudent. Which allows the users to create a homework object in UltiStudent. |
4.5.1. Overview
The add note add-note
mechanism is facilitated by AddNoteCommand
and
AddNoteCommandParser
.
It takes in the following input from the user: ModuleCode
and NoteName
which will construct individual objects that construct a Note
object.
The AddNoteCommandParser
implements Parser
with the following operation:
-
AddNoteCommandParser#parse()
- This operation will take in aString
input from the user that will create individual objects based on the prefixes 'mc/' and 'n/'. TheString
value after the individual prefixes will create the respective object: 'mc/' forModuleCode
and 'n/' forNoteName
. A validation check will be imposed upon the creation of each object. Any checks that fails the validation would prompt the user on the failed component.
For example:
-
ModuleCode
would useParserUtil#parseNoteModuleCode
to ensure that user has input 2 letters followed by 4 digits with an option to include a optional letter after the 4 digits. -
NoteName
would useParserUtil#parseNoteName
to ensure that note name is not a null.-
After validation checks are completed with no errors, a
Note
object is then constructed withModuleCode
andNoteName
. -
AddNoteCommandParser
would then return aAddNoteCommand
object with theNote
as the parameter
-
4.5.2. Example
Given below is an example usage scenario of how add-note
mechanism behaves at
each step.
Step 1: The user executes `add-note mc/CS2103T n/Week 1 Lecture to add a note for CS2103T Week 1 Lecture.
Step 2: LogicManager
would use UltiStudentParser#parse()
to parse the input from the user.
Step 3: UltiStudentParser
would determine which command is being used and creates the respective
parser. In this case, AddNoteCommandParser is being created and the user’s
input would be pass in as a parameter.
Step 4: AddNoteCommandParser
would do a validation check on the user’s input
before creating and returning a AddNoteCommand
object with Note
as the parameter.
Step 5: LogicManager
would use AddNoteCommand#execute()
to add the
ModuleCode
and Note
into the Model
which is handled by ModelManager
Step 6: AddNoteCommand
would return a CommandResult
to the LogicManager
which would then be return back to the user.
The image below illustrates the scenario of when the user executes add-hw mc/CS1101S hw/Tutorial 1
d/01/05/2019
:
add-note
4.6. Deleting a note : delete-note
This feature allows the user to delete a note from the homework manager through its index.
The delete note feature is facilitated by the DeleteNoteCommandParser
and
the DeleteNoteCommand
.
The delete command is part of the logic component of our application. It interacts with the model and the storage components of our application.
4.6.1. Overview
The DeleteNoteCommandParser
implements Parser
with the following operation:
-
DeleteNoteCommandParser#parse()
- This operation will take in aint
input from the user which will delete the note entry at the index which has entered. Any invalid format of the command will be prompted by the command parser.
4.6.2. Current Implementation
The delete note feature is executed by the DeleteNoteCommand
. Currently,
the deletion of any note entry is done based on the INDEX
of the
note entry.
During the design of our delete function, we considered between two alternatives.
Description of Implementation | Pros and Cons |
---|---|
Deletion by Index (Current Choice) |
Pros: Since each note has a unique index within each list, deleting a note by its index is less prone to bugs and will be easier to implement. Cons: User will need to scroll for the entry and look for its index which can be inconvenient. |
Deletion by Homework Name |
Pros: It may be more intuitive for users to delete a note through its note name. Cons: Notes for different modules can have similar names. For example, two different note entries for two different modules can be called 'Week 7 Lecture'. This may cause it to be more error-prone. |
We have decided to opt for the first option primarily because it reduces the number of potential bugs and the complexities involved when taking into account the different cases upon using deletion by note name.
4.7. Editing and Saving a note : edit-note
save-note
These two feature allows the user to edit existing note and save them after editing. |
4.7.1. Overview
The edit-note
command helps the user to open the selected notes to allow the user to start editing its content
by displaying all the content on the NotesManagerMainPanel
which is a text field. It requires the need of the
save-note
command to help save the user’s edits
Below is an activity diagram of how the users use edit-note
and save-note
to facilitate adding contents to
their existing notes:
edit-note
and save-note
Step 1: User will key in edit-note INDEX
on the command line
Step 2: System will do a validation check to see if INDEX
of note exist in the list of notes in the Model
.
If note does not exist, it will throw a ParserException
to the user. Else note will be opened and proceed to
step 3.
Step 3: Once it is opened, NotesManagerMainPanel
will be enabled, allowing the user to start typing their
notes in the text field.
Step 4: When the user is done editing, he/she can use save-note
in the command line to save the edited
content to the opened note.
Step 5: Upon successful save, NotesManagerMainPanel
will be disabled and user will not be able to type
anything on NotesManagerMainPanel
4.7.2. Design Considerations
Options |
Pro |
Cons |
1. Users to type their content on the command line |
- Easy implementation |
- Not user friendly |
2. Users to type their content on the |
- User friendly |
- Two sources of input, Command Line and TextField |
Option 2 is being selected and implemented as we focus on the users convenience and the ability to edit their notes easily. Separation of command line and notes text field would reduce the number of commands the user has to remember and there will be lesser confusion of command line mode or text input mode.
4.8. Editing a Cap Entry : edit-cap
This feature allows the user to edit a cap entry from the cap entry list. Users can do so either via:
the cap entry’s index with the edit-cap
command or the cap entry’s module code with the edit-cap-mc
4.8.1. Current Implementation
The edit-cap
command is facilitated by the Logic and Model components of the application, UltiStudent.
The sequence diagram below shows how the editing of cap entries work when the user enters
edit-cap
edit-cap
The sequence diagram for the "Update Module Semester" reference frame above can be seen below.
Given below is an example usage scenario of how edit-cap
behaves at each step.
Step 1: The user launches the application and opens the CAP Manager.
Step 2: There are already existing CAP entries. The user now executes edit-cap 2 g/A sem/Y2S2
to edit the cap entry in the 2nd index with grade A and
moduleSemester of Y2S2
.
Step 3: Upon executing this command, the EditCapCommandParser
will take in all the arguments inputted and create a
EditCapCommand
object. This object is then returned to the Logic Manager
which will then execute the EditCommand
Step 4: When executing the EditCapCommand
this alters the attributes of the CAP Entry in the UniqueCapEntryList object of
UltiStudent by setCapEntry(a,b) method, where a
is the cap entry to edit, and b
is the edited cap entry.
In doing so, this will call the method of updateCapForDelete(a)
and updateCapForAdd(b)
, which will update the CAP score.
Step 5: Next, the UniqueModuleSemesterList
will be updated. This is done by the updateModuleSemesterList(x,y)
where x
is
the moduleSemesterOfCapEntry
to edit, while y
is the moduleSemesterOfEditedCapEntry
.
Step 6: If moduleSemesterOfCapEntry
is different from moduleSemesterOfEditedCapEntry
, the model
will check if it
contains moduleSemesterOfEditedCapEntry
. If it does not, moduleSemesterOfEditedCapEntry
will be added to
the UniqueModuleSemesterList
.
Step 7: On the other hand, if the model
does not have any cap entries with the same semesters as
moduleSemesterOfCapEntry
after editing the cap entries, which is reflected if hasCapEntriesWithSameSemester
is false.
The moduleSemesterOfCapEntryToEdit
will be deleted to the UniqueModuleSemesterList
.
4.8.2. Design Considerations
Aspect: How to store the Cap Score.
-
Alternative 1 (current choice): Store the cap score as a static variable in CapEntry class.
-
Pros: Easy to implement.
-
Cons: Since a static variable belongs to the CapEntry class, there may be unintended side effects when we use commands to modify the
UniqueCapEntryList
.
-
-
Alternative 2: Store the cap score as a separate class that is then store in UltiStudent.
-
Pros: Each versioned UltiStudent will have their own cap score.
-
Cons: Will use more memory and is harder to implement.
-
Aspect: How to assign score for module grade.
-
Alternative 1 (current choice): Use a Hash Map to get the Store the cap score as a static variable in CapEntry class.
-
Pros: Lower time complexity O(1) and cleaner code.
-
Cons: Larger memory occupation.
-
-
Alternative 2: Use switch cases to find and allocate score to grade.
-
Pros: Easier readability.
-
Cons: Slower time complexity, worst case of O(N).
-
4.9. Deleting a Cap Entry : delete-cap
This feature allows the user to delete a cap entry from the cap entry list. Users can do so either via:
the cap entry’s index with the delete-cap
command or the cap entry’s module code with the delete-cap INDEX
4.9.1. Current Implementation
The delete-cap
command is facilitated by the Logic and Model components of the application, UltiStudent.
The activity diagram below shows how the deleting of cap entries work when the user enters
delete-cap
.
delete-cap
Given below is an example usage scenario of how delete-cap
behaves at each step.
Step 1: The user executes delete-cap 2
to delete the cap entry in the 2nd index.
Step 2: Upon executing this command, the DeleteCapCommandParser
parses the arguments and checks if the arguments are valid.
If not valid, the command throws an exception and terminates.
Step 3: If the argument is valid, the command checks if the CapEntry
exists in the CAP Manager. If it does, the entry is deleted.
The UniqueCapEntryList
is then updated and the CAP score is updated as well.
Step 4: Check if after deleting the target CapEntry
the UniqueCapEntryList
still has a CapEntry
of the same semester. If there is,
the module semester will be deleted from the UniqueModuleSemesterList
. Then the UniqueModuleSemesterList
will be updated.
4.10. Logging
We are using java.util.logging
package for logging. The LogsCenter
class is used to manage the logging levels and logging destinations.
-
The logging level can be controlled using the
logLevel
setting in the configuration file (See Section 4.11, “Configuration”) -
The
Logger
for a class can be obtained usingLogsCenter.getLogger(Class)
which will log messages according to the specified logging level -
Currently log messages are output through:
Console
and to a.log
file.
Logging Levels
-
SEVERE
: Critical problem detected which may possibly cause the termination of the application -
WARNING
: Can continue, but with caution -
INFO
: Information showing the noteworthy actions by the App -
FINE
: Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size
4.11. Configuration
Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json
).
5. 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. |
5.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.
5.2. Publishing Documentation
See UsingTravis.adoc to learn how to deploy GitHub Pages using Travis.
5.3. Converting Documentation to PDF format
We use Google Chrome for converting documentation to PDF format, as Chrome’s PDF engine preserves hyperlinks used in webpages.
Here are the steps to convert the project documentation files to PDF format.
-
Follow the instructions in UsingGradle.adoc to convert the AsciiDoc files in the
docs/
directory to HTML format. -
Go to your generated HTML files in the
build/docs
folder, right click on them and selectOpen with
→Google Chrome
. -
Within Chrome, click on the
Print
option in Chrome’s menu. -
Set the destination to
Save as PDF
, then clickSave
to save a copy of the file in PDF format. For best results, use the settings indicated in the screenshot below.
5.4. Site-wide Documentation Settings
The build.gradle
file specifies some project-specific asciidoc attributes which affects how all documentation files within this project are rendered.
Attributes left unset in the build.gradle file will use their default value, if any.
|
Attribute name | Description | Default value |
---|---|---|
|
The name of the website. If set, the name will be displayed near the top of the page. |
not set |
|
URL to the site’s repository on GitHub. Setting this will add a "View on GitHub" link in the navigation bar. |
not set |
|
Define this attribute if the project is an official SE-EDU project. This will render the SE-EDU navigation bar at the top of the page, and add some SE-EDU-specific navigation items. |
not set |
5.5. Per-file Documentation Settings
Each .adoc
file may also specify some file-specific asciidoc attributes which affects how the file is rendered.
Asciidoctor’s built-in attributes may be specified and used as well.
Attributes left unset in .adoc files will use their default value, if any.
|
Attribute name | Description | Default value |
---|---|---|
|
Site section that the document belongs to.
This will cause the associated item in the navigation bar to be highlighted.
One of: * Official SE-EDU projects only |
not set |
|
Set this attribute to remove the site navigation bar. |
not set |
5.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 |
6. Testing
6.1. Running Tests
There are three ways to run tests.
The most reliable way to run tests is the 3rd one. The first two methods might fail some GUI tests due to platform/resolution-specific idiosyncrasies. |
Method 1: Using IntelliJ JUnit test runner
-
To run all tests, right-click on the
src/test/java
folder and chooseRun 'All Tests'
-
To run a subset of tests, you can right-click on a test package, test class, or a test and choose
Run 'ABC'
Method 2: Using Gradle
-
Open a console and run the command
gradlew clean allTests
(Mac/Linux:./gradlew clean allTests
)
See UsingGradle.adoc for more info on how to run tests using Gradle. |
Method 3: Using Gradle (headless)
Thanks to the TestFX library we use, our GUI tests can be run in the headless mode. In the headless mode, GUI tests do not show up on the screen. That means the developer can do other things on the Computer while the tests are running.
To run tests in headless mode, open a console and run the command gradlew clean headless allTests
(Mac/Linux: ./gradlew clean headless allTests
)
6.2. Types of tests
We have two types of tests:
-
GUI Tests - These are tests involving the GUI. They include,
-
System Tests that test the entire App by simulating user actions on the GUI. These are in the
systemtests
package. -
Unit tests that test the individual components. These are in
seedu.ultistudent.ui
package.
-
-
Non-GUI Tests - These are tests not involving the GUI. They include,
-
Unit tests targeting the lowest level methods/classes.
e.g.seedu.ultistudent.commons.StringUtilTest
-
Integration tests that are checking the integration of multiple code units (those code units are assumed to be working).
e.g.seedu.ultistudent.storage.StorageManagerTest
-
Hybrids of unit and integration tests. These test are checking multiple code units as well as how the are connected together.
e.g.seedu.ultistudent.logic.LogicManagerTest
-
6.3. Troubleshooting Testing
Problem: HelpWindowTest
fails with a NullPointerException
.
-
Reason: One of its dependencies,
HelpWindow.html
insrc/main/resources/docs
is missing. -
Solution: Execute Gradle task
processResources
.
7. Dev Ops
7.1. Build Automation
See UsingGradle.adoc to learn how to use Gradle for build automation.
7.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.
7.3. Coverage Reporting
We use Coveralls to track the code coverage of our projects. See UsingCoveralls.adoc for more details.
7.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.
7.5. Making a Release
Here are the steps to create a new release.
-
Update the version number in
MainApp.java
. -
Generate a JAR file using Gradle.
-
Tag the repo with the version number. e.g.
v0.1
-
Create a new release using GitHub and upload the JAR file you created.
7.6. Managing Dependencies
A project often depends on third-party libraries. For example, UltiStudent depends on the Jackson library for JSON parsing. Managing these dependencies can be automated using Gradle. For example, Gradle can download the dependencies automatically, which is better than these alternatives:
-
Include those libraries in the repo (this bloats the repo size)
-
Require developers to download those libraries manually (this creates extra work for developers)
Appendix A: Product Scope
Target user profile:
-
university student
-
prefer desktop apps over other types
-
can type fast
-
prefers typing over mouse input
-
is reasonably comfortable using CLI apps
Value proposition: manage student life faster and better than a typical mouse/GUI driven app
Appendix B: User Stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
|
new user |
see usage instructions |
refer to instructions when I forget how to use the App |
|
user |
add a new person |
|
|
user |
delete a person |
remove entries that I no longer need |
|
user |
find a person by name |
locate details of persons without having to go through the entire list |
|
user |
hide private contact details by default |
minimize chance of someone else seeing them by accident |
|
user with many persons in the UltiStudent |
sort persons by name |
locate a person easily |
{More to be added}
Appendix C: Use Cases
(For all use cases below, the System is the AddressBook
and the Actor is the user
, unless specified otherwise)
Use case: Delete person
MSS
-
User requests to list persons
-
AddressBook shows a list of persons
-
User requests to delete a specific person in the list
-
AddressBook deletes the person
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. AddressBook shows an error message.
Use case resumes at step 2.
-
{More to be added}
Appendix D: Non Functional Requirements
-
Should work on any mainstream OS as long as it has Java
9
or higher installed. -
Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.
-
A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
{More to be added}
Appendix F: Product Survey
Product Name
Author: …
Pros:
-
…
-
…
Cons:
-
…
-
…
Appendix G: 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. |
G.1. Launch and Shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file
Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to a different location. Close the window.
-
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-
G.2. Opening a manager
-
Opening respective manager with the command:
open
-
Prerequisites: Currently in Homework Manager with Homework icon being highlighted.
-
Test case:
open HomeworkManager
Expected: UI does not change changes -
Prerequisites: Currently in other Manager with Homework icon not being highlighted.
-
Test case:
open HomeworkManager
Expected: HomeworkManager is opened and GUI of HomeworkManager is shown -
Prerequisites: Currently in Notes Manager with Notes icon being highlighted.
-
Test case:
open NotesManager
Expected: UI does not change changes -
Prerequisites: Currently in other Manager with Homework icon not being highlighted.
-
Test case:
open NotesManager
Expected: NotesManager is opened and GUI of NotesManager is shown -
Prerequisites: Currently in Cap Manager with Notes icon being highlighted.
-
Test case:
open CapManager
Expected: UI does not change changes -
Prerequisites: Currently in other Manager with Homework icon not being highlighted.
-
Test case:
open CapManager
Expected: CapManager is opened and GUI of CapManager is shown
-
G.3. Adding a homework
Adding a homework with the command: add-hw
-
Prerequisites: HomeworkManager has to be opened to see changes on GUI. (i.e. "open HomeworkManager" command has to be ran first)
-
Test case:
add-hw mc/CS2103T hw/Tutorial 1 d/22/05/2019
Expected: A homework will be added into the list of homework in the Homework Main Panel. The module code in which homework belongs to is also added in the Homework SubPanel list if not present before. -
Test case:
add-hw mc/CSXXXXT hw/Tutorial 1 d/22/05/2019
Expected: No homework is added. Error details will be shown in the status message. -
Other incorrect add-hw commands to try :
add-hw
,add-hw mc/CS2103T hw/Tutorial 1 d/dd/MM/YYYY
(where dd/MM/YYYY is a past date)
Expected: Similar to previous.
G.4. Deleting a homework entry
-
Deleting a homework while all homework are listed with the command:
delete-hw
-
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil autonmatically generates sample data when the json file is empty.
-
Test case:
delete-hw 1
Expected: First homework is deleted from the list. Details of the deleted homework shown in the status message. Timestamp in the status bar is updated. -
Test case:
delete-hw 0
Expected: No homework is deleted. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete-hw
,delete-hw x
(where x is larger than the list size)
Expected: Similar to previous.
-
G.5. Editing a homework entry
Edit a homework while all homework are listed with the command: edit-hw
-
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil automatically generates sample data when the json file is empty.
-
Test case:
edit-hw 1 d/30/05/2019
Expected: The deadline of the first homework is changed to 30/05/2019. Details of the edited homework shown in the status message. Timestamp in the status bar is updated. -
Test case:
edit-hw 0
Expected: No homework is edited. Error details shown in the status message. Status bar remains the same. -
Other incorrect edit commands to try:
edit-hw
,edit-hw x
(where x is larger than the list size),edit-hw 30/05/2019
Expected: Similar to previous.
G.6. Finding homework entries of which contains this module
Finds homework that has a homework module and displays these modules in a list with the command: find-mod
-
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil automatically generates sample data when the json file is empty.
-
Test case:
find-mod CS2030
Expected: The homework list displays homeworks that has CS2030 as part of its homework module. -
Test case:
find-mod x
where x is any module code that is not present in the module code list.
Expected: No homework is displayed in the homework list. Status bar shows that "0 homework listed!"
G.7. List all homework entries
Lists all existing homework entries with the command: list-hw
-
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil automatically generates sample data when the json file is empty.
-
Test case:
find-mod CS2030
followed bylist-hw
Expected: The homework list displays all existing homework entry.
G.8. Adding a note
Adding a note with the command: add-note
-
Prerequisites: NotesManager has to be opened. (i.e. "open NotesManager" command has to be ran first)
-
Test case:
add-note mc/CS2103T n/Week 7 Tutorial
Expected: A note will be added into the list of note in the Notes Main Panel. -
Test case:
add-note mc/CSXXXXT n/Tutorial 1
Expected: No note is added. Error details will be shown in the status message. -
Other incorrect add-note commands to try :
add-note
,add-note mc/CS2103T n/
(where note name is a whitespace) Expected: Similar to previous.
G.9. Deleting a note
-
Deleting a note while all note are listed with the command:
delete-note
-
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil autonmatically generates sample data when the json file is empty.
-
Test case:
delete-note 1
Expected: First note is deleted from the list. Details of the deleted note shown in the status message. Timestamp in the status bar is updated. -
Test case:
delete-note 0
Expected: No note is deleted. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete-note
,delete-note x
(where x is larger than the list size)
Expected: Similar to previous.
-
G.10. Editing a Note
Editing a note with the command : edit-note
-
Prerequisites: NotesManager has to be opened (i.e.
open NotesManager
command has to be ran first). Multiple notes in the notes list. -
Test case:
edit-note 1
Expected: First note will be selected and the contents of the selected note will be populated in the text area in the NotesMainPanel. -
Test case:
edit-note 0
Expected: No note will be selected. Error details will be shown in the status message. -
Other incorrect edit note commands to try:
edit-note
Expected: Similar to previous.
G.11. Saving a Note
Saving a note with the command : save-note
-
Prerequisites: NotesManager has to be opened (i.e.
open NotesManager
command has to be ran first). Multiple notes in the notes list. A note has to be selected (i.eedit-note INDEX
command has to ran to select a note atINDEX
) -
Test case:
save-note
Expected: Contents of selected note will be saved. Details of note will be shown in the status message. -
Prerequisites: NotesManager has to be opened and no note is being selected.
-
Test case:
save-note
Expected: Error details will be shown in the status message.
G.12. Adding a cap entry
Adding a cap entry while all cap entries are listed with the command: add-cap
-
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil automatically generates sample Data when the UltiStudent.json file is corrupted or unavailable.
-
Test case:
add-cap mc/CS3203 g/B mcs/8 sem/Y1S1
Expected: Cap entry with module code CS1010, grade of B, 4MCs, Y1S1 is added. Details of the first cap entry shown in the status message. Timestamp in the status bar is updated. CAP score displayed is updated. -
Test case:
add-cap mc/CS3203 g/B mcs/100 sem/Y1S1
Expected: No cap entry is added. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. -
Test case:
add-cap mc/CS55555 g/B mcs/100 sem/Y1S1
Expected: No cap entry is added. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. -
Test case:
add-cap mc/CS55555 g/B mcs/100 sem/Y1S3
Expected: No cap entry is added. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. -
Other incorrect edit commands to try:
add-cap mc/1234 g/A+ mcs/4 sem/Y2S2
{give more}
Expected: Similar to previous.
G.13. Deleting a cap entry
Deleting a cap entry while all cap entries are listed with the command: delete-cap
-
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil automatically generates sample Data when the UltiStudent.json file is corrupted or unavailable.
-
Test case:
delete-cap 1
Expected: First cap entry is deleted. Details of the deleted cap entry shown in the status message. Timestamp in the status bar is updated. CAP score displayed is updated. -
Test case:
delete-cap 0
Expected: No cap entry is deleted. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. -
Test case:
delete-cap x
where x is larger than the list size
Expected: No cap entry is deleted. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. -
Test case:
delete-cap x
where x is negative number
Expected: No cap entry is deleted. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. -
Other incorrect delete commands to try:
delete
,delete x
(where x is larger than the list size) {give more}
Expected: Similar to previous.
G.14. Editing a cap entry
Editing a cap entry while all cap entries are listed with the command: edit-cap
-
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil automatically generates sample Data when the UltiStudent.json file is corrupted or unavailable.
-
Test case:
edit-cap 1 g/A mcs/4
Expected: First cap entry is edited. Details of the first cap entry shown in the status message. Timestamp in the status bar is updated. CAP score displayed is updated. -
Test case:
edit-cap 0 g/A mcs/4
Expected: No cap entry is edit. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. -
Test case:
edit-cap x g/B mcs/4
where x is larger than the list size
Expected: No cap entry is deleted. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. -
Test case:
edit-cap x g/B mcs/4
where x is negative number
Expected: No cap entry is deleted. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. -
Other incorrect edit commands to try:
edit
,edit x
(where x is larger than the list size) {give more}
Expected: Similar to previous.