diff --git a/src/main/java/duke/Duke.java b/src/main/java/duke/Duke.java
index ace169665e..530b8505c2 100644
--- a/src/main/java/duke/Duke.java
+++ b/src/main/java/duke/Duke.java
@@ -14,10 +14,11 @@
*/
public class Duke {
+ public static final String WELCOME_MESSAGE = "Hello! I'm Duke. What would you like to do today?";
+
/** The file path where the data of the chatbot is stored */
private static final String FILE_PATH = "data/tasks.txt";
-
private final Storage storage;
private final TaskList tasks;
diff --git a/src/main/java/duke/gui/MainWindow.java b/src/main/java/duke/gui/MainWindow.java
index ebbc604b73..88cb10c8e5 100644
--- a/src/main/java/duke/gui/MainWindow.java
+++ b/src/main/java/duke/gui/MainWindow.java
@@ -1,5 +1,7 @@
package duke.gui;
+import static duke.Duke.WELCOME_MESSAGE;
+
import duke.Duke;
import duke.command.CommandResult;
import duke.data.exception.DukeException;
@@ -25,9 +27,13 @@ public class MainWindow extends AnchorPane {
private Duke duke;
+ /**
+ * Initializes the main window with the given welcome message.
+ */
@FXML
public void initialize() {
scrollPane.vvalueProperty().bind(dialogContainer.heightProperty());
+ addDukeDialog(WELCOME_MESSAGE);
}
public void setDuke(Duke d) {
diff --git a/src/main/resources/images/DaUser.png b/src/main/resources/images/DaUser.png
deleted file mode 100644
index 3c82f45461..0000000000
Binary files a/src/main/resources/images/DaUser.png and /dev/null differ
diff --git a/src/main/resources/view/UserDialogBox.fxml b/src/main/resources/view/UserDialogBox.fxml
index 4ac84b3263..3e3ce1e02a 100644
--- a/src/main/resources/view/UserDialogBox.fxml
+++ b/src/main/resources/view/UserDialogBox.fxml
@@ -15,10 +15,6 @@
-
-
-
-
diff --git a/src/test/java/duke/data/task/TaskListTest.java b/src/test/java/duke/data/task/TaskListTest.java
index 382491acdb..c28ab86420 100644
--- a/src/test/java/duke/data/task/TaskListTest.java
+++ b/src/test/java/duke/data/task/TaskListTest.java
@@ -10,22 +10,23 @@
import org.junit.jupiter.api.Test;
import duke.data.exception.DukeException;
+import duke.data.exception.InvalidTaskIndexException;
public class TaskListTest {
@Test
- public void removeTask_invalidIndex_throwsDukeException() {
+ public void remove_invalidIndex_throwsInvalidTaskIndexException() {
TaskList taskList = new TaskList(
new Todo("todo"),
new Deadline("deadline", LocalDate.now()),
new Event("event", LocalDate.now(), LocalDate.now())
);
- assertThrows(DukeException.class, () -> taskList.remove(-1));
- assertThrows(DukeException.class, () -> taskList.remove(4));
+ assertThrows(InvalidTaskIndexException.class, () -> taskList.remove(-1));
+ assertThrows(InvalidTaskIndexException.class, () -> taskList.remove(4));
}
@Test
- public void removeTask_validIndexIndex_taskNotInList() {
+ public void remove_validIndexIndex_taskNotInList() {
Task toRemove = new Todo("toRemove");
TaskList taskList = new TaskList(
new Todo("todo"),
diff --git a/src/test/java/duke/parser/ParserTest.java b/src/test/java/duke/parser/ParserTest.java
index 15ff2f1c7f..0e140b4d52 100644
--- a/src/test/java/duke/parser/ParserTest.java
+++ b/src/test/java/duke/parser/ParserTest.java
@@ -1,7 +1,7 @@
package duke.parser;
-import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import org.junit.jupiter.api.Test;
@@ -9,9 +9,21 @@
import duke.command.AddDeadlineCommand;
import duke.command.AddEventCommand;
import duke.command.AddTodoCommand;
-import duke.command.Command;
+import duke.command.ClearCommand;
+import duke.command.DeleteCommand;
import duke.command.ExitCommand;
+import duke.command.FindCommand;
+import duke.command.HelpCommand;
+import duke.command.ListCommand;
+import duke.command.MarkCommand;
+import duke.command.UnmarkCommand;
import duke.data.exception.DukeException;
+import duke.data.exception.InvalidDateException;
+import duke.data.exception.InvalidKeywordException;
+import duke.data.exception.InvalidTaskArgumentException;
+import duke.data.exception.InvalidTaskIndexException;
+
+
public class ParserTest {
@@ -28,119 +40,290 @@ public void parse_invalidCommandWord_throwsDukeException() {
@Test
public void parse_byeCommandWord_returnsExitCommand() {
try {
- assertEquals(Parser.parse("bye").getClass(), ExitCommand.class);
+ assertTrue(Parser.parse("bye") instanceof ExitCommand);
} catch (DukeException e) {
fail(e.getMessage());
}
}
@Test
- public void parse_emptyTodoDescription_throwsDukeException() {
+ public void parse_emptyTodoDescription_throwsInvalidTaskArgumentException() {
try {
Parser.parse("todo");
- } catch (DukeException e) {
+ } catch (InvalidTaskArgumentException e) {
return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
}
fail("Add Todo Command was successfully constructed with empty description.");
}
@Test
public void parse_validTodo_returnsAddTodoCommand() {
- Command command;
try {
- command = Parser.parse("todo desc abc");
+ assertTrue(Parser.parse("todo desc") instanceof AddTodoCommand);
+ assertTrue(Parser.parse("todo desc abc") instanceof AddTodoCommand);
} catch (DukeException e) {
fail(e.getMessage());
- return;
}
-
- assertEquals(command.getClass(), AddTodoCommand.class);
}
@Test
- public void parse_emptyDeadlineDescription_throwsDukeException() {
+ public void parse_emptyDeadlineDescription_throwsInvalidTaskArgumentException() {
try {
Parser.parse("deadline");
- } catch (DukeException e) {
+ } catch (InvalidTaskArgumentException e) {
return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
}
fail("Add Deadline Command was successfully constructed with empty description.");
}
@Test
- public void parse_emptyDeadlineBy_throwsDukeException() {
+ public void parse_emptyDeadlineBy_throwsInvalidTaskArgumentException() {
try {
Parser.parse("deadline desc");
- } catch (DukeException e) {
+ } catch (InvalidTaskArgumentException e) {
return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
}
fail("Add Deadline Command was successfully constructed without /by field.");
}
@Test
- public void parse_invalidDeadlineBy_throwsDukeException() {
+ public void parse_invalidDeadlineBy_throwsInvalidDateException() {
try {
Parser.parse("deadline desc /by invalid");
- } catch (DukeException e) {
+ } catch (InvalidDateException e) {
return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
}
fail("Add Deadline Command was successfully constructed with invalid /by field.");
}
@Test
public void parse_validDeadline_returnsAddDeadlineCommand() {
- Command command;
try {
- command = Parser.parse("deadline desc /by 2023-01-01");
+ assertTrue(Parser.parse("deadline desc /by 2023-01-01") instanceof AddDeadlineCommand);
+ assertTrue(Parser.parse("deadline desc /by 1999-12-30") instanceof AddDeadlineCommand);
} catch (DukeException e) {
fail(e.getMessage());
- return;
}
-
- assertEquals(command.getClass(), AddDeadlineCommand.class);
}
@Test
- public void parse_emptyEventDescription_throwsDukeException() {
+ public void parse_emptyEventDescription_throwsInvalidTaskArgumentException() {
try {
Parser.parse("event");
- } catch (DukeException e) {
+ } catch (InvalidTaskArgumentException e) {
return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
}
fail("Add Event Command was successfully constructed with empty description.");
}
@Test
- public void parse_invalidEventFrom_throwsDukeException() {
+ public void parse_invalidEventFrom_throwsInvalidDateException() {
try {
- Parser.parse("deadline desc /from invalid /to 2023-01-01");
- } catch (DukeException e) {
+ Parser.parse("event desc /from invalid /to 2023-01-01");
+ } catch (InvalidDateException e) {
return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
}
fail("Add Event Command was successfully constructed with invalid /from field.");
}
@Test
- public void parse_invalidEventTo_throwsDukeException() {
+ public void parse_invalidEventTo_throwsInvalidDatetException() {
try {
- Parser.parse("deadline desc /from 2023-01-01 /to invalid");
- } catch (DukeException e) {
+ Parser.parse("event desc /from 2023-01-01 /to invalid");
+ } catch (InvalidDateException e) {
return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
}
fail("Add Event Command was successfully constructed with invalid /to field.");
}
@Test
public void parse_validEvent_returnsAddEventCommand() {
- Command command;
try {
- command = Parser.parse("event desc /from 2023-01-01 /to 2024-01-01");
+ assertTrue(Parser.parse("event desc /from 2023-01-31 /to 2024-01-01") instanceof AddEventCommand);
+ assertTrue(Parser.parse("event desc /from 2020-01-31 /to 2024-01-01") instanceof AddEventCommand);
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void parse_listCommand_returnsListCommand() {
+ try {
+ assertTrue(Parser.parse("list") instanceof ListCommand);
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void parse_clearCommand_returnsClearCommand() {
+ try {
+ assertTrue(Parser.parse("clear") instanceof ClearCommand);
} catch (DukeException e) {
fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void parse_emptyKeyword_throwsInvalidKeywordException() {
+ try {
+ Parser.parse("find");
+ } catch (InvalidKeywordException e) {
return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
}
+ fail("Find Command was successfully constructed with empty keyword.");
+ }
- assertEquals(command.getClass(), AddEventCommand.class);
+ @Test
+ public void parse_multipleKeyword_throwsInvalidKeywordException() {
+ try {
+ Parser.parse("find a b");
+ } catch (InvalidKeywordException e) {
+ return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ fail("Find Command was successfully constructed with multiple keywords.");
+ }
+
+ @Test
+ public void parse_validKeyword_returnsFindCommand() {
+ try {
+ assertTrue(Parser.parse("find a") instanceof FindCommand);
+ assertTrue(Parser.parse("find abc") instanceof FindCommand);
+ assertTrue(Parser.parse("find keyword") instanceof FindCommand);
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
}
+
+ @Test
+ public void parse_helpCommand_returnsHelpCommand() {
+ try {
+ assertTrue(Parser.parse("help") instanceof HelpCommand);
+ assertTrue(Parser.parse("help anything") instanceof HelpCommand);
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void parse_emptyMarkIndex_throwsInvalidTaskIndexException() {
+ try {
+ Parser.parse("mark");
+ } catch (InvalidTaskIndexException e) {
+ return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ fail("Mark Command was successfully constructed with no index.");
+ }
+
+ @Test
+ public void parse_invalidMarkIndex_throwsInvalidTaskIndexException() {
+ try {
+ Parser.parse("mark invalid");
+ } catch (InvalidTaskIndexException e) {
+ return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ fail("Mark Command was successfully constructed with invalid index.");
+ }
+
+ @Test
+ public void parse_validMarkIndex_returnsMarkCommand() {
+ try {
+ assertTrue(Parser.parse("mark 1") instanceof MarkCommand);
+ assertTrue(Parser.parse("mark 999") instanceof MarkCommand);
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void parse_emptyUnmarkIndex_throwsInvalidTaskIndexException() {
+ try {
+ Parser.parse("unmark");
+ } catch (InvalidTaskIndexException e) {
+ return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ fail("Unmark Command was successfully constructed with no index.");
+ }
+
+ @Test
+ public void parse_invalidUnmarkIndex_throwsInvalidTaskIndexException() {
+ try {
+ Parser.parse("unmark invalid");
+ } catch (InvalidTaskIndexException e) {
+ return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ fail("Unmark Command was successfully constructed with invalid index.");
+ }
+
+ @Test
+ public void parse_validUnmarkIndex_returnsUnmarkCommand() {
+ try {
+ assertTrue(Parser.parse("unmark 1") instanceof UnmarkCommand);
+ assertTrue(Parser.parse("unmark 999") instanceof UnmarkCommand);
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ }
+
+ @Test
+ public void parse_emptyDeleteIndex_throwsInvalidTaskIndexException() {
+ try {
+ Parser.parse("delete");
+ } catch (InvalidTaskIndexException e) {
+ return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ fail("Delete Command was successfully constructed with no index.");
+ }
+
+ @Test
+ public void parse_invalidDeleteIndex_throwsInvalidTaskIndexException() {
+ try {
+ Parser.parse("delete invalid");
+ } catch (InvalidTaskIndexException e) {
+ return;
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ fail("Delete Command was successfully constructed with invalid index.");
+ }
+
+ @Test
+ public void parse_validDeleteIndex_returnsUnmarkCommand() {
+ try {
+ assertTrue(Parser.parse("delete 1") instanceof DeleteCommand);
+ assertTrue(Parser.parse("delete 999") instanceof DeleteCommand);
+ } catch (DukeException e) {
+ fail(e.getMessage());
+ }
+ }
+
}