diff --git a/src/main/java/utilities/AdditionalInfoParser.java b/src/main/java/utilities/AdditionalInfoParser.java index fbdc2647c4..a94563001b 100644 --- a/src/main/java/utilities/AdditionalInfoParser.java +++ b/src/main/java/utilities/AdditionalInfoParser.java @@ -81,7 +81,7 @@ public static String[] splitToAndFrom(String input) throws WilliamException { * @throws WilliamException If the description of the additional detail is empty */ public static void checkAdditionalDetailEmpty(String input) throws WilliamException { - if (input == null) { + if (input == null || input.trim().isEmpty()) { throw new WilliamException("The description of a task should not be empty. Please try again!"); } } diff --git a/src/main/java/utilities/StorageStub.java b/src/main/java/utilities/StorageStub.java new file mode 100644 index 0000000000..3138fc822c --- /dev/null +++ b/src/main/java/utilities/StorageStub.java @@ -0,0 +1,29 @@ +package utilities; + +import tasks.Task; +import java.util.ArrayList; +import java.util.List; + +/** + * The StorageStub class deals with loading tasks and saving tasks into a list + * (it simulates saving and loading task from a text file for the ParserTest) + */ +public class StorageStub extends Storage { + private List tasks; + + public StorageStub(String filePath) { + super(filePath); + this.tasks = new ArrayList<>(); + } + + @Override + public List loadFromFile() { + return this.tasks; + } + + @Override + public void writeToFile(List tasks) { + this.tasks = tasks; + } + +} diff --git a/src/main/java/utilities/TaskListStub.java b/src/main/java/utilities/TaskListStub.java new file mode 100644 index 0000000000..ae5bf55e7e --- /dev/null +++ b/src/main/java/utilities/TaskListStub.java @@ -0,0 +1,51 @@ +package utilities; + +import tasks.Task; + +import java.util.ArrayList; +import java.util.List; + +/** + * The TaskListStub contains the task list e.g. it has operations to add/delete + * tasks in the list (it simulates these operations for the ParserTest) + */ +public class TaskListStub extends TaskList { + private List tasks; + + public TaskListStub() { + this.tasks = new ArrayList<>(); + } + + @Override + public void addTask(Task task) { + this.tasks.add(task); + } + + @Override + public void deleteFromList(String input) { + int idOfItem = Integer.parseInt(input); + int actualId = idOfItem - 1; + if (actualId >= 0 && actualId < tasks.size()) { + tasks.remove(actualId); + } + } + + @Override + public void markAndUnmark(String input) { + int idOfItem = Integer.parseInt(input); + int actualId = idOfItem - 1; + if (actualId >= 0 && actualId < tasks.size()) { + Task task = tasks.get(actualId); + task.changeIsDone(); + } + } + + @Override + public List getTasks() { + return this.tasks; + } + + public int getSize() { + return this.tasks.size(); + } +} diff --git a/src/test/java/utilities/DateAndTimeParserTest.java b/src/test/java/utilities/DateAndTimeParserTest.java new file mode 100644 index 0000000000..7654919d5c --- /dev/null +++ b/src/test/java/utilities/DateAndTimeParserTest.java @@ -0,0 +1,73 @@ +package utilities; + +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import exceptions.WilliamException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * Test class for the DateAndTimeParser in utilities package + */ +public class DateAndTimeParserTest { + /** + * Test the acceptDateAndTime method with the correct input, no exception thrown + */ + @Test + public void acceptDateAndTime_correctDateTime_noException() { + assertDoesNotThrow(() -> DateAndTimeParser.acceptDateAndTime("12/12/2023 1800")); + + assertDoesNotThrow(() -> DateAndTimeParser.acceptDateAndTime("13/12/2023 1700")); + } + + /** + * Test the acceptDateAndTime method with the wrong input, exception thrown + */ + @Test + public void acceptDateAndTime_incorrectDateTime_exceptionThrown() { + try { + DateAndTimeParser.acceptDateAndTime("12-12-2023 5pm"); + fail(); + } catch (WilliamException e) { + assertEquals("The date and time format is invalid. Please try again!", e.getMessage()); + } + } + + /** + * Test the checkWhetherToAndFromValid method with the correct input, no + * exception thrown + */ + @Test + public void checkWhetherToAndFromValid_correctToAndFrom_noException() { + assertDoesNotThrow(() -> DateAndTimeParser.checkWhetherToAndFromValid("11/12/2023 1800", "12/12/2023 1800")); + } + + /** + * Test the checkWhetherToAndFromValid method with the wrong input, exception + * thrown + */ + @Test + public void checkWhetherToAndFromValid_fromDateAfterToDate_exceptionThrown() { + try { + DateAndTimeParser.checkWhetherToAndFromValid("13/12/2023 1800", "12/12/2023 1800"); + fail(); + } catch (WilliamException e) { + assertEquals("The '/from' date and time should be before '/to' date and time. Please try again!", + e.getMessage()); + } + } + + /** + * Test the convertStringToDate method with the correct input + */ + @Test + public void convertStringToDate() { + LocalDateTime expectedDate = LocalDateTime.of(2023, 12, 12, 18, 0); + LocalDateTime actualDate = DateAndTimeParser.convertStringToDate("12/12/2023 1800"); + assertEquals(expectedDate, actualDate); + } +} diff --git a/src/test/java/utilities/ParserTest.java b/src/test/java/utilities/ParserTest.java new file mode 100644 index 0000000000..cd90f90ba2 --- /dev/null +++ b/src/test/java/utilities/ParserTest.java @@ -0,0 +1,167 @@ +package utilities; + +import org.junit.jupiter.api.Test; + +import commands.Commands; +import utilities.Parser; +import utilities.StorageStub; +import utilities.TaskListStub; +import tasks.Todo; +import tasks.Deadline; +import tasks.Event; + +import org.junit.jupiter.api.BeforeEach; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * Test class for the Parser in the utilities packages + */ +public class ParserTest { + private TaskListStub taskListStub; + private StorageStub storageStub; + private Parser parser; + + @BeforeEach + public void setUp() { + taskListStub = new TaskListStub(); + storageStub = new StorageStub("noStringPath"); + parser = new Parser(taskListStub, storageStub); + } + + /** + * Test the parseCommands method for toDo switch case for the correct input + * (assertTrue if it is added successfully, assertFalse if its not added + * successfully) + */ + @Test + public void parseCommands_toDoCommand_addsToDo() { + String additionalInfo = "Read Book"; + parser.parseCommands(Commands.todo, additionalInfo); + assertFalse(taskListStub.getTasks().isEmpty()); + assertTrue(taskListStub.getTasks().get(0) instanceof Todo); + } + + /** + * Test the parseCommands method for toDo switch case for the incorrect input + * (assertTrue since it should not be added, and list should be empty) + */ + @Test + public void parseCommands_incorrectToDoCommand_doesNotAddTask() { + parser.parseCommands(Commands.todo, ""); + assertTrue(taskListStub.getTasks().isEmpty()); + } + + /** + * Test the parseCommands method for deadline switch case for the correct input + * (assertTrue if it is added successfully, assertFalse if its not added + * successfully) + */ + @Test + public void parseCommands_deadlineCommand_addsDeadline() { + String additionalInfo = "CS2103 Assignment 1 /by 12/12/2023 1800"; + parser.parseCommands(Commands.deadline, additionalInfo); + assertFalse(taskListStub.getTasks().isEmpty()); + assertTrue(taskListStub.getTasks().get(0) instanceof Deadline); + } + + /** + * Test the parseCommands method for deadline switch case for the incorrect + * input (assertTrue since it should not be added, and list should be empty) + */ + @Test + public void parseCommands_incorrectDeadlineCommand_doesNotAddTask() { + parser.parseCommands(Commands.deadline, "CS2103 Assignment 1"); + parser.parseCommands(Commands.deadline, "CS2103 Assignment 1 /by"); + parser.parseCommands(Commands.deadline, "CS2103 Assignment 1 /by 12/12/2023 6pm"); + assertTrue(taskListStub.getTasks().isEmpty()); + } + + /** + * Test the parseCommands method for event switch case for the correct input + * (assertTrue if it is added successfully, assertFalse if its not added + * successfully) + */ + @Test + public void parseCommands_eventCommand_addsDeadline() { + String additionalInfo = "CS2103 Assignment 2 /from 12/12/2023 1800 /to 13/12/2023 1700"; + parser.parseCommands(Commands.event, additionalInfo); + assertFalse(taskListStub.getTasks().isEmpty()); + assertTrue(taskListStub.getTasks().get(0) instanceof Event); + } + + /** + * Test the parseCommands method for event switch case for the incorrect + * input (assertTrue since it should not be added, and list should be empty) + */ + @Test + public void parseCommands_incorrectEventCommand_doesNotAddTask() { + parser.parseCommands(Commands.event, "CS2103 Assignment 2"); + parser.parseCommands(Commands.event, "CS2103 Assignment 2 /from 12/12/2023 1800 "); + parser.parseCommands(Commands.event, "CS2103 Assignment 2 /from 12/12/2023 1800 /to "); + parser.parseCommands(Commands.event, "CS2103 Assignment 2 /from 12/12/2023 1800 /to 11/12/2023 1900"); + parser.parseCommands(Commands.event, "CS2103 Assignment 2 /from 12/12/2023 6pm /to 12/12/2023 7pm"); + assertTrue(taskListStub.getTasks().isEmpty()); + } + + /** + * Test the parseCommands method for bye switch case, check whether a task been + * added successfully to a file (since file should not be used for isolation, it + * is temporaily stored in an arraylist instead) + */ + @Test + public void parseCommands_byeCommand_addTasksIntoFile() { + Todo todo = new Todo("Test Task Added To File"); + taskListStub.addTask(todo); + + parser.parseCommands(Commands.bye, ""); + + assertFalse(storageStub.loadFromFile().isEmpty()); + assertEquals(todo, storageStub.loadFromFile().get(0)); + assertFalse(parser.isExit()); + } + + /** + * Test the parseCommands method for delete switch case, check whether a task + * has been deleted successfully + */ + @Test + public void parseCommands_deleteCommand_deleteTaskFromList() { + Todo todo = new Todo("Test Task Added To File"); + taskListStub.addTask(todo); + + // Since there is only one task, the ID of the task is 1 + parser.parseCommands(Commands.delete, "1"); + assertTrue(taskListStub.getTasks().isEmpty()); + } + + /** + * Test the parseCommands method for mark switch case, check whether a task has + * been marked successfully + */ + @Test + public void parseCommands_markCommand_markTaskAsDone() { + Todo todo = new Todo("Test Task Added To File", false); + taskListStub.addTask(todo); + + // Since there is only one task, the ID of the task is 1 + parser.parseCommands(Commands.mark, "1"); + assertEquals("X", taskListStub.getTasks().get(0).getStatusIcon()); + } + + /** + * Test the parseCommands method for mark switch case, check whether a task has + * been marked successfully + */ + @Test + public void parseCommands_markCommand_markTaskAsNotDone() { + Todo todo = new Todo("Test Task Added To File", true); + taskListStub.addTask(todo); + + // Since there is only one task, the ID of the task is 1 + parser.parseCommands(Commands.mark, "1"); + assertEquals(" ", taskListStub.getTasks().get(0).getStatusIcon()); + } +}