Skip to content

Latest commit

 

History

History
1868 lines (1418 loc) · 91.2 KB

DeveloperGuide.adoc

File metadata and controls

1868 lines (1418 loc) · 91.2 KB

PlanMySem - Developer Guide

By: T08-3 Since: Jan 2019 Licence: MIT

1. Introduction

Welcome to PlanMySem!

PlanMySem is a text-based (Command Line Interface) scheduling/calendar application that caters to NUS students and staff who prefer to use a desktop application for managing their schedule/calendar. PlanMySem automatically creates a planner that is synchronised according to the NUS academic calendar for the current semester and enables easy creation, editing and deleting of items. Special weeks such as recess week and reading week are taken into account within our unique recursion system. Items can then be efficiently managed via the intuitive tagging system.

PlanMySem is optimized for those who prefer to work with a Command Line Interface (CLI) and/or are learning to work more efficiently with CLI tools. Additionally, unlike traditional calendar/scheduling applications, PlanMySem utilizes minimal resources on the user’s machine while still allowing the user to view their schedules swiftly and efficiently. ​

2. About this Developer Guide

This developer guide provides a detailed documentation on the implementation of all the various features PlanMySem offers. To navigate between the different sections, you could use the table of contents above.

For ease of communication, this document will refer to lessons/activities/events/appointments that you might add into the planner as slots.

Additionally, throughout this developer guide, there will be various icons used as described below.

💡
This is a tip. Follow these suggested tips to make your life much simpler when using PlanMySem!
ℹ️
This is a note. These are things for you to take note of when using PlanMySem.
This is a sign-post dictating important information. These are information that you will surely need to know to use PlanMySem efficiently.
🔥
This is a sign-post informing caution. Please take note of these items and exercise some care.
⚠️
This is a rule. Ensure that you follow these rules to ensure proper usage of PlanMySem. ​

3. Setting up

3.1. Prerequisites

  1. JDK 9 or later

    ⚠️
    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

    ℹ️
    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. ​

3.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. Run the PlanMySem.Main class (right-click the Main class and click Run Main.main()) and try executing a few commands

  9. Run all the tests (right-click the test folder, and click Run 'All Tests') and ensure that they pass

  10. Open the StorageFile file and check for any code errors

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

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

3.3. Verifying the setup

  1. Run the PlanMySem.Main and try a few commands

  2. Run the tests to ensure they all pass. ​

3.4. Configurations to do before writing code

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

3.4.2. Updating documentation to match your fork

After forking the repo, the documentation will still have the PlanMySem branding and refer to the https://github.com/CS2113-AY1819S2-T08-3/main repo.

If you plan to develop this fork as a separate product (i.e. instead of contributing to https://github.com/CS2113-AY1819S2-T08-3/main), 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. ​

3.4.3. Setting up CI

Set up Travis to perform Continuous Integration (CI) for your fork. See UsingTravis.adoc to learn how to set it up.

After setting up Travis, you can optionally set up coverage reporting for your team fork (see UsingCoveralls.adoc).

ℹ️
Coverage reporting could be useful for a team repository that hosts the final version but it is not that useful for your personal fork.

Optionally, you can set up AppVeyor as a second CI (see UsingAppVeyor.adoc).

ℹ️
Having both Travis and AppVeyor ensures your App works on both Unix-based platforms and Windows-based platforms (Travis is Unix-based and AppVeyor is Windows-based) ​

3.4.4. Getting started with coding

When you are ready to start coding,

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

  2. Take a look at [GetStartedProgramming]. ​

4. Design

4.1. Architecture

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

Common represents a collection of classes used by multiple other components.

The following class plays an important role at the architecture level, 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.

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.

SDforDeleteSlot
Figure 2. Component interactions for delete 1 command

The sections below give more details of each component. ​

4.2. UI component

UiComponentClassDiagram
Figure 3. Structure of the UI Component

API : Ui.java

The UI consists of a MainWindow that is made up of just a TextField commandInput and a TextArea outputConsole. This application is mainly a text-based application, hence there are not many components here.

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 read from commandInput, using the Logic component.

  • Displays commandResult to the user via outputConsole. ​

4.3. Logic component

LogicComponentClassDiagram
Figure 4. Structure of the Logic Component

API : Logic.java

the Logic component,

  1. Uses the parser class to parse the user command.

    • This results in a Command object which is executed.

  2. The command execution can affect the Model (e.g. adding a Slot).

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

  4. In addition, the CommandResult object can also instruct the Ui to display results, 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.

SDforDeleteSlot
Figure 5. Interactions Inside the Logic Component for the delete 1 Command

4.4. Model component

ModelComponentClassDiagram
Figure 6. Overall structure of the Model Component

API : Model.java

The Model component

  • stores the Planner data.

  • does not depend on any of the other three components. ​

4.5. Storage component

API : Storage.java

The Storage component saves the Planner data in XML format and read it back.

This functionality is provided via Java Architecture for XML Binding (JAXB), a software framework that maps Java classes to XML representations. In summary, JAXB allows storing and retrieving data in memory in any XML format. More information about JAXB can be obtain from Oracle.

To represents XML content as Java objects, "adapted" classes are used to represent and allow conversion of un-mappable objects into mappable objects. ​

4.6. Common classes

Classes used by multiple components are in the PlanMySem.common package. ​

5. Implementation

This section describes some noteworthy details on how certain features are implemented.

5.1. Initialization of the Planner and its Semester

The Planner and its Semester has to be initialized for PlanMySem to work as all other features of PlanMySem would interact with this Semester object. The initialization is automated and dynamic to ensure sustainability. ​

5.1.1. Current Implementation

Upon launching PlanMySem, the initialization of the Planner and its Semester would be implemented via two steps:

  1. Automatically generate the academic calendar from the current date.

  2. Setup current Semester from the academic calendar.

The academic calendar is dynamically generated by invoking the function generateSemester in the Semester class. The function will first retrieve the current date from the system clock to determine which academic year it is. As a new academic year starts from August, it can be determined from the month of the current date.

  • If the current date is before August, the current academic year is "the previous year / current year".
    e.g. If the date is 25/3/2019, the academic year is "2018 / 2019".

  • If the current date is after August, the current academic year is "the current year / next year".
    e.g. If the date is 25/8/2019, the academic year is "2019 / 2020".

After determining the academic year, the details of the semesters will be generated. All the weeks of the academic year can be calculated from the first day of semester 1 since each semester has a fixed amount of weeks.

ℹ️
Semester 1 of the academic year starts with an orientation week and will always begin from the first Monday of August.
  • Semester 1 has 18 weeks (inclusive of orientation week) and semester 2 has 17 weeks.

  • The vacation between semester 1 and 2 has 5 weeks.

  • The vacation between academic years will have 12 or 13 weeks depending on the starting week of the next academic year.

Each week of the year will correspond to an academic week and this information will be stored in a HashMap for efficient retrieval. This HashMap can be used to determine the academic week given a date (by finding out the week of the year for that date). The tables below shows an example of the relation between academic week and the week of the year for academic year 2018/2019.

Table 1. Weeks in academic year 2018/2019, Semester 1.
Academic Week Example (Week of the year) Example (Period)

Orientation Week

32

6 Aug 2018 (First Monday of Aug 2018) - 12 Aug 2018

Week 1 - 6

33 - 38

13 Aug 2018 - 23 Sep 2018

Recess Week

39

24 Sep 2018 - 30 Sep 2018

Week 7 - 13

40 - 46

1 Oct 2018 - 18 Nov 2018

Reading Week

47

19 Nov 2018 - 25 Nov 2018

Examination Week

48 - 49

26 Nov 2018 - 9 Dec 2018

Vacation

50 - 52

10 Dec 2018 - 30 Dec 2018

Vacation

1 - 2

31 Dec 2018 - 13 Jan 2019

Table 2. Weeks in academic year 2018/2019, Semester 2.
Academic Week Example (Week of the year) Example (Period)

Week 1 - 6

3 - 8

14 Jan 2019 - 24 Feb 2019

Recess Week

9

25 Feb 2019 - 3 Mar 2019

Week 7 - 13

10 - 16

4 Mar 2019 - 21 Apr 2019

Reading Week

17

22 Apr 2019 - 28 Apr 2019

Examination Week

18 - 19

29 Apr 2019 - 12 May 2019

Vacation

20 - 31

12 weeks duration

Hence, the information listed below can be determined from the current date.

  • Current academic week

  • Current academic semester

  • Current academic year

  • Number of weeks in current academic semester

  • Start date of current academic semester

  • End date of current academic semester

These information would be assigned to the Semester object upon initialization of the Planner. ​

5.1.2. Design Considerations

This section details an aspect which we carefully considered for the initialization of the Planner and its Semester.

Aspect: Generation of academic calendar
  • Alternative 1 (current choice): Generate academic calendar by performing calculations from the current date.

    • Pros: Generation of academic calendar is dynamic and will work for future dates.

    • Cons: Computationally expensive as many operations have to be performed.

  • Alternative 2: Retrieve academic calendar from a pre-generated file.

    • Pros: Generation of academic calendar is efficient and not prone to calculation errors.

    • Cons: Requires the pre-generated file which may be accidentally edited or deleted by the user.

We chose alternative 1 as we wanted PlanMySem to be sustainable and continue working for future dates. The cons for alternative 2 also outweighs the cons for alternative 1 as editing or deleting the pre-generated file could potentially break the application. Hence, we implemented alternative 1 as it is a more suitable choice. ​

5.2. Parser / Command Format and Structure

Due to the flexibility and huge variation of the envisioned command format and structures, it was decided that it was more appropriate to create a new Parser instead of relying on the existing regex implementation in AB3 for heavy parsing.

The AB3 parser was heavily modified to serve unordered command parameters as well as to allow more flexibility such that mistakes in commands will still be interpreted as valid as long as the "minimal" set of parameters are present. Regex is currently only used to retrieve the command keywords and arguments. Arguments are then parsed via 2 different methods/techniques according to the format and structure of the command keyword. ​

5.2.1. Current Implementation

  • Ordering of parameters are ignored when possible.

  • Repeated parameters are ignored. The first parameter of the same "type" are taken as valid, the rest are discarded.

  • Alternate formats of commands are implemented to give freedom of choice and cater to different types of users with different personalities and comfort levels.

  • Shortened versions of command keywords are implemented to give ways for users to shorten commands and be more efficient.

Hence, parameters in PlanMySem can be categorised into 2 categories:

  1. Prefixed parameters such as n/NAME, st/START_TIME, des/DESCRIPTION, etc.

  2. Non-Prefixed parameters, A.K.A. keywords, such as INDEX, TYPE_OF_VIEW. etc. ​

Parsing Prefixed Parameters

To retrieve parameters, the function private static HashMap<String, Set<String>> getParametersWithArguments(String args) can be called. The keys of the returned HashMap represent prefixes while the values represent the prefix’s parameters, held in a set. This allows for easy, quick and efficient access to specific prefixes and its parameters; O(1) access, insertion and removal.

The results of getParametersWithArguments can be interpreted in these manners:

  • When the returned set of parameters, to a specific prefix, is null, then both the prefix and parameters was not keyed in at all.

  • When the returned set of parameters, to a specific prefix, is not null but contains empty strings such that string.isEmpty() returns true, then the prefix was keyed in but the parameter was left blank.

The values of the returned HashMap is a Set, hence, there is no need to handle repeated parameters of a specific prefix as they will be automatically discarded. ​

Parsing Keywords

To retrieve keywords, the function private String getStartingArgument(String args) can be called. Here, keywords are thought of as parameters that are not prefixed. In PlanMySem, keywords are utilized in command structures when they are to be used alone or when order of parameters are important. In such cases, there is no logical need for prefixing as the meaning of these parameters can be identified.

The results of getStartingArgument can be interpreted in these manners:

  • When the keyword is null, then the parameter was not keyed in.

  • When the keyword data type does not match the intended, then the parameter was keyed in wrongly or is mis-ordered.

ℹ️
Additional keywords are not handled and ignored to provide ease of use and cater to user mistakes. ​

5.2.2. Design Considerations

Here are the considerations that led to the new parsing system. In both cases, choices were made were largely due to the fact that they provide a better user experience and ease of use. ​

Aspect: Handling repeated parameters
  • Alternative 1 (current choice): When possible, accept repeated parameters.

    • Pros: Less computationally expensive and allow users to make minor mistakes.

    • Cons: User errors may be misinterpreted and hence wrong actions may be executed.

  • Alternative 2: Always accept and handle repeated parameters.

    • Pros: Errors are shown to the user so that the invalid command may be fixed.

    • Cons: Force user to rewrite commands, even in the event of simple/minor mistakes, and thus may hinder user experience and ease of use. ​

Aspect: Handling order of parameters
  • Alternative 1 (current choice): Parse parameters without regards to order.

    • Pros: Greater user experience due to greater ease of use.

    • Cons: More computationally expensive and tougher development process due to more cases to care for, requires manual parsing.

  • Alternative 2: Accept only a specific ordering of parameters.

    • Pros: Less computationally expensive and short development process, able to use existing regex solutions in AB3.

    • Cons: Greatly hinder user experience as order of parameters have no relation to meaning of commands. ​

5.2.3. Future Implementation

Though the current implementation has much flexibility, there is more that can be done to elevate user experience to the next level. These are some possible enhancements:

  1. Parse a larger variety of date and time formats.

  2. Parse time as a single parameter instead of two.

  3. Enhance function calls to retrieve prepended parameters and keywords to handle trivial cases that should invoke ParseException. ​

5.3. Slot Management

Slot Management involves mainly the interaction between the users and their slots.

The section below will describe in detail the Current Implementation, Design Considerations and Future Implementation of the Slot Management. ​

5.3.1. Current Implementation

Users are able to perform three actions (or commands), though a small variety of methods, involving slots:

  • Add

    • Add multiple slots via the recursion system.

    • Add a single slot via omitting the recursion system.

  • Edit

    • Edit multiple slots via tags.

    • Edit a single slot via index.

  • Delete

    • Delete slots via tags.

    • Delete a single slot via index.

The Add command heavily relies on the recursion system to select multiple dates in which to add the same slot to multiple days. Additionally, the Add command also allows users to input tags to tag slots.

The Edit and Delete command then makes use of the tagging system to then select multiple slots for editing/deleting. ​

5.3.2. Design Considerations

Here are the considerations regarding slot management. ​

Aspect: Wrapping of data in Slot

The topic of whether to wrap all primitives and Strings, in Java, is contentious. However, in this case of PlanMySem, there are no possible invalid values for any of the data that Slot holds, other than the / character that would have already been handled by parser. For instance, any String is a valid name and the same goes for location, description and etc; wrapping these data will not achieve any narrowing of possible valid inputs.

Hence, data in Slot are not wrapped. This is in accordance to the You aren’t gonna need it (YAGNI) principle. ​

Aspect: Storing and accessing Slots
  • Alternative 1 (current implementation): Use of Map, such as HashMap to store Days that store Slots.

    • Pros: HashMap allows for easier and faster, O(1) access time, access of particular Day according to date.

    • Cons: This requires splitting of the calendar into days, as such there is no easy way to account for Slots that occur across days.

  • Alternative 2: Store Slots in a huge list.

    • Pros: Allows for easier access by "index" and offers flexibility, for example, in the time of slots.

    • Cons: Expensive to access, add and remove items. Furthermore, it is extremely expensive to collect slots that occur in a day, a very important and most likely to be a commonly used feature.

Alternative 1 was chosen as the benefits of quick and easy access to days outweigh the disadvantages involve with forbidding slots than span over a day. After all, there are few cases of slots crossing the boundaries of a day, over midnight. ​

5.3.3. Future Implementation

Create a class to represent Days, instead of utilising a HashMap

Currently, Days are held in a HashMap of key LocalDate and value Day. While this works without any loss in performance, this causes duplication of code and removes some key concepts of abstraction. For example, there are code blocks dedicated to retrieving days or slots that could have been placed into this new class. This is an issue as these code have nothing to do with for instance, Semester but they are placed there.

Therefore, this needs to be implemented in the future to achieve less coupling, more cohesion and respect the Single Responsibility Principle (SRP), Open-Closed Principle (OCP) and Separation of Concerns Principle (SoC). ​

Planner to hold multiple Semesters

While PlanMySem now allow users to work on the current semester, it is unable to cater to future semesters. For instance when a semester is about to end, users are not able to plan ahead for the coming semester.

This is an issue that plagues user experience and is a significant problem. To solve this issue, Planner needs to hold multiple semesters in a List and more features need to be included to allow saving, loading and switching of semesters and etc. ​

5.4. List feature

5.4.1. Current Implementation

The list function supports searching using a single keyword.

The keyword is compared to all names/tags of all Slots existing in Planner.

If an exact match is found, the Slot will be added to the output list. ​

5.5. Find feature

5.5.1. Current Implementation

The find function supports searching using a single keyword.

ℹ️
The name/tag of the Slot MUST contain the specified keyword in order for a match to occur. Completely different keywords do not constitute a match.

The matching Slots are then weighted based on their name/tag’s Levenshtein Distance from the keyword.

💡
A low Levenshtein Distance is attributed to a high level of similarity between the name/tag and the keyword. (A value of 0 constitutes an exact match.)
The maximum Levenshtein Distance set in PlanMySem is 20.

The weighted Slots are inserted into a PriorityQueue and the closest matching Slots will be polled into the output list.

Upon executing the find command with valid parameters, a sequence of events is executed. The sequence of events illustrated in the Sequence Diagram below will be in reference to the execution of a find n/keyword command. The sequence of events are as follows:

  1. Upon calling the execute method of the Logic component, the Logic component would then parse the find n/keyword command.

  2. LogicManager then invokes the parseCommand function of ParserManager.

  3. ParserManager in turn invokes the parse function of the appropriate parser for the find command which in this case, is FindCommandParser.

  4. After parsing is done, FindCommandParser would instantiate the FindCommand object which would be returned to the LogicManager.

  5. LogicManager is then able to invoke the execute function of the returned FindCommand object.

  6. The command execution will call the getDays method of the FindCommand object which retrieves data from the Model component (i.e. retrieving data from the current Semester).

  7. FindCommand will execute the getDiscoveredNames method to find the closely matching Slots with names containing 'keyword'.

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

  9. In addition, the CommandResult object can also instruct the Ui to display results, such as displaying help to the user.

To give a graphical summary of the above process, a Sequence Diagram detailing the execution of the find n/keyword command is provided below.

FindSequenceDiagram
Figure 7. Sequence of Interactions between Components for the find n/keyword Command

The Communication Diagram below summarises the data links between the various objects in the find command.

FindCommunicationDiagram
Figure 8. Data Interactions between Components for the find n/keyword Command

5.5.2. Design Considerations

Aspect: What constitutes a positive search result in find command

No.

Alternatives

Pros

Cons

Past Implementation 1

Positive search result by strictly matching the entered keyword

Easy to implement.

Search must be exact, typos or an incomplete keyword will yield incorrect results. Nothing different from List feature.

Past Implementation 2

Positive search result as long as name/tag contains the keyword.

Searches will detect names/tags similar to the keyword.

Output list will be longer. May become excessively long if short keyword is provided.

Current Implementation

Store the search results in a PriorityQueue ordered by their Levenshtein distances from the search keyword.

Searches are ordered by a degree of similarity, instead of the random order of names/tags in Past Implementation 2.

Adds complexities in finding and searching.

5.6. View feature

This feature presents the planner in different formats to the user. The available formats are the month view, week view, and the day view. This section will detail how this feature is implemented. ​

5.6.1. Current Implementation

Upon invoking the view command with valid parameters (refer to UserGuide.adoc for view usage), a sequence of events is executed. For clarity, the sequence of events will be in reference to the execution of a view month command. A graphical representation is also included in the Sequence Diagram below for your reference when following through the sequence of events. The sequence of events are as follows:

  1. Firstly, the view month command is passed into the execute function of LogicManager to be parsed.

  2. LogicManager then invokes the parseCommand function of ParserManager.

  3. ParserManager in turn invokes the parse function of the appropriate parser for the view command which in this case, is ViewCommandParser.

    ℹ️
    The view command can be parsed into only 3 general types of views which are the month, week or day view as specified in the command parameter.
  4. After parsing is done, ViewCommandParser would instantiate the ViewCommand object which would be returned to the LogicManager.

  5. LogicManager is then able to invoke the execute function of the returned ViewCommand object.

  6. In the execute function of the ViewCommand object, data will be retrieved from the Model component (i.e. retrieving data from the current Semester).

  7. Now that the ViewCommand object has the data of the current semester, it is able to invoke the displayMonthView method.

  8. With the output returned from the displayMonthView, the CommandResult object will be instantiated.

  9. This CommandResult object would be returned to the LogicManager which then returns the same CommandResult object back to the UI component.

  10. Finally, the UI component would display the contents of the CommandResult object to the user. For this view month command, the displayed result would be the monthly calendar view of all months in the current semester.

ViewMonthSequenceDiagram
Figure 9. Sequence Diagram upon executing the view month command.

The 3 general types of view (month, week, day) are generated by the methods displayMonthView, displayWeekView, displayDetailedWeekView, displayDayView from the ViewCommand class and the implementation of these methods is explained below.

displayMonthView method displays all the months of the current semester in a monthly calendar format. Each academic week of the semester is also indicated in the display. The implementation of this method can be broken down into 3 parts:

  1. Print month header (e.g. January 2019) and calculate required amount of whitespace before the 1st of the month.

  2. Print all days of the month using a loop.

    • Append academic week after each Saturday or last day of month.

  3. Repeat parts 1 and 2 for every month in the semester.

displayWeekView method displays the weekly calendar format of a specified week. The implementation of this method can be broken down into the following steps:

  1. Print academic week header (e.g. Week 13 of Sem 2).

  2. Retrieve all days of the week and for each day, retrieve its slots into an ArrayList.

  3. For each day, print the slot details (only start time, end time and a shortened title) and remove the slot from the ArrayList.

  4. Repeat step 3 until the ArrayList of slots for each day is empty.

displayDayView method displays the details of all slots of a specified day. The implementation of this method can be broken down into 2 parts:

  1. Retrieve all slots for the specified day.

  2. Print all details of each slot found.

displayDetailedWeekView method displays the details of all slots of a specified week since displayWeekView only shows a formatted and summarised week view. The implementation of this method can be broken down into the following steps:

  1. Print academic week header (e.g. Week 13 of Sem 2).

  2. Retrieve all days of the week.

  3. For each day, print all details of all slots via the displayDayView method. ​

5.6.2. Design Considerations

This section details our considerations for the implementation of the view feature.

Aspect: Functionality of view week command
  • Alternative 1 (current choice): Option for user to display a formatted summarised week view or a detailed week view.

    • Pros: The formatted summarised week view is uncluttered. User given the choice and flexibility for the week view.

    • Cons: User is required to spend a little more time to specify an additional parameter in the view week command.

  • Alternative 2: Only a single formatted week view which displays details of all slots in the specified week.

    • Pros: Efficient for the user as user is only required to enter a single command to view all details of all slots.

    • Cons: The formatted week view will be too cluttered as there are too many slots and lots of details. Formatting is an issue as well as details of each slot can be of varying lengths.

Alternative 1 was chosen to be implemented as it gives the user freedom of choice to select the degree of details to be displayed in the output of the view week command. The output of alternative 1 is also less cluttered than alternative 2 and thus enhances the presentability of PlanMySem. ​

5.7. Undo/Redo feature

5.7.1. Current Implementation

The undo/redo mechanism is facilitated by VersionedPlanner.

ℹ️
Only Add, Edit and Delete commands can be undone/redone.

It extends Planner with an undo/redo history, stored internally as an plannerStateList and currentStatePointer. Additionally, it implements the following operations:

  • VersionedPlanner#commit() — Saves the current planner state in its history.

  • VersionedPlanner#undo() — Restores the previous planner state from its history.

  • VersionedPlanner#redo() — Restores a previously undone planner state from its history.

These operations are exposed in the Model interface as Model#commitPlanner(), Model#undoPlanner() and Model#redoPlanner() 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 VersionedPlanner will be initialized with the initial planner state, and the currentStatePointer pointing to that single planner state.

UndoRedoStartingStateListDiagram

Step 2. The user executes delete 5 command to delete the 5th Slot in the planner. The delete command calls Model#commitPlanner(), causing the modified state of the planner after the delete 5 command executes to be saved in the plannerStateList, and the currentStatePointer is shifted to the newly inserted planner state.

UndoRedoNewCommand1StateListDiagram

Step 3. The user executes add n/CS2113T …​ to add a new slot. The add command also calls Model#commitPlanner(), causing another modified planner state to be saved into the plannerStateList.

UndoRedoNewCommand2StateListDiagram

ℹ️
If a command fails its execution, it will not call Model#commitPlanner(), so the planner state will not be saved into the plannerStateList.

Step 4. The user now decides that adding the Slot was a mistake, and decides to undo that action by executing the undo command. The undo command will call Model#undo(), which will shift the currentStatePointer once to the left, pointing it to the previous planner state, and restores the planner to that state.

UndoRedoExecuteUndoStateListDiagram

ℹ️
If the currentStatePointer is at index 0, pointing to the initial planner state, then there are no previous planner states to restore. The undo command uses Model#canUndo() 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#redoPlanner(), which shifts the currentStatePointer once to the right, pointing to the previously undone state, and restores the planner to that state.

ℹ️
If the currentStatePointer is at index plannerStateList.size() - 1, pointing to the latest planner state, then there are no undone planner states to restore. The redo command uses Model#canRedo() 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 planner, such as list, will usually not call Model#commitPlanner(), Model#undoPlanner() or Model#redoPlanner(). Thus, the plannerStateList remains unchanged.

UndoRedoNewCommand3StateListDiagram

Step 6. The user executes clear, which calls Model#commitPlanner(). Since the currentStatePointer is not pointing at the end of the plannerStateList, all planner 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

5.7.2. Design Considerations

Aspect: How undo & redo executes
  • Alternative 1 (current choice): Saves the entire planner.

    • 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 person 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 planner 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 VersionedPlanner.

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

5.8. Data Exporting / Exporting feature

This feature exports the Planner into a .ics file. This section will detail how this feature is implemented. ​

5.8.1. Current Implementation

Upon entering the export command with valid parameters (refer to UserGuide.adoc for export usage), the following sequence of events is executed:

  1. The ParserManager parses the export command and calls the parse method in ExportCommandParser.

  2. The ExportCommandParser then constructs a ExportCommand object with a filename.

  3. The Command object is returned and execution will get the current Semester from Model

  4. The IcsSemester is then constructed using Semester and converted to a String.

  5. The String is then written to a file with the filename parsed.

  6. The result of the command execution, CommandResult, will then returned to Ui.

Given below is the Sequence Diagram upon executing the export command.

ExportCommandSequenceDiagram
Figure 10. Sequence of implementation for the export Command

​ The ExportCommandParser will check whether the optional filename parameter was input. If this parameter is included, the input filename is used. Else, if no other characters have been input (e.g. "export"), the default "PlanMySem" is used as the filename. This process can be seen from the activity diagram in the figure below.

ExportCommandActivityDiagram
Figure 11. Activity diagram showing the workflows for export Command

5.8.2. Design Considerations

This portion explains alternative implementations as well as the rationale behind my chosen method.

Aspect: Using a .ics library
  • Alternative 1 (current choice): Writing my own .ics file.

    • Pros: No need to include and understand how to use the external library.

    • Cons: Difficult to read and work with .ics formatting.

  • Alternative 2: Using iCal4j library to read and write .ics files.

    • Pros: No need to manually format data into .ics format.

    • Cons: Difficult to translate our recursion system to the .ics RRULE system.

Reason for current choice: Using the library will allow PlanMySem to easily import non-native .ics files. However, this would require changes to Model as currently the recurrence for slots is not saved.

In addition, as our application is a specially designed planner for NUS matters, I felt that it was unnecessary to have the same slots on multiple applications.

Hence, I chose to code the reading and writing of .ics files and add a disclaimer that importing of non-native .ics files is likely to cause errors. ​

5.9. Data Encryption / Decryption feature

The storage file "PlanMySem.txt" is encrypted to prevent easy access of the user’s calendar.

5.9.1. Current Implementation

We are encrypting and decrypting the data using the Java Cipher. This feature is implemented through the Encryptor that contains the encrypt and decrypt methods. The encrypt method takes a String as an argument and returns a encrypted String object. The decrypt method takes in a String object as an argument and returns the decrypted message as a String object.

The encryption is done using AES/CBC/PKCS5Padding. The key used for encryption/decryption is generated through various device parameters such as username, operating system (OS) and java runtime version. The secret key generated is stored in a file named "KeyStorage.jceks". No password is required from the user to retrieve this key, but a password input can be added to KeyStorage to improve security.

A initialization vector (IV) is required for the Cipher Block Chain (CBC) mode of encryption. A random IV is generated and appended at the beginning of the data before being stored. The IV is then retrieved from the same file to decrypt the data.

Encryption of the data is done automatically before the file is saved. In the implementation, the AdaptedPlanner is first marshaled into a StringWriter before being encrypted and written into the file. This is to ensure that the data is JAXB formatted and the save algorithm is unaffected. Similarly, decryption of the data is done automatically before it is loaded. In the implementation, the file is read and decrypted and parsed into a StringReader. The StringReader is then un-marshaled and loaded. This is to ensure that the file is converted back into a JAXB object before being loaded and the load algorithm is unaffected. ​

5.10. Configuration

5.10.1. User Preferences [COMING IN 2.0]

The files generated by PlanMySem are also named "PlanMySem" and are saved in user’s PlanMySem folder by default. This default filename and file path can be changed via the the configuration file (default: config.json).
There is no need for manual configuration of the Semester as it is initialized dynamically as mentioned in Section 5.1, “Initialization of the Planner and its Semester”. ​

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

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

6.2. Publishing Documentation

See UsingTravis.adoc to learn how to deploy GitHub Pages using Travis. ​

6.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 12. Saving documentation as PDF files in Chrome

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

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

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

7. Testing

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

7.2. Types of tests

  1. Unit tests targeting the lowest level methods/classes.
    e.g. PlanMySem.commons.UtilTest

  2. Integration tests that are checking the integration of multiple code units (those code units are assumed to be working).
    e.g. PlanMySem.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. PlanMySem.logicManager.LogicTest, PlanMySem.parse,ParserTest

7.3. Troubleshooting Testing

Problem: Logic fails with a NullPointerException.

  • Reason: One of its dependencies, HelpWindow.html in src/main/resources/docs is missing.

  • Solution: Execute Gradle task processResources. ​

8. Dev Ops

8.1. Build Automation

See UsingGradle.adoc to learn how to use Gradle for build automation. ​

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

8.3. Coverage Reporting

We use Coveralls to track the code coverage of our projects. See UsingCoveralls.adoc for more details. ​

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

8.5. Making a Release

Here are the steps to create a new release.

  1. Update the version number in Main.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. ​

8.6. Managing Dependencies

Projects often depends on third-party libraries. For example, PlanMySem 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) ​

Appendix A: Product Scope

Target user profile:

  • NUS students and staff

  • has a need to manage a significant number of categories, activites, timeslots, tags in a calendar

  • prefer desktop apps over other types

  • prefers having a completely offline calendar

  • can type fast

  • prefers typing over mouse input

  • is reasonably comfortable using CLI apps

Value proposition: manage personal planner faster than a typical mouse/GUI driven app and caters to users who prefer an offline solution due to the current technology climate where information privacy/data privacy/data protection has become an uncertainty ​

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 if I do not know how to use the app

* * *

new user

initialize the calendar by year and semester

align the planner with the school’s academic calendar

* * *

user

add a slot

store all my slots in the calendar

* * *

user

delete a slot

remove all slots from my calendar that have been cancelled

* * *

user

edit a slot

edit slots from my calendar that have been postponed/ brought forward/ changed

* * *

user

list all slots

view all slots on the planner which I have activities on

* * *

user

recurse a slot

easily create all the relevant time slots for a module to recur every week

* * *

user

view all slots on a certain day

conveniently view my planner for the day

* * *

user

view all slots on a certain week

conveniently view my planner for the week

* * *

user

view all slots on a certain month

conveniently view my planner for the month

* * *

user

add details to a slot

record information related to the slot

* * *

user

undo a command

easily revert my changes and restore a previous state

* * *

user

redo a command

easily revert my undo command in case I mistakenly undo too far

* *

user

view the planner in a graphic calendar format

easily view my schedule for the day/week/month/semester

* *

user

view a slot

view the details of a specific activity I am looking for

* *

user

remove tags on a time slot

remove unused/ unnecessary tags from an activity

* *

user

edit tags

rename tags

* *

user

list all tags

view all existing tags

* *

user

view color coded categories

easily view the different types of categories

* *

user

encrypt my planner data

ensure the privacy of my planner

* *

user

decrypt an encrypted planner data

securely transfer the planner data to be operated on another device

*

user

import semester timetable (.ics files)

transfer my existing activities into the new timetable

*

user

export semester timetable (.ics files)

view my timetable on another platform

*

user

receive notifications of upcoming activities

be reminded of important upcoming activities

*

user

view recess week and exam week

view specifically the weeks to rest

*

user

view vacations

plan my schedule on vacation days or special semesters

*

user

favourite an activity

prioritise important activities

*

user

view public holidays

be aware of upcoming public holidays

*

user

compare my timetable with someone else’s

find a common time slot for a meeting

*

user

generate summary reports

view how much time I spent attending training / tutorials

Appendix C: Use Cases

This section describes the Use Cases for some of our implemented features. (For all use cases below, the System is PlanMySem and the Actor is the user, unless specified otherwise) ​

C.1. Use Case: Add a slot

  • MSS:

    • 1. User inputs add command followed by all the mandatory parameters.

    • 2. System reflects the additions to the planner.

      Use case ends.

  • Extensions:

    • 1a. System detects an error in the entered data.

      • 1a1. System outputs error message.

        Use case ends.

    • 1b. System detects insufficient parameters in the entered data.

      • 1b1. System outputs error message.

        Use case ends. ​

C.2. Use Case: List slots

  • MSS:

    • 1. User inputs the command to list slots followed by the tag or name of the slot.

    • 2. System displays all slots with the specified name or tag with their indexes.

      Use case ends.

  • Extensions:

    • 1a. Planner is empty.

      • 1a1. System outputs error message.

        Use case ends.

    • 1b. Tag or name does not exist in the planner.

      • 1b1. System outputs error message.

        Use case ends. ​

C.3. Use Case: Delete a slot

  • MSS:

    • 1. User inputs the delete command followed by the index or tag of the intended slot.

    • 2. System deletes the intended slot from the planner and outputs confirmation message.

      Use case ends.

  • Extensions:

    • 1a. Tag or index does not exist in the planner.

      • 1a1. System outputs error message.

        Use case ends. ​

C.4. Use Case: Edit a slot

  • MSS:

    • 1. User inputs command to edit a slot along with the tag or index, followed by the parameters to be changed.

    • 2. System changes the specified parameters for the slot.

    • 3. System reflects the slots as well as the perimeters changed.

      Use case ends.

  • Extensions:

    • 1a. Tag or index does not exist in the planner.

      • 1a1. System outputs error message.

        Use case ends.

    • 1b. System detects an error in the entered data.

      • 1b1. System outputs error message.

        Use case ends. ​

C.5. Use Case: View all slots in a Day

  • MSS:

    • 1. User inputs the command to view all slots along with the specific day or date in the current semester.

    • 2. System displays all the slots for that specified day or date.

      Use case ends.

  • Extensions:

    • 1a. Specified day or date does not exist in the current semester.

      • 1a1. System outputs error message.

        Use case ends.

    • 1b. System detects an error in the entered data.

      • 1b1. System outputs error message.

        Use case ends. ​

C.6. Use Case: Export planner

  • MSS:

    • 1. User inputs command to export the planner.

    • 2. System converts planner to .ics format.

    • 3. System saves .ics file in the main directory as "PlanMySem.ics".

    • 4. System displays confirmation message.

      Use case ends.

  • Extensions: :: 1a. A filename is included in the command.

    :

    1ai. The filename is valid.

    :

    1ai.1. System converts planner to .ics format.

    :

    1ai.2. System saves .ics file in the respective directory.

    :

    1ai.3. System displays confirmation message.

    Use case ends. ::: 1aii. The filename is invalid :::: 1aii.1 System outputs error message.

    + 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 a fully packed schedule, three times over, without a noticeable sluggishness in performance for typical usage.

  3. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.

  4. The system should respond relatively quickly to user commands so as to not make the user wait around; this is an advantage of using PlanMySem.

  5. The system should take up relatively little space on the local machine so as to cater to all students and OS.

  6. The system should be easy to use, intuitive and simple, such that any student regardless of past experience with calendar/scheduling software is able to use it.

  7. The system should be flexible to allow all kinds of schedules that target users might have.

  8. The data should be encrypted to prevent private data from being accessed. ​

Appendix E: Glossary

Mainstream OS

Windows, Linux, Unix, OS-X

Levenshtein Distance

The Levenshtein distance is a string metric for measuring difference between two sequences.
Informally, the Levenshtein distance between two words is the minimum number of single-character edits (i.e. insertions, deletions or substitutions) required to change one word into the other. ​

Appendix F: 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.

F.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 a window with a welcome message. 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. ​

F.2. Adding a slot

  1. Deleting a slot while all slots are listed

    1. Prerequisites: Add a single or multiple slot(s) using the add command.

    2. Test case: add n/CS2113T Lecture d/mon st/8:00 am et/9:00 am des/Topic: Software Engineering t/CS2113T t/Lecture r/normal r/past
      Expected: Add a single slot, named "CS2113T Lecture" with description "Software Engineering" on all mondays, from 0800hrs to 0900hrs with the tags "CS2113T" and "Tutorial". Total of 13 slots are added to the planner.

    3. Test case: add n/CS2113T Lecture d/mon st/8:00 am et/9:00 am des/Topic: Software Engineering t/CS2113T t/Lecture
      Expected: Add a single slot, named "CS2113T Lecture" with description "Software Engineering" on the coming monday, from 0800hrs to 0900hrs with the tags "CS2113T" and "Tutorial". A single slot is added to the planner.

    4. Test case: add n/ Lecture d/mon st/8:00 am et/9:00 am des/Topic: Software Engineering t/CS2113T t/Lecture
      Expected: No Slot is added. Error details shown in the status message.

    5. Other incorrect add commands to try include invalid or unspecified dates, days and or time
      Expected: Similar to previous. ​

F.3. Editing a slot

  1. Editing a slot while all slots are listed

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

    2. Test case: edit 1 nl/ICube
      Expected: The first slot shown in the list is edited such that it’s location is replaced with "ICube". The selected slot and the edited details, in this case only "location", is displayed.

    3. Test case: edit 0
      Expected: No Slot is edited. Error details shown in the status message.

    4. Other incorrect edit commands to try: edit, edit x (where x is larger than the list size) {give more}
      Expected: Similar to previous. ​

F.4. Deleting a slot

  1. Deleting a slot while all slots are listed

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

    2. Test case: delete 1
      Expected: First slot is deleted from the Planner. Number of deleted slots is shown, as i, and details of the slot is shown.

    3. Test case: delete 0
      Expected: No Slot is deleted. Error details shown in the status message.

    4. Other incorrect delete commands to try: delete, delete x (where x is larger than the list size) {give more}
      Expected: Similar to previous. ​

F.5. Viewing the planner

  1. View all slots for the current week

    1. Prerequisites: Add slots using the add command for any day of the current week.

    2. Test case: view week
      Expected: A weekly calendar view with all added slots for the current week with a summarised title.

    3. Test case: view week details
      Expected: A detailed view of all added slots for the current week.

    4. Other incorrect view commands to try: view, view week 0
      Expected: Error message returned which shows proper command usage or indicating an invalid input. ​