Logo Know-It-All

About the Project

Know-It-All is a flashcard application borne from CS2103T, a software engineering course spanning 13 weeks. We were tasked to take an existing addressbook application and either enhance it or morph it into a different product. After 4 developmental milestones, the result is Know-It-All, a digital flashcard solution that helps users store and organise their learning material. With an easy to use interface and convenient sharing functionality, Know-It-All iss designed to help students perform rote learning more efficiently. From cramming in between lessons to focused study, the interactive test session boosts the effectiveness of repetition and recall for memorisation. Download Know-It-All here!

My role in the project was to implement a folder system, so that users could group together multiple sets of flashcards. Apart from writing code, I maintained the User Guide, Developer Guide and project GitHub repository. Most importantly, I synergised with my team members to work productively and help everyone achieve their goals.

In this document, the following style elements from the respective documentation are present:

test: Command to be executed or a component, class or object in the architecture of the application.

Important information that should be noted.
Useful tips that can help if you get stuck.

Useful information for a deeper understanding of the current topic.

Summary of Contributions

Major Enhancement: I added the ability to have flashcard folders

  • What it does: allows the user to create folders that store separate sets of flashcards. Folders can be renamed and deleted.

  • Justification: This feature allows the user to logically group flashcards of the same topic together, separate from flashcards of other topics. This significantly improves the product as it enables better organisation, which is crucial for efficiency and ease of use.

  • Highlights: The enhancement affected all components extensively. For some components, the architecture had to be redesigned, and the multiple options to do so had to be carefully considered and assessed. The implementation was also challenging due to the tightly coupled nature of classes within each component, and the non-trivial changes to architecture required both a deep and broad understanding of how every component worked.

Code Contributed: Please click here to see samples of my functional and test code.

  • The tests I wrote increased coverage from 80% to 84% (Pull requests #104, #177)

Other Contributions:

  • Project Management:

    • Created GitHub organisation and team repository, issue labels, milestones and project board

    • Managed and tagged milestones v1.1 to v1.2

  • Documentation:

    • User Guide:

      • Introduced an About section (later renamed to How To Use this Guide) and populated the Command Summary and Glossary sections. Also revised the document format be more consistent (Pull request #90)

      • Rewrote and added annotated UI images to Quick Start to improve clarity (Pull request #180)

    • Developer Guide:

      • Wrote user stories to set project requirements, which were eventually ported over to GitHub issues for project management (Pull request #53)

      • Contributed to use cases and manual testing (Pull request #104, #180)

  • Community:

    • Performed the initial refactoring of code to flashcard context (Pull requests #37)

    • Reviewed over 20 pull requests, spotting potential errors and making suggestions (Pull requests #128, #178)

    • Made bug reports to notify teammates of bugs related to their components (Issues #118, #122, #136, #169) and addressed/assigned bug reports from external testers

    • Integrated a GitHub plugin (Netlify) to the team repo

Contributions to the User Guide

As we morphed the product, we kept the user guide up to date with the features we implemented. To showcase my technical writing skills, I have included an excerpt of my notable contributions, namely Quick Start and the new folder-related commands.

Introduction

Know-It-All is a flashcard application that helps users store and organise their learning material. With an easy to use interface and convenient content sharing functionality, Know-It-All is designed to help students perform rote learning more efficiently. From cramming in between lessons to focused study, the interactive test session boosts the effectiveness of repetition and recall for memorisation. Know-It-All targets medicine students as their studies involve a considerable amount of memory work, and deals with content that is suitable for the bite-sized flashcard format.

Ui

How To Use This Guide

Welcome to the Know-It-All User Guide! This document will equip you with what you need in order to use v1.4 of the application. While some familiarity with command line programs will come in handy, simply adhere to the command formats specified in this guide closely and the rest will be a breeze.

Using the application

In this section, we’ll walk you through the primary user interface of the application and how to create your first flashcard.

To use a command, type the command in the command box and press enter to execute it.
e.g. typing help and pressing enter will open the help window.
  1. When booting up the app for the first time, you should see the home directory much like the screengrab below. The first and only folder present is a sample folder.

    AnnotatedStartupUI
  2. cd 1 : enters the 1st flashcard folder. You will see a change in the user interface as you enter the folder.

    AnnotatedEnterFolderUI
  3. add q/How many chambers are there in a heart? a/Four : adds a new flashcard to the current folder.

    AnnotatedAddCardUI
  4. select 4 : selects the 4th flashcard in the current folder, which is also your newly added card.

    AnnotatedSelectCardUI
  5. exit : exits the app. The app window will close.

This is the end of the Quick Start tutorial. Please refer to [Features] for details of each command, and feel free to reach out to us if you run into any issues!

Folder Operations

Commands listed in this section are folder-level operations. This includes the operations such as creating and deleting of folders, and excludes commands that affect the contents of individual folders (e.g. adding a card).

The commands in this section, unless otherwise stated, can only be executed when you are at the home directory, outside of any folder. The commands are also not valid inside a test or report session. You can easily verify that you are at the home directory with the status bar at the bottom, which should display:

StatusBarInHomeDirectory

Enter folder : cd

Enters the folder specified by index. Panel on the left will display the list of cards in that folder.

Format: cd FOLDER_INDEX

Examples:

  • cd 2
    Enters the second folder in the folder list on the home directory.

Exit folder : cd ..

Return to the root directory (exit the current folder). A list of folders will be displayed

Format: cd ..

  • This command, unlike the rest of the commands in this section, can only be executed when inside a folder.

Examples:

  • cd 2
    cd ..
    The first command enters the second folder in the folder list on the home directory. The second command then returns you back to the home directory by exiting the folder.

Create new folder : addfolder

Creates a new flashcard folder with the specified name.

Format: addfolder FOLDER_NAME

  • The newly created folder will not contain any cards.

  • Folder names must be unique, between 1 and 50 characters, and only contain letters, numbers and whitespace. Folder names with the same characters but different capitalisation are non-unique. Attempting to add a folder with any of the above rules violated will result in an error.

  • Each folder and its cards are stored independently in the directory specified in preferences.json. By default, this is the data/ directory.

Examples:

  • addfolder Nervous System
    Creates a folder with the name "Nervous System". The UI should appear like the following after the command is executed.

AnnotatedAddFolderUI

You can then enter the folder with the cd command and begin adding cards.

Remove folder : deletefolder

Removes the flashcard folder specified by index.

Format: deletefolder FOLDER_INDEX

  • When a folder is deleted, all its cards are removed as well.

Examples:

  • deletefolder 2
    Deletes the second folder in the folder list, along with its cards, on the home directory.

Rename folder : editfolder

Renames the flashcard folder specified by index.

Format: editfolder FOLDER_INDEX NEW_FOLDER_NAME

  • The new name of the folder cannot be the same as an existing folder, and must adhere to the rules specified in Create new folder : addfolder.

  • You are allowed to rename an existing folder to a different capitalisation of its own name.

Examples:

  • editfolder 2 Circulatory System
    Renames the second folder in the folder list to "Circulatory System".

Merge folders feature Coming in v2.0

This feature will enable users to join multiple folders together, reducing the number of folders and grouping two topics.

Format: merge FOLDER_INDEX_1 FOLDER_INDEX_1 NEW_FOLDER_NAME

Command Summary

Command Summary

add q/QUESTION a/ANSWER [h/HINT] [i/INCORRECT_OPTION]…​

Adds a flashcard to the current folder.

edit INDEX [q/QUESTION] [a/ANSWER] [h/HINT] [i/INCORRECT_OPTION]…​

Edits the flashcard specified by the index in the current folder.

select INDEX

Displays flashcard details (question, answer, hint, card score) on the right panel on selection by index.

delete INDEX

Deletes the flashcard identified by index from the current folder.

sort

Displays all flashcards sorted such that the lowest scoring cards are at the top temporarily.

search KEYWORDS [MORE_KEYWORDS]

Searches for flashcards inside the current folder using keywords in flashcard questions.

list

Display a list of the flashcards in the current folder

report

Display a test score report for the current folder

undo

Undoes the previous undoable command.

redo

Redoes the last undo.

cd ..

Return to the root directory (exit the current folder). A list of folders will be displayed.

cd FOLDER_INDEX

Enters the folder specified by index. Panel on the left will display the list of cards in that folder.

addfolder FOLDER_NAME

Creates a new flashcard folder with the specified name.

deletefolder FOLDER_INDEX

Removes the flashcard folder specified by index.

editfolder FOLDER_INDEX NEW_FOLDER_NAME

Renames the flashcard folder specified by index to the new name specified.

test

This command begins a test session, where the display area enters a fullscreen.

ans ANSWER

Enter answer for a flashcard.

reveal

Immediately reveals the correct answer.

next

Presents the next lowest score flashcard in this current test session.

end

Quits the current test session or report display.

search KEYWORDS [MORE_KEYWORDS]

Searches for flashcards inside the current folder using keywords in flashcard questions.

import FILENAME

Imports a file with the specified name. Filename must include .csv extension

export FOLDER_INDEX [MORE_INDEXES]

Creates a csv file containing the flashcards from the specified folder, which can later be imported.

help

Opens the User Guide in a new window.

exit

Exits the application.

Contributions to the Developer Guide

We also kept the Developer Guide updated so that potential developers and enthusiast users could better understand the design and implementation of our app. This section is long-running, although the first few pages of the section should suffice in showcasing the technical depth of my contributions.

Model component

ModelClassDiagram
Figure 1. Structure of the Model Component

API : Model.java

The Model,

  • stores a UserPref object that represents the user’s preferences.

  • stores a list of VersionedCardFolders representing the folders that the user has. These VersionedCardFolders in turn each store a list of Cards. Each Card stores information about a single question.

  • exposes unmodifiable instances of FilteredList<Card> and FilteredList<VersionedCardFolder> 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.

  • exposes two instances of SimpleObjectProperty<Card>, which represent the current cards being selected and being tested, if any.

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

Folders

Current Implementation

A folder is another layer of abstraction over a CardFolder. Where we dealt with a single CardFolder in previous iterations, we now have multiple CardFolders that each have their own set of Cards. Users are able to manage each CardFolder independently.

Folders in the application are achieved via enhancements from the AddressBook implementation. The changes span across all four components (UI, Logic, Model and Storage).

Model

Previously, an instance of ModelManager contained only a single VersionedCardFolder, holding the current and previous state of the CardFolder. To support multiple folders, ModelManager now holds an ObservableList of CardFolders. The change is illustrated in the figure below, with the original implementation on the left and new implementation on the right.

ModelEnhancementDiagram

To allow users to operate on multiple CardFolders, the following notable methods were also introduced:

  • ModelManager#addFolder(CardFolder cardfolder) - Adds a specified cardfolder to the ModelManager’s list

  • ModelManager#deleteFolder(int index) - Deletes the CardFolder at the specified index in the ModelManager’s list

  • ModelManager#getActiveCardFolderIndex() - Gets the index of the current active CardFolder

  • ModelManager#enterFolder(int index) - Specifies the active CardFolder for operations to be performed on via the index in ModelManager’s list and sets the boolean inFolder to true to denote that user is inside a folder.

  • ModelManager#exitFolderToHome() - Sets the boolean inFolder to false to indicate that the user is at the home directory.

  • ModelManager#renameFolder(int index, String newName) - Renames the folder at the specified index in the ModelManager’s list to the new name.

  • ModelManager#getState() - Returns the current state of the ModelManager. The possible states are {IN_FOLDER, IN_HOMEDIR, IN_TEST, IN_REPORT}.

Storage

Similarly, the StorageManager needs to represent each CardFolder separately. In the same manner as in the Model component, we introduce a list of JsonCardFolderStorages. The change is illustrated in the figure below, with the original implementation on the left and new implementation on the right.

StorageEnhancementDiagram

Notable new methods:

  • StorageManager#readCardFolders() - Reads in all CardFolders from all CardFolderStorage objects in the list.

  • StorageManager#saveCardFolders(List<ReadOnlyCardFolder> cardFolders) - Saves all CardFolders provided in the argument to the user’s data directory.

Logic

The existing implementation of the Logic component propagates changes in a Model’s CardFolder to the Storage component. With listeners, it is informed when a CardFolder is modified (e.g. a new card is added) so that it can invoke the appropriate Storage methods.

The same principle was applied to propagate changes regarding CardFolders themselves (and not their stored cards) to Storage: e.g. adding a new folder. Model is now an Observable, and changes to a Model’s CardFolders will inform the LogicManager, which in turn invokes StorageManager#saveCardFolders(List<ReadOnlyCardFolder> cardFolders).

To illustrate how the Model, Storage and Logic components interact, below is a walkthrough of a typical usage scenario of the addfolder command. Component interactions for an addfolder command is a sequence diagram that summarises the example:

  • Step 1. The addfolder command is executed. For example, addfolder f.

  • Step 2. As with every command, the command parser reads the input and generates the relevant Command object, in this case an AddFolderCommand. The object is returned to the LogicManager.

If the input is invalid (e.g. user did not provide a folder name or provided one that violated the constraints of folder names), Step 2 would not proceed and an error message is displayed. The Model and Storage components would not be modified.
  • Step 3. The LogicManager executes the AddFolderCommand, Before transferring control to the Model component with the ModelManager#addFolder() method, a few checks are performed to ensure that the user is inside a folder and the model does not already have a folder with the same name (not shown in sequence diagram).

If any of the aforementioned checks do not succeed, Step 3 would end in a Command Exception being thrown and would not proceed. Model and Storage components would not be modified.
  • Step 4. The ModelManager creates a VersionedCardFolder to represent the newly created folder, storing a reference to its currently empty list of cards. Before returning control to the Logic component, ModelManager#indicateModified() is invoked to notify listeners in the LogicManager that the list of CardFolders have changed.

  • Step 5. The Logic component takes over control and checks if the ModelManager is modified. In the case of addfolder the object is indeed modified (as a result of Step 4) and thus the component proceeds to save the Model’s CardFolders to Storage.

  • Step 6. Before handing over control to Storage, the LogicManager obtains the information to save and the path to save to with ModelManager#getCardFolders() and ModelManager#getCardFoldersFilesPath() respectively. It then passes these objects as parameters when it calls StorageManager#saveCardFolders().

  • Step 7. The Storage component receives control, with the StorageManager clearing the directory of data files at the specified path and creating JsonCardFolderStorage objects with path names equivalent to the names of the folders it has received. It then proceeds to invoke JsonCardFolderStorage#saveCardFolder() on all the JsonCardFolderStorage to save all the folders before returning to the LogicManager.

If the path provided by the Model Component is invalid, the Storage component throws an exception and an error message is displayed. The changes made to Model are not saved and the command does not execute successfully.
  • Step 8. The LogicManager terminates and returns the result of the command to the calling method.

AddFolderSequenceDiagram
Figure 2. Component interactions for an addfolder command
UI

As folders are a layer of abstraction over the cards, there is a need for the GUI to represent this abstraction for greater clarity and ease of use for the user. This is done by introducing the FolderListPanel class, which displays a list of all folders that the user has.

The fullScreenPlaceholder:StackPane object houses the content in the main window of our application. Depending on whether the user is in the home directory or within a folder, different UI objects are placed within fullScreenPlaceholder.

  • When the user is in the home directory, fullScreenPlaceholder holds a FolderListPanel to display all the folders in a list inside the main window.

  • When the user is within a folder, fullScreenPlaceholder holds a CardMainScreen object, which is composed of a CardListPanel and BrowserPanel. These represent the list of cards on the scrolling sidebar, as well as the card viewer on the right. The content within the CardMainScreen depends on the particular folder the user has navigated into, as different folders hold different cards.

To better understand how the UI is updated, below is a walkthrough of what happens when the user enters a folder. Refer to the sequence diagram in UI behaviour when user enters folder for a visual representation:

  • Step 1. The Logic component informs the UI component that the user has entered a folder. The UI component responds by invoking MainWindow#handleEnterFolder().

  • Step 2. UI retrieves the list of cards belonging to the entered folder from the LogicManager.

  • Step 3. A new CardListPanel is created with the information obtained in Step 2.

  • Step 4. The new CardListPanel from Step 3, together with the existing BrowserPanel, are used to create a new CardMainScreen object.

  • Step 5. The content held by fullScreenPlaceholder is replaced with the newly generated CardMainScreen.

EnterFolderGUISequenceDiagram
Figure 3. UI behaviour when user enters folder

Design Considerations

Aspect: How multiple folders are represented in Model
  • Alternative 1 (current choice): List of structures representing individual folders

    • Pros: Scalable and better follows OOP principles.

    • Cons: Hard to implement, alters fundamental architecture of components.

  • Alternative 2: A single structure containing Cards with information on their folder membership (folder operations performed by iterating over all cards)

    • Pros: Easy to implement.

    • Cons: Not scalable, will be computationally expensive to perform folder operations when there are many cards and/or folders.

Evaluation: On the account of how computationally expensive it would be to parse through thousands of cards every card or folder operation, the first alternative was chosen and time was set aside to overcome the technical challenge of implementing the choice.

Aspect: Folder identification
  • Alternative 1: Use a unique folder name

    • Pros: Easier to implement.

    • Cons: The undo/redo feature would not be compatible with this approach, as checking equality between different versions of a folder across time necessarily requires the comparison of cards.

  • Alternative 2: Identify a folder by its cards

    • Pros: There can be no folders with identical cards, preventing redundancy.

    • Cons: Two folders could have identical names as long as the cards are different, which is potentially confusing.

  • Alternative 3 (current choice): Mixed approach, use Alternative 1 for comparing different folders and Alternative 2 for comparing the same folder across time

    • Pros: Reaps the benefits of both approaches without the disadvantages.

    • Cons: Difficult to implement and for future developers to grasp the difference between the two types of comparisons.

Evaluation: While it was difficult the implement, Alternative 3 was chosen due to the immense limitations of the first two approaches. The third alternative had little to no downside apart from requiring time to understand and implement.

Aspect: Storage file name and folder name
  • Alternative 1: Let folder name be the file name of the storage file

    • Pros: Less ambiguity as to how file name is related to folder name, able to find storage file path with folder name.

    • Cons: Harder to retrieve folder name from the file as it requires parsing the path, more prone to data corruption as file name could be modified when application is running (although this could be overcome with some OS-level syscalls to lock the file).

  • Alternative 2 (current choice): Let file name be independent of folder name, which is stored inside the storage file itself

    • Pros: Easier to implement and avoids dependency on existing storage files after application starts.

    • Cons: When saving folders from Model, it is difficult to match folders with existing storage files. Hence, rather than saving the modified folder, it is more feasible to clear the directory and save all folders. This is computationally expensive and may not be scalable beyond a certain size.

Evaluation: While in the long-run, the first alternative appears to better decision, time limitations make Alternative 2 good enough for most practical use cases. The saved time was used to implement other features.

Aspect: What folders to generate in the event corrupted storage files are encountered
  • Alternative 1: Display a sample folder

    • Pros: Easy to implement, guaranteed that application will not be empty with no folders displayed.

    • Cons: Non-corrupted folders will not be displayed and will potentially be overwritten.

  • Alternative 2: Display non-corrupted folders

    • Pros: Non-corrupted data is preserved.

    • Cons: If all data is corrupted, an empty application is presented to the user.

  • Alternative 3 (current choice): Mixed approach, display all non-corrupted folders unless all data is corrupted, in which case display sample folder

    • Pros: Has the advantages but not the disadvantages of Alternatives 1 and 2.

    • Cons: More difficult to implement, developers will need to pay special attention to understand this behaviour.

Evaluation: Alternative 3 was deemed the most logical choice because it achieves the important objectives of retaining non-corrupted user data, while always ensuring there is data for the user to work with even if he/she is starting the application for the first time.

Current Implementation

The state of the application with regard to navigation (i.e. whether a user is inside of a folder or at the home directory) affects the types of commands available to the user.

  • The commands that affect cards (e.g. adding a card, editing a card) are executed within folders and are known as Card Operations.

  • Commands that affect folders (e.g. adding a folder, deleting a folder) are only executable at the home directory and are known as Folder Operations.

Please refer to the User Guide for the full list of commands under both categories.

To keep track of navigation state, an enum State is maintained by the ModelManager. Other components may retrieve the current state with ModelManager#getState(). This is also how the Command objects determines whether the command is executable in the present navigation state.

Change Directory Command

Folder navigation is achieved by the user through the use of the cd command. As navigating folders do not actually modify folders and their cards, folder navigation does not involve the Storage Component.

The change directory command has the following formats:

  1. cd .. - Returns the user to the home directory. This command can only be executed when the user is inside a folder.

  2. cd FOLDER_INDEX - Enters the folder specified by FOLDER_INDEX. This command can only be executed from the home directory, when the user is not in any folder.

When a cd command is executed, the Logic component parses the command and creates a ChangeDirectoryCommand object. If the command is of the first format, ChangeDirectoryCommand() is invoked without any arguments and the boolean isExitingFolder is set to true. If the command is of the second format, the overloaded constructor ChangeDirectoryCommand(FOLDER_INDEX) is instead called and isExitingFolder is set to false.

ChangeDirectoryCommand#execute() is then invoked. The value of isExitingFolder will determine the corresponding methods in ModelManager that are called (exitFoldersToHome() or enterFolder()). The sequence diagram in Component interactions for cd command illustrates this conditional choice and the interactions involved with each option.

ChangeCommandSequenceDiagram
Figure 4. Component interactions for cd command

Design Considerations

Aspect: Command format to enter and exit folders
  • Alternative 1 (current choice): Use variations of the same command (e.g. cd .. and cd INDEX )

    • Pros: More intuitive and akin to other Command Line applications.

    • Cons: Harder to implement as the logic for parsing the command is different from that of existing commands.

  • Alternative 2: Use distinct commands (e.g. home and enter INDEX)

    • Pros: Commands would function similar to other commands in the application.

    • Cons: Harder for the user to get acquainted with as there are two separate commands with logically similar functionality; introduces redundancy.

Evaluation: This matter is highly subjective and conflicting feedback was received during testing. However, we believe that our target audience, a user familiar with the command line, would be more used to navigation with a single command and as such would prefer Alternative 1.

UC04 Add folder

Guarantees

  • A folder of the desired name is created.

MSS

  1. Student navigates to home directory.

  2. Student inputs the name of the folder he wants to create.

  3. System creates a folder of the desired name and shows it on the home directory.

    Use case ends

Extensions

  • 2a. Student inputs a name that already exists.

    • 2a1. System displays an error message prompting the user to use a folder name that is not taken.

      Use case resumes from step 2.

UC05 Edit folder name

Guarantees

  • A particular folder as selected by the student is renamed to the desired name.

MSS

  1. Student navigates to home directory.

  2. Student indicates the folder he wants to rename, as well as the new name.

  3. System renames the folder to the new name and shows it on the home directory.

    Use case ends

Extensions

  • 2a. Student inputs a name that already exists.

    • 2a1. System displays an error message prompting the user to use a folder name that is not taken.

      Use case resumes from step 2.

  • 2b. Student chooses a folder that does not exist.

    • 2b1. System displays an error message prompting the user to choose a valid folder.

      Use case resumes from step 2.

  • 2c. Student enters a blank as the desired new folder name.

    • 2c1. System displays an error message informing that the folder name cannot be a blank.

      Use case resumes from step 2.

UC06 Navigating into folders

MSS

  1. Student indicates the folder he wants to enter.

  2. System enters the folder and displays the folder content.

    Use case ends

Extensions

  • 1a. Student chooses a folder that does not exist.

    • 1a1. System displays an error message prompting the user to choose a valid folder.

      Use case resumes from step 1.

  • 1b. Student is already inside a folder.

    • 1b1. System displays an error message informing that the user can only navigate into the folder when he is at the home directory.

    • 1b2. Student navigates back to home directory.

      Use case resumes from step 1.

Folder operations

  1. Adding a folder

    1. Prerequisites: You must be at the home directory (status bar should read In Home Directory) and have only one folder called "Sample Folder". To get this configuration, you can delete all data files except for the jar file and relaunch the application.

    2. Test case: addfolder Folder 1
      Expected: A folder by the name of "Folder 1" is added. Status message confirms that the folder added, and the new folder can be found in the list of folders.

    3. Test case: addfolder Sample Folder
      Expected: No folder is added. Error details shown in the status message.

    4. Other incorrect addfolder commands to try: addfolder, addfolder Special/Chars, addfolder x (where x is string longer than 50 characters)
      Expected: Similar to previous.

  2. Deleting a folder

    1. Prerequisites: You must be at the home directory (status bar should read In Home Directory) and have at least one folder.

    2. Test case: deletefolder 1
      Expected: The folder at index 1 is deleted. Status message confirms that the folder is deleted, and the folder can no longer be found in the list of folders.

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

    4. Other incorrect deletefolder commands to try: deletefolder, deletefolder Sample Folder, deletefolder x (where x is larger than the list length)
      Expected: Similar to previous.

  3. Renaming a folder

    1. Prerequisites: You must be at the home directory (status bar should read In Home Directory) and have at least one folder called "Sample Folder", and no folder called "New Name".

    2. Test case: editfolder x New Name (where x is the index of a folder that is not Sample Folder)
      Expected: The folder at index x is renamed to "New Name". Status message confirms that renaming operation succeeded.

    3. Test case: editfolder x sample folder (where x is the index of Sample Folder)
      Expected: The folder at index x is renamed to its original name (with new capitalisation). Status message confirms that renaming operation succeeded.

    4. Test case: editfolder x Sample Folder (where x is not the index of Sample Folder)
      Expected: The folder at index x is not renamed. Error details shown in the status message.

    5. Other incorrect editfolder commands to try: editfolder, editfolder New Name 1, editfolder x New Name (where x is larger than the list length)
      Expected: No folder is renamed. Error details shown in the status message.

  4. Persistence of folder operations

    1. Prerequisites: You must be at the home directory (status bar should read In Home Directory) and know where the data files are stored. By default, this will be at the data/ directory at the path of the jar file.

    2. Test case: addfolder x (where x is the name not used by any existing folder)
      Expected: A new json by the name of x.json appears in the data directory.

    3. Test case: deletefolder 1
      Expected: The json with the same file name as the deleted folder is no longer present in the data directory. No other files in the directory are affected.

    4. Test case: editfolder 1 x (where x is a name not used by any existing folder)
      Expected: The json with the original name of the edited folder is no longer present in the data directory, replaced with a json with the new folder name. No other files in the directory are affected.

  1. Entering a folder

    1. Prerequisites: You must be at the home directory (status bar should read In Home Directory) and have at least one folder.

    2. Test case: cd 1
      Expected: Folder 1 is entered. Status message confirms this and UI is updated.

    3. Test case: cd x (where x is larger than the list length)
      Expected: No folder is entered. Error details shown in the status message.

    4. Other incorrect cd commands to try: cd, cd Sample Folder, cd ..
      Expected: Similar to previous.

  2. Exiting a folder

    1. Prerequisites: You must be inside a folder (status bar should read Inside Folder: x where x is the name of the folder you are in).

    2. Test case: cd ..
      Expected: The folder is exited and you return to the home directory. Status message confirms this and UI is updated.

    3. Test case: cd x (where x is any combination of characters other than "..")
      Expected: The folder is not exited. Error details shown in the status message.

    4. Other incorrect cd commands to try: cd, cd Home
      Expected: Similar to previous.

Saving data

  1. Dealing with missing/corrupted data files

    1. Prerequisites: You must know where the data files are stored. By default, this will be at the data/ directory at the path of the jar file.

    2. Test case: Delete the data directory and launch the app
      Expected: A sample folder is present when the app launches (although it is not committed to storage until a persistent change is made).

    3. Test case: Insert a non-json file/corrupted json file in the data directory and launch the app
      Expected: The valid json files have folders with their corresponding names present. The non-json file/corrupted json file remains unaffected.