diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000000..600cf08275 --- /dev/null +++ b/build.gradle @@ -0,0 +1,68 @@ +plugins { + id 'java' + id 'application' + id 'checkstyle' + id 'com.github.johnrengelman.shadow' version '6.0.0' +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0' + testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0' +} + +test { + useJUnitPlatform() + + testLogging { + events "passed", "skipped", "failed" + + showExceptions true + exceptionFormat "full" + showCauses true + showStackTraces true + showStandardStreams = false + } +} + +application { + mainClassName = "Launcher" +} + +shadowJar { + archiveBaseName = "duke" + archiveClassifier = null +} + +checkstyle { + toolVersion = '8.23' +} + +run{ + standardInput = System.in +} + +repositories { + mavenCentral() +} + + +dependencies { + String javaFxVersion = '11' + + implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux' +} diff --git a/docs/README.md b/docs/README.md index fd44069597..7c84f3184b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,20 +1,133 @@ -# User Guide +# Eu Zin's Duke User Guide -## Features +Eu Zin's Duke is a simple no frills(because Eu Zin is not great at jxml yet) to-do list that can help you keep track of your bust day! -### Feature 1 -Description of feature. +## Contents: + - Quickstart + - Features + - List View + - Add todo + - Add event + - Add deadline + - Mark as Complete + - Delete task + - Set task duration + - Search for a task + - FAQ + - Command Summary +--- -## Usage +# Quickstart +Due to the easy-to-use nature of Eu Zin's Duke, this will be the quickest Quickstart Guide you've ever seen. -### `Keyword` - Describe action +### 1. Open Eu Zin's Duke +You will arrive at the main dialog page. It will look something like this: -Describe action and its outcome. +![Image](start.png) -Example of usage: +You will notice 3 important features: +1. The User Input Box - For you to type in the commands for Eu Zin's Duke +2. The Send Button - To send your commands to Eu Zin's Duke when you are done entering them +3. The Scroll Bar - To Scroll up and down the dialog box -`keyword (optional arguments)` +### 2. Create your first Task +Your task can come in 3 forms: todo, event and deadline. -Expected outcome: +##### todo +These tasks are the most basic of tasks, they **only have a description**. +To create a todo input: +`todo ` and hit *Send* -`outcome` +##### event +These tasks have a **description** and a **timeframe**. +To create an event input: +`event /at ` and hit *Send* +The description and timefram cane be of any string format. + +##### deadline +These tasks have a **description** and a **date-time** +To create a deadline input: +`deadline /by ` and hit *Send* +The description can be of any String format. +> **_NOTE:_** **The date-time must be strictly in either of these formats:** DD/MM/YYYY TTTT *OR* YYYY/MM/DD TTTT + +### Complete your task +Once you've completed your task, input: +`done ` +index being the number of the task you just completed. + +You should see your task appear completed in this format +![Image](done.png) + +That's it for the Quickstart. You can refer to the Features sections below for everything Eu Zin's Duke can do. + +--- + +# Features +Eu Zin's Duke contains easy to use features that are activated by typing commands in the User Input Box and hitting the *Send* Button. + +### List View: `list` +Shows every task in your list, completed or not. + +Format: `list` + +### Add todo: `todo` +Adds a todo to the end of your list. +A todo consists of only a **description**. + +Format: `todo ` + +### Add event: `event` +Adds an event to the end of your list. +An event consists of a **description** and a **timeframe**, which can be input in any string format. + +Format: `event /at ` + +### Add deadline: `deadline` +Adds a deadline to the end of your list. +A deadline consists of a **description** and a **date-time**. The description can be in any string format. +> **_NOTE:_** **The date-time must be strictly in either of these formats:** DD/MM/YYYY TTTT *OR* YYYY/MM/DD TTTT + +Format: `deadline /by ` + +### Mark as Complete: `done` +When you have finished a task, you can mark it as complete. It will be displayed on your list with a tick. +The task to mark as complete is **specified by its index number in integer form** + +Format: `done ` + +### Delete task: `delete` +Removed a task completely from your list. +The task to delete is **specified by its index number in integer form** + +Format: `delete ` + +### Set task duration: `duration` +Set a duration for a particular task in your list. +The task to set duration for is **specified by its index number in integer form** +The duration can be enter in any string format. + +Format: `duration ` + +### Search for a task: `find` +Find a particular task in your list using a keyword. +The keyword can be in any string format. + +Format: `find ` + +--- +# FAQ +##### Q. Will my list be saved after I close Eu Zin's Duke? +##### A: Yes it will be saved and loaded when you reopen Eu Zin's Duke. + +--- +# Command Summary + +| Action | Format | +| ------ | ------ | +| Add todo | Format: `todo ` | +| Add event | Format: `event /at `| +| Add deadline | Format: `deadline /by ` | +| Mark as Complete | Format: `done ` | +| Delete Task | Format: `delete ` | +| Search for Task | Format: `find ` | \ No newline at end of file diff --git a/docs/Ui.png b/docs/Ui.png new file mode 100644 index 0000000000..8b6e097410 Binary files /dev/null and b/docs/Ui.png differ diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000000..c741881743 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-slate \ No newline at end of file diff --git a/docs/done.png b/docs/done.png new file mode 100644 index 0000000000..531d596f61 Binary files /dev/null and b/docs/done.png differ diff --git a/docs/start.PNG b/docs/start.PNG new file mode 100644 index 0000000000..433f34d1be Binary files /dev/null and b/docs/start.PNG differ diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..f3d88b1c2f Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..bd1b0284d6 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Sep 01 23:06:27 SGT 2020 +distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew new file mode 100755 index 0000000000..2fe81a7d95 --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000..62bd9b9cce --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/iPStorage b/iPStorage new file mode 100644 index 0000000000..ddb61870ef --- /dev/null +++ b/iPStorage @@ -0,0 +1,5 @@ +D ~ 1 ~ assignment ~ 2020/09/14 2359 ~ +E ~ 0 ~ party ~ tonight ~ 2hours +T ~ 1 ~ workout ~ +T ~ 0 ~ workout2 ~ +T ~ 0 ~ sleep ~ diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 0000000000..b67c700ac5 --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,70 @@ +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.Scanner; + +public class Deadline extends Task { + LocalDate deadlineDate; + LocalTime deadlineTime; + + public Deadline(String userInput) throws deadlineException { + String[] StringArr = handleUserInput(userInput); + this.description = StringArr[0]; + deadlineDate = processDate(StringArr[1]); + deadlineTime = processTime(StringArr[1]); + } + + + // Constructor for use by Storage.loadFromDisk(); + public Deadline(String description, String deadline, boolean isDone) throws deadlineException { + super(description); + deadlineDate = processDate(deadline); + deadlineTime = processTime(deadline); + this.isDone = isDone; + } + + private String[] handleUserInput(String userInput) throws deadlineException { + String[] StringArr = userInput.split(" /by "); + if (StringArr.length != 2) throw new deadlineException("\"1.Please provide a deadline is the following " + + "format: or "); + StringArr[0] = StringArr[0].replace("deadline ", ""); + if (StringArr[0].equals("")) throw new deadlineException("Please give a description"); + return StringArr; + } + + private LocalDate processDate(String deadline) throws deadlineException { + String[] dateTimeSplit = deadline.split(" "); + String[] dateSplit = dateTimeSplit[0].split("/"); + if (dateTimeSplit.length != 2 || dateSplit.length != 3) + throw new deadlineException("3.Please provide a deadline is the following " + + "format: or "); + if (dateSplit[0].length() == 4) { + return LocalDate.of(Integer.parseInt(dateSplit[0]), Integer.parseInt(dateSplit[1]), Integer.parseInt(dateSplit[2])); + } else { + return LocalDate.of(Integer.parseInt(dateSplit[2]), Integer.parseInt(dateSplit[1]), Integer.parseInt(dateSplit[0])); + } + } + + private LocalTime processTime(String deadline) { + String[] dateTimeSplit = deadline.split(" "); + return LocalTime.of(Integer.parseInt(dateTimeSplit[1].substring(0, 2)), Integer.parseInt(dateTimeSplit[1].substring(2))); + } + + @Override + public String getDescription() { + return super.getDescription() + " ~ " + deadlineDate.toString().replaceAll("-", "/") + " " + deadlineTime.toString().replace(":", ""); + } + + @Override + public String getStatusIcon() { + return (isDone ? "[\u2713]" : "[\u2718]"); //return tick or X symbols + } + + @Override + public String toString() { + String returnString = ""; + returnString += "[D]" + super.getStatusIcon() + this.description + " (by:" + deadlineDate.toString() + " " + deadlineTime.toString() + ")"; + if (!duration.equals("")) returnString += " (duration: " + this.duration + ")"; + return returnString; + } +} diff --git a/src/main/java/DialogBox.java b/src/main/java/DialogBox.java new file mode 100644 index 0000000000..a1e0f5b733 --- /dev/null +++ b/src/main/java/DialogBox.java @@ -0,0 +1,60 @@ +import java.io.IOException; +import java.util.Collections; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; +import javafx.scene.text.Text; + +/** + * An example of a custom control using FXML. + * This control represents a dialog box consisting of an ImageView to represent the speaker's face and a label + * containing text from the speaker. + */ +public class DialogBox extends HBox { + @FXML + private Label dialog; + @FXML + private ImageView displayPicture; + + private DialogBox(String text, Image img) { + try { + FXMLLoader fxmlLoader = new FXMLLoader(MainWindow.class.getResource("/view/DialogBox.fxml")); + fxmlLoader.setController(this); + fxmlLoader.setRoot(this); + fxmlLoader.load(); + } catch (IOException e) { + e.printStackTrace(); + } + + dialog.setText(text); + displayPicture.setImage(img); + } + + /** + * Flips the dialog box such that the ImageView is on the left and text on the right. + */ + private void flip() { + ObservableList tmp = FXCollections.observableArrayList(this.getChildren()); + Collections.reverse(tmp); + getChildren().setAll(tmp); + setAlignment(Pos.TOP_LEFT); + } + + public static DialogBox getUserDialog(String text, Image img) { + return new DialogBox(text, img); + } + + public static DialogBox getDukeDialog(String text, Image img) { + var db = new DialogBox(text, img); + db.flip(); + return db; + } +} diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5d313334cc..dbcd91bfdc 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,10 +1,38 @@ +import java.io.IOException; + + public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); + private final Storage storage; + private final Parser parser; + private final Ui ui; + + public Duke() throws IOException, ToDoException, eventException, deadlineException { + Storage dukeStorage = Storage.initialiseStorage(); + this.storage = dukeStorage; + this.parser = new Parser(); + this.ui = new Ui(); } -} + + /** + * You should have your own function to generate a response to user input. + * Replace this stub with your completed method. + */ + String getResponse(String userInput) throws IOException{ + TaskList taskList = this.storage.taskList; + try { + if (userInput.equals("bye")) { + return ui.showByeMessage(); + } else if (userInput.equals("list")) { + return ui.showList(storage.taskList); + } else if (userInput.startsWith("todo") || userInput.startsWith("deadline") || userInput.startsWith("event")) { + return parser.processAddTaskInput(userInput, taskList, storage, ui); + } else { + TaskList originalTaskList = TaskList.copy(taskList); + parser.processOtherActionInput(userInput, taskList, ui, storage); + return ui.showOtherActionMessage(userInput, originalTaskList); + } + } catch (DukeException e) { + return e.toString(); + } + } +} \ No newline at end of file diff --git a/src/main/java/DukeException.java b/src/main/java/DukeException.java new file mode 100644 index 0000000000..5db6be69e9 --- /dev/null +++ b/src/main/java/DukeException.java @@ -0,0 +1,14 @@ +public class DukeException extends Throwable { + String message = ""; + + public DukeException() {}; + + public DukeException(String message) { + this.message = message; + } + + public String toString() { + if (!message.equals("")) return message; + else return "Duke is too dumb, Duke dunno what you mean"; + } +} diff --git a/src/main/java/DurationException.java b/src/main/java/DurationException.java new file mode 100644 index 0000000000..9ae536754f --- /dev/null +++ b/src/main/java/DurationException.java @@ -0,0 +1,7 @@ +public class DurationException extends DukeException { + + @Override + public String toString() { + return "Please provide a duration to set in the following format: duration "; + } +} diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 0000000000..0ba13d8e79 --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,45 @@ + + +public class Event extends Task{ + String timeFrame; + + public Event(String userInput) throws eventException { + String[] handledUserInput = handleUserInput(userInput); + this.description = handledUserInput[0]; + this.timeFrame = handledUserInput[1]; + } + + public Event(String description, String timeFrame, boolean isDone) throws eventException { + this.description = description; + this.timeFrame = timeFrame; + this.isDone = isDone; + } + + private String[] handleUserInput(String userInput) throws eventException{ + eventException properFormatAdvisoryException = new eventException("Please provide event in the following " + + "format: "); + if (userInput.equals("event")) throw properFormatAdvisoryException; + String[] StringArr = userInput.split(" /at"); + if (StringArr.length != 2) throw properFormatAdvisoryException; + StringArr[0] = StringArr[0].replace("event ", ""); + return StringArr; + } + + @Override + public String getDescription() { + return super.getDescription() + " ~ " + this.timeFrame; + } + + @Override + public String getStatusIcon() { + return (isDone ? "[\u2713]" : "[\u2718]"); //return tick or X symbols + } + + @Override + public String toString() { + String returnString = ""; + returnString += "[E]" + getStatusIcon() + this.description + " (at:" + this.timeFrame + ")"; + if (!duration.equals("")) returnString += " (duration: " + this.duration + ")"; + return returnString; + } +} diff --git a/src/main/java/Launcher.java b/src/main/java/Launcher.java new file mode 100644 index 0000000000..0e288bc006 --- /dev/null +++ b/src/main/java/Launcher.java @@ -0,0 +1,7 @@ +import javafx.application.Application; + +public class Launcher { + public static void main(String[] args) { + Application.launch(Main.class, args); + } +} diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..f578f7960d --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: Launcher + diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 0000000000..bf3b6338b6 --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,32 @@ +import java.io.IOException; + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; + +/** + * A GUI for Duke using FXML. + */ +public class Main extends Application { + + private Duke duke = new Duke(); + + public Main() throws IOException, ToDoException, eventException, deadlineException { + } + + @Override + public void start(Stage stage) { + try { + FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("/view/MainWindow.fxml")); + AnchorPane ap = fxmlLoader.load(); + Scene scene = new Scene(ap); + stage.setScene(scene); + fxmlLoader.getController().setDuke(duke); + stage.show(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/MainWindow.java b/src/main/java/MainWindow.java new file mode 100644 index 0000000000..19569952dd --- /dev/null +++ b/src/main/java/MainWindow.java @@ -0,0 +1,52 @@ +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.image.Image; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.VBox; + +import java.io.IOException; + +/** + * Controller for MainWindow. Provides the layout for the other controls. + */ +public class MainWindow extends AnchorPane { + @FXML + private ScrollPane scrollPane; + @FXML + private VBox dialogContainer; + @FXML + private TextField userInput; + @FXML + private Button sendButton; + + private Duke duke; + + private Image userImage = new Image(this.getClass().getResourceAsStream("/images/User.jpg")); + private Image dukeImage = new Image(this.getClass().getResourceAsStream("/images/Duke.jpg")); + + @FXML + public void initialize() { + scrollPane.vvalueProperty().bind(dialogContainer.heightProperty()); + } + + public void setDuke(Duke d) { + duke = d; + } + + /** + * Creates two dialog boxes, one echoing user input and the other containing Duke's reply and then appends them to + * the dialog container. Clears the user input after processing. + */ + @FXML + private void handleUserInput() throws IOException { + String input = userInput.getText(); + String response = duke.getResponse(input); + dialogContainer.getChildren().addAll( + DialogBox.getUserDialog(input, userImage), + DialogBox.getDukeDialog(response, dukeImage) + ); + userInput.clear(); + } +} diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java new file mode 100644 index 0000000000..3c539e12a5 --- /dev/null +++ b/src/main/java/Parser.java @@ -0,0 +1,71 @@ +import java.io.IOException; +import java.util.Scanner; + +public class Parser { + /** + * Returns appropriate task after processing userInput. Calls on ui to give user a response + * + * @param userInput + * @return Task to be used by Duke instance + * @throws ToDoException + * @throws deadlineException + * @throws eventException + */ + public String processAddTaskInput(String userInput, TaskList taskList, Storage storage, Ui ui) throws DukeException, IOException { + String taskType = userInput.split(" ")[0]; + Task thisTask = null; + switch (taskType) { + case "todo": + thisTask = new Task(userInput.replace("todo ", "")); + taskList.addTask(thisTask, storage); + return ui.showAddTaskMessage(thisTask, taskList); + case "deadline": + thisTask = new Deadline(userInput); + taskList.addTask(thisTask, storage); + return ui.showAddTaskMessage(thisTask, taskList); + case "event": + thisTask = new Event(userInput); + taskList.addTask(thisTask, storage); + return ui.showAddTaskMessage(thisTask, taskList); + default: + throw new DukeException(); + } + } + + /** + * Processes userInput and calls on ui to give appropriate response to the user + * + * @param userInput + * @param taskList + * @throws IOException + * @throws DukeException + */ + public String processOtherActionInput(String userInput, TaskList taskList, Ui ui, Storage storage) throws IOException, DukeException { + String[] splitUserInput = userInput.split(" "); + String actionType = splitUserInput[0]; + if (splitUserInput[1].equals("")) throw new DukeException("Please enter an index/duration"); + switch (actionType) { + case "done": + int doneIndex = Integer.parseInt(userInput.replace("done ", "")); + assert doneIndex >= 1 : "Index must be a positive value"; + taskList.taskCompleted(doneIndex, storage); + return ui.showOtherActionMessage(userInput, taskList); + case "delete": + int indexDeleted = Integer.parseInt(userInput.replace("delete ", "")); + TaskList duplicatedTaskList = TaskList.copy(taskList); + assert indexDeleted >= 1 : "Index must be a positive value"; + taskList.deleteTask(indexDeleted, storage); + return ui.showOtherActionMessage(userInput, duplicatedTaskList); + case "find": + return ui.showOtherActionMessage(userInput, taskList); + case "duration": + if (userInput.equals("duration")) throw new DurationException(); + int indexSettingDuration = Integer.parseInt(userInput.split(" ")[1]); + assert indexSettingDuration >= 1 : "Index must be a positive value"; + taskList.setDuration(userInput, storage); + return ui.showOtherActionMessage(userInput, taskList); + default: + throw new DukeException(); + } + } +} diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java new file mode 100644 index 0000000000..53b77bfb49 --- /dev/null +++ b/src/main/java/Storage.java @@ -0,0 +1,71 @@ +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Scanner; + +public class Storage { + public TaskList taskList; + static private final String HOME = System.getProperty("user.home"); + static private final java.nio.file.Path PATH = java.nio.file.Paths.get(HOME, "data"); + static private final java.nio.file.Path FILE = java.nio.file.Paths.get(HOME, "data", "iPStorage.txt"); + + public static Storage initialiseStorage() throws IOException, ToDoException, eventException, deadlineException { + Storage returnStorage = new Storage(); + returnStorage.taskList = TaskList.retrieveTaskList(FILE); + returnStorage.loadFromDisk(); + return returnStorage; + } + + /** + * Called when Duke is initialised + * @throws IOException + */ + public void loadFromDisk() throws IOException, ToDoException, eventException, deadlineException { + taskList = TaskList.retrieveTaskList(FILE); + } + + /** + * Writes a specific task to the hard disc. Called by saveToDisk() method + * @param task + * @param printWriter + * @throws IOException + */ + public void writeTask(Task task, PrintWriter printWriter) throws IOException { + Class taskType = task.getClass(); + + if (taskType.equals(Event.class)) { + printWriter.print("E ~ "); + } else if (taskType.equals(Deadline.class)) { + printWriter.print("D ~ "); + } else { + printWriter.print("T ~ "); + } + + printWriter.print(task.isDone ? "1 ~ " : "0 ~ "); + printWriter.print(task.getDescription()); + printWriter.print(" ~ " + task.getDuration()); + printWriter.print("\n"); + } + + /** + * Called every time a change is made to the list. Updates the data stored on hard disc + * @throws IOException + */ + public void saveToDisk() throws IOException { + boolean directoryExists = java.nio.file.Files.exists(PATH); + + if (!directoryExists) { + Files.createDirectory(PATH); + } + + FileWriter fileWriter = new FileWriter(FILE.toFile()); + PrintWriter printWriter = new PrintWriter(fileWriter); + + for (Task task : taskList.getList()) { + writeTask(task, printWriter); + } + printWriter.close(); + } +} diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 0000000000..ba29270b59 --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,47 @@ +public class Task { + protected String description; + protected boolean isDone; + protected String duration = ""; + + public Task() { } + + public Task(String description) { + this.description = description; + this.isDone = false; + } + + public Task(String description, boolean isDone) throws ToDoException { + if (description.equals("")) throw new ToDoException(); + this.description = description; + this.isDone = isDone; + } + + public Task(String description, boolean isDone, String duration) { + this.description = description; + this.isDone = isDone; + this.duration = duration; + } + + public String getDescription() { + return this.description; + } + + public String getStatusIcon() { + return (isDone ? "[\u2713]" : "[\u2718]"); //return tick or X symbols + } + + public String toString(){ + String returnString = ""; + returnString += "[T]" + this.getStatusIcon() + this.description; + if (!duration.equals("")) returnString += " (duration: " + this.duration + ")"; + return returnString; + } + + public void setDuration(String duration) { + this.duration = duration; + } + + public String getDuration() { + return duration; + } +} diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java new file mode 100644 index 0000000000..8b23aeeda2 --- /dev/null +++ b/src/main/java/TaskList.java @@ -0,0 +1,149 @@ +import javax.lang.model.type.ArrayType; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Scanner; + +public class TaskList { + private final ArrayList taskList; + + public TaskList() { + taskList = new ArrayList<>(); + } + + private TaskList(ArrayList taskList) { + this.taskList = taskList; + } + + private void add(Task task) { + this.taskList.add(task); + } + + /** + * Called by Storage when Duke is initialised. Looks for the on hard disc storage of the list. If found, retrieves it to be used by Duke + * Else the text file is created to be used for future storing on hard disc + * @param File + * @return + * @throws IOException + */ + public static TaskList retrieveTaskList(Path File) throws IOException, ToDoException, eventException, deadlineException { + TaskList returnTaskList = new TaskList(); + if (java.nio.file.Files.exists(File)) { + Scanner scanner = new Scanner(File); + while (scanner.hasNextLine()) { + Task taskAdded = null; + String taskData = scanner.nextLine(); + String[] taskDataDivided = taskData.split(" ~ "); + boolean isDone = taskDataDivided[1].equals("1"); + switch (taskDataDivided[0]) { + case "E": + taskAdded = new Event(taskDataDivided[2], taskDataDivided[3], isDone); + if (taskDataDivided.length > 4) taskAdded.setDuration(taskDataDivided[4]); + returnTaskList.add(taskAdded); + break; + case "D": + taskAdded = new Deadline(taskDataDivided[2], taskDataDivided[3], isDone); + if (taskDataDivided.length > 4) taskAdded.setDuration(taskDataDivided[4]); + returnTaskList.add(taskAdded); + break; + case "T": + taskAdded = new Task(taskDataDivided[2], isDone); + if (taskDataDivided.length > 3) taskAdded.setDuration(taskDataDivided[3]); + returnTaskList.add(taskAdded); + break; + } + } + } + return returnTaskList; + } + + public static TaskList copy(TaskList copiedTaskList) { + return new TaskList(copiedTaskList.getList()); + } + + /** + * Getter to return a copy of the ArrayList + * @return copy of ArrayList + */ + public ArrayList getList() { + ArrayList returnTaskList = new ArrayList<>(); + for (Task task : taskList) returnTaskList.add(task); + return returnTaskList; + } + + /** + * Deletes task specific to the index + * @param index + * @throws deleteException + * @throws IOException + */ + public void deleteTask(int index, Storage storage) throws deleteException, IOException { + if (index <= taskList.size()) { + taskList.remove(index - 1); + storage.saveToDisk(); + } else { + throw new deleteException(); + } + } + + public void setDuration(String userInput, Storage storage) throws IOException { + String[] splitBySpaces = userInput.split(" "); + int indexSettingDuration = Integer.parseInt(splitBySpaces[1]); + String durationSet = splitBySpaces[2]; + Task taskSettingDurationFor = taskList.get(indexSettingDuration-1); + taskSettingDurationFor.setDuration(durationSet); + storage.saveToDisk(); + } + + /** + * Add Task given to the list + * @param task + */ + public void addTask(Task task, Storage storage) throws IOException { + taskList.add(task); + storage.saveToDisk(); + } + + /** + * Marks task with given index as completed + * @param index + */ + public void taskCompleted(int index, Storage storage) throws IOException { + taskList.get(index - 1).isDone = true; + storage.saveToDisk(); + } + + /** + * getter for the size of the ArrayList + * @return + */ + public int getSize() { + return taskList.size(); + } + + public ArrayList searchFor(String searchString) { + ArrayList returnArrayList = new ArrayList<>(); + for (Task task : taskList) { + if (task.getDescription().contains(searchString)) returnArrayList.add(task); + } + return returnArrayList; + } + + + public String printTaskList() { + if (this.taskList.size() == 0) { + return "You currently have nothing on your list"; + } else { + String returnString = "Here's what you have on your list"; + int counter = 0; + Iterator taskIterator = this.taskList.iterator(); + while (taskIterator.hasNext()) { + Task thisTask = taskIterator.next(); + returnString += "\n" + (counter + 1) + ". " + thisTask.toString(); + counter++; + } + return returnString; + } + } +} diff --git a/src/main/java/ToDoException.java b/src/main/java/ToDoException.java new file mode 100644 index 0000000000..5a6b55eb23 --- /dev/null +++ b/src/main/java/ToDoException.java @@ -0,0 +1,7 @@ +public class ToDoException extends DukeException { + + public String toString() { + return "what todo gimme smth to write pls"; + } + +} diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java new file mode 100644 index 0000000000..4b5423a7c2 --- /dev/null +++ b/src/main/java/Ui.java @@ -0,0 +1,55 @@ +import java.util.ArrayList; + +public class Ui { + private static final String LOGO = " ____ _ \n" + + "| _ \\ _ _| | _____ \n" + + "| | | | | | | |/ / _ \\\n" + + "| |_| | |_| | < __/\n" + + "|____/ \\__,_|_|\\_\\___|\n"; + + public void showWelcomeMessage() { + System.out.println(LOGO + "\nHello im Eu Zin's Duke, he spent thursday afternoon creating me cuz he forgot abt the iP"); + } + + public String showAddTaskMessage(Task thisTask, TaskList taskList) { + return "I've added\n" + thisTask.toString() + " | to your list. \nNow got " + (taskList.getSize()) + " task in the list\n"; + } + + public String showOtherActionMessage(String userInput, TaskList taskList) throws DukeException { + String processedInput = userInput.split(" ")[0]; + switch (processedInput) { + case "done" : + int doneIndex = Integer.parseInt(userInput.substring(5)); + return "ok sure good job i guess\n" + taskList.getList().get(doneIndex-1) + "\n"; + case "delete" : + int indexDeleted = Integer.parseInt(userInput.replace("delete ", "")); + return "ok deleted this task alr:\n" + taskList.getList().get(indexDeleted-1) + "\n" + "Now you left " + (taskList.getSize()-1) + + " task(s)"; + case "find" : + ArrayList taskArrayList = taskList.searchFor(userInput.split(" ")[1]); + if (taskArrayList.size() == 0) { + return "We were unable to find your task"; + } else { + String returnString = "Here is what we found \n"; + for (Task task : taskArrayList) { + returnString += task.toString() + "\n"; + } + return returnString; + } + case "duration" : + int indexSettingDuration = Integer.parseInt(userInput.split(" ")[1]); + return "duration has been set for:\n" + taskList.getList().get(indexSettingDuration-1); + default : + throw new DukeException(); + } + } + + public String showByeMessage() { + return "Bye. Hope to see you again soon!"; + } + + public String showList(TaskList taskList) { + return taskList.printTaskList(); + } + +} diff --git a/src/main/java/deadlineException.java b/src/main/java/deadlineException.java new file mode 100644 index 0000000000..f9585e2c3c --- /dev/null +++ b/src/main/java/deadlineException.java @@ -0,0 +1,11 @@ +public class deadlineException extends DukeException { + + public deadlineException(String message) { + super(message); + } + + public String toString() { + if (!message.equals("")) return message; + else return "what deadline gimme smth to write pls"; + } +} diff --git a/src/main/java/deleteException.java b/src/main/java/deleteException.java new file mode 100644 index 0000000000..2eb1790e18 --- /dev/null +++ b/src/main/java/deleteException.java @@ -0,0 +1,5 @@ +public class deleteException extends DukeException { + public String toString() { + return "delete whaaaaaaaaat"; + } +} diff --git a/src/main/java/eventException.java b/src/main/java/eventException.java new file mode 100644 index 0000000000..436f827fff --- /dev/null +++ b/src/main/java/eventException.java @@ -0,0 +1,12 @@ +public class eventException extends DukeException { + + + public eventException(String message) { + super(message); + } + + public String toString() { + if (!message.equals("")) return message; + else return "what event gimme smth to write pls"; + } +} diff --git a/src/main/java/searchException.java b/src/main/java/searchException.java new file mode 100644 index 0000000000..5df5106f6c --- /dev/null +++ b/src/main/java/searchException.java @@ -0,0 +1,7 @@ +public class searchException extends DukeException { + + @Override + public String toString() { + return "nothing to search"; + } +} diff --git a/src/main/resources/images/DaDuke.png b/src/main/resources/images/DaDuke.png new file mode 100644 index 0000000000..d893658717 Binary files /dev/null and b/src/main/resources/images/DaDuke.png differ diff --git a/src/main/resources/images/DaUser.png b/src/main/resources/images/DaUser.png new file mode 100644 index 0000000000..3c82f45461 Binary files /dev/null and b/src/main/resources/images/DaUser.png differ diff --git a/src/main/resources/images/Duke.jpg b/src/main/resources/images/Duke.jpg new file mode 100644 index 0000000000..a16479523b Binary files /dev/null and b/src/main/resources/images/Duke.jpg differ diff --git a/src/main/resources/images/User.jpg b/src/main/resources/images/User.jpg new file mode 100644 index 0000000000..b160626b4f Binary files /dev/null and b/src/main/resources/images/User.jpg differ diff --git a/src/main/resources/view/DialogBox.fxml b/src/main/resources/view/DialogBox.fxml new file mode 100644 index 0000000000..ddb68605e8 --- /dev/null +++ b/src/main/resources/view/DialogBox.fxml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml new file mode 100644 index 0000000000..df46910af2 --- /dev/null +++ b/src/main/resources/view/MainWindow.fxml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/DukeTest.java b/src/test/java/DukeTest.java new file mode 100644 index 0000000000..c613cf08a9 --- /dev/null +++ b/src/test/java/DukeTest.java @@ -0,0 +1,28 @@ +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DukeTest { + Parser parser = new Parser(); + + @Test + public void invalidUserInputTest() throws IOException, DukeException { + try { + parser.processOtherActionInput("anyhow", new TaskList(), new Ui()); + } catch (DukeException e) { + assertEquals(e.toString(), "Duke is too dumb, Duke dunno what you mean"); + } + } + + @Test + public void deadlineWithoutDescriptionTest() throws ToDoException, eventException { + try { + parser.processAddTaskInput("deadline", new TaskList(), new Ui()); + } catch (deadlineException e) { + assertEquals(e.toString(), "what deadline gimme smth to write pls"); + } + } +} diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 657e74f6e7..09e0af68b4 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,62 @@ -Hello from - ____ _ +____ _ | _ \ _ _| | _____ | | | | | | | |/ / _ \ | |_| | |_| | < __/ |____/ \__,_|_|\_\___| +Hello im Eu Zin's Duke, he spent thursday afternoon creating me cuz he forgot abt the iP + +\ / \ / \ / \ / im not very creative \ / \ / \ / \ / + \ / \ / \ / \ / EuZin's Duke \ / \ / \ / \ / + +ok can i've added it +[T][✘]bring dogs for walk +Now got 1 task in the list + +\ / \ / \ / \ / im not very creative \ / \ / \ / \ / + \ / \ / \ / \ / EuZin's Duke \ / \ / \ / \ / + + +\ / \ / \ / \ / im not very creative \ / \ / \ / \ / + \ / \ / \ / \ / EuZin's Duke \ / \ / \ / \ / + +ok can i've added it +[E][✘]birthday party (at: tonight) +Now got 2 task in the list + +\ / \ / \ / \ / im not very creative \ / \ / \ / \ / + \ / \ / \ / \ / EuZin's Duke \ / \ / \ / \ / + +\ / \ / \ / \ / im not very creative \ / \ / \ / \ / + \ / \ / \ / \ / EuZin's Duke \ / \ / \ / \ / + +ok can i've added it +[D][✘]finish tutorial (by: today) +Now got 3 task in the list + +\ / \ / \ / \ / im not very creative \ / \ / \ / \ / + \ / \ / \ / \ / EuZin's Duke \ / \ / \ / \ / + +\ / \ / \ / \ / im not very creative \ / \ / \ / \ / + \ / \ / \ / \ / EuZin's Duke \ / \ / \ / \ / + +ok sure good job i guess +[✓] [E][✓]birthday party (at: tonight) + +\ / \ / \ / \ / im not very creative \ / \ / \ / \ / + \ / \ / \ / \ / EuZin's Duke \ / \ / \ / \ / + +\ / \ / \ / \ / im not very creative \ / \ / \ / \ / + \ / \ / \ / \ / EuZin's Duke \ / \ / \ / \ / + +faster do don't netflix already +1. [T][✘]todo bring dogs for walk +2. [E][✓]birthday party (at: tonight) +3. [D][✘]finish tutorial (by: today) + +\ / \ / \ / \ / im not very creative \ / \ / \ / \ / + \ / \ / \ / \ / EuZin's Duke \ / \ / \ / \ / + + + + diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index e69de29bb2..a626518e9a 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -0,0 +1,5 @@ +todo bring dogs for walk +event birthday party /at tonight +deadline finish tutorial /by today +done 2 +list \ No newline at end of file diff --git a/text-ui-test/runtest.bat b/text-ui-test/runtest.bat index d0facc6310..afea3cbc70 100644 --- a/text-ui-test/runtest.bat +++ b/text-ui-test/runtest.bat @@ -1,13 +1,13 @@ @ECHO OFF REM create bin directory if it doesn't exist -if not exist ..\bin mkdir ..\bin +if not exist C:\Users\euzun\IdeaProjects\ip\bin mkdir C:\Users\euzun\IdeaProjects\ip\bin REM delete output from previous run del ACTUAL.TXT REM compile the code into the bin folder -javac -cp ..\src -Xlint:none -d ..\bin ..\src\main\java\Duke.java +javac -cp ..\src -Xlint:none -d ..\bin ..\src\main\java\*.java IF ERRORLEVEL 1 ( echo ********** BUILD FAILURE ********** exit /b 1 @@ -15,7 +15,7 @@ IF ERRORLEVEL 1 ( REM no error here, errorlevel == 0 REM run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT -java -classpath ..\bin Duke < input.txt > ACTUAL.TXT +java -classpath C:\Users\euzun\IdeaProjects\ip\bin Duke < input.txt > ACTUAL.TXT REM compare the output to the expected output FC ACTUAL.TXT EXPECTED.TXT diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh old mode 100644 new mode 100755