diff --git a/.gitignore b/.gitignore index 2873e189e1..d7a2c1593f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,19 @@ -# IDEA files -/.idea/ -/out/ -/*.iml - -# Gradle build files -/.gradle/ -/build/ -src/main/resources/docs/ - -# MacOS custom attributes files created by Finder -.DS_Store -*.iml -bin/ - -/text-ui-test/ACTUAL.TXT -text-ui-test/EXPECTED-UNIX.TXT +# IDEA files +/.idea/ +/out/ +/*.iml + +# Gradle build files +/.gradle/ +/build/ +src/main/resources/docs/ +gradle/ + +# MacOS custom attributes files created by Finder +.DS_Store +*.iml +bin/ + +/text-ui-test/ACTUAL.TXT +text-ui-test/EXPECTED-UNIX.TXT +/.class diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 8e359a0145..419450f2f6 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,9 +1,9 @@ -# Contributors - -Display | Name | Github Profile | Homepage ----|:---:|:---:|:---: -![](https://avatars0.githubusercontent.com/u/22460123?s=100) | Jeffry Lum | [Github](https://github.com/j-lum/) | [Homepage](https://se.kasugano.moe) -![](https://avatars0.githubusercontent.com/u/1673303?s=100) | Damith C. Rajapakse | [Github](https://github.com/damithc/) | [Homepage](https://www.comp.nus.edu.sg/~damithch/) -# I would like to join this list. How can I help the project - -For more information, please refer to our [contributor's guide](https://oss-generic.github.io/process/). +# Contributors + +Display | Name | Github Profile | Homepage +---|:---:|:---:|:---: +![](https://avatars0.githubusercontent.com/u/22460123?s=100) | Jeffry Lum | [Github](https://github.com/j-lum/) | [Homepage](https://se.kasugano.moe) +![](https://avatars0.githubusercontent.com/u/1673303?s=100) | Damith C. Rajapakse | [Github](https://github.com/damithc/) | [Homepage](https://www.comp.nus.edu.sg/~damithch/) +# I would like to join this list. How can I help the project + +For more information, please refer to our [contributor's guide](https://oss-generic.github.io/process/). diff --git a/README.md b/README.md index af0309a9ef..406b2cda32 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,26 @@ -# Duke project template - -This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it. - -## Setting up in Intellij - -Prerequisites: JDK 17, update Intellij to the most recent version. - -1. Open Intellij (if you are not in the welcome screen, click `File` > `Close Project` to close the existing project first) -1. Open the project into Intellij as follows: - 1. Click `Open`. - 1. Select the project directory, and click `OK`. - 1. If there are any further prompts, accept the defaults. -1. Configure the project to use **JDK 17** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).
- In the same dialog, set the **Project language level** field to the `SDK default` option. -1. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output: - ``` - Hello from - ____ _ - | _ \ _ _| | _____ - | | | | | | | |/ / _ \ - | |_| | |_| | < __/ - |____/ \__,_|_|\_\___| - ``` - -**Warning:** Keep the `src\main\java` folder as the root folder for Java files (i.e., don't rename those folders or move Java files to another folder outside of this folder path), as this is the default location some tools (e.g., Gradle) expect to find Java files. +# Duke project template + +This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it. + +## Setting up in Intellij + +Prerequisites: JDK 17, update Intellij to the most recent version. + +1. Open Intellij (if you are not in the welcome screen, click `File` > `Close Project` to close the existing project first) +1. Open the project into Intellij as follows: + 1. Click `Open`. + 1. Select the project directory, and click `OK`. + 1. If there are any further prompts, accept the defaults. +1. Configure the project to use **JDK 17** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).
+ In the same dialog, set the **Project language level** field to the `SDK default` option. +1. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output: + ``` + Hello from + ____ _ + | _ \ _ _| | _____ + | | | | | | | |/ / _ \ + | |_| | |_| | < __/ + |____/ \__,_|_|\_\___| + ``` + +**Warning:** Keep the `src\main\java` folder as the root folder for Java files (i.e., don't rename those folders or move Java files to another folder outside of this folder path), as this is the default location some tools (e.g., Gradle) expect to find Java files. diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000000..52631abcac --- /dev/null +++ b/build.gradle @@ -0,0 +1,59 @@ +plugins { + id 'java' + id 'application' + id 'com.github.johnrengelman.shadow' version '7.1.2' +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.0' + testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.0' + + String javaFxVersion = '17.0.7' + + 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' +} + +test { + useJUnitPlatform() + + testLogging { + events "passed", "skipped", "failed" + + showExceptions true + exceptionFormat "full" + showCauses true + showStackTraces true + showStandardStreams = false + } +} + +application { + mainClass.set("hewwokitty.Launcher") +} + +shadowJar { + archiveBaseName = "hewwokitty" + archiveClassifier = null + archiveFileName = "hewwokitty.jar" +} + +run{ + standardInput = System.in +} + + diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 0000000000..60e677779e --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,434 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml new file mode 100644 index 0000000000..b18688d2f1 --- /dev/null +++ b/config/checkstyle/suppressions.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/data/hewwoTasks.txt b/data/hewwoTasks.txt new file mode 100644 index 0000000000..687d14690c --- /dev/null +++ b/data/hewwoTasks.txt @@ -0,0 +1 @@ +T|0|cry diff --git a/docs/README.md b/docs/README.md index 47b9f984f7..ceb07df1b5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,30 +1,30 @@ -# Duke User Guide - -// Update the title above to match the actual product name - -// Product screenshot goes here - -// Product intro goes here - -## Adding deadlines - -// Describe the action and its outcome. - -// Give examples of usage - -Example: `keyword (optional arguments)` - -// A description of the expected outcome goes here - -``` -expected output -``` - -## Feature ABC - -// Feature details - - -## Feature XYZ - -// Feature details \ No newline at end of file +# HewwoKitty Usew Guide UwU + +![Ui.png](Ui.png) + +## Managing Tasks + +hewwokitty can hewp you keep twack of many twypes of tasks! + +**how to use!** + 1. todo [description] + 1. creates a Todo task +2. deadline [description] /by [date in yyyy-MM-dd] + 1. creates a Deadline task +3. event [description] /from [start date] /to [end date] + 1. creates an Event task +4. list + 1. lists all tasks +5. mark [task number] and unmark [task number] + 1. marks a task as complete/incomplete based on the order in the list +6. delete [task number] + 1. removes a task from the list based on the order in the lsit +7. find [keyword] + 1. summarises a list of tasks that contain that keyword + 2. partial searches are possible e.g searching "cry" will also return tasks that are about "crying" + +## Some Exceptions +hewwokitty stwuggwes with some exceptions, hewe is what **NOT** to enter +1. do not leave any fields blank +2. dates which are not in yyyy-MM-dd will not be accepted +3. meowmeowmeowmeowmeow (i am a cat) diff --git a/docs/Ui.png b/docs/Ui.png new file mode 100644 index 0000000000..6919b20c6f Binary files /dev/null and b/docs/Ui.png differ diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..033e24c4cd 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..38b1a5087f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000000..fcb6fca147 --- /dev/null +++ b/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original 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 POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# 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 ;; #( + MSYS* | 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 + if ! command -v java >/dev/null 2>&1 + then + 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 +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# 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"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000..6689b85bee --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@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=. +@rem This is normally unused +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% equ 0 goto execute + +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 execute + +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 + +: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 %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 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! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java deleted file mode 100644 index 5d313334cc..0000000000 --- a/src/main/java/Duke.java +++ /dev/null @@ -1,10 +0,0 @@ -public class Duke { - public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - } -} diff --git a/src/main/java/data/hewwoTasks.txt b/src/main/java/data/hewwoTasks.txt new file mode 100644 index 0000000000..1daac2144f --- /dev/null +++ b/src/main/java/data/hewwoTasks.txt @@ -0,0 +1,5 @@ +E|0|sleep|6pm|8pm +D|1|drugs|2019-10-10 +D|0|meow |2018-08-08 +T|0|help +E|0|do drugs |5pm |7pm diff --git a/src/main/java/hewwokitty/HewwoKitty.java b/src/main/java/hewwokitty/HewwoKitty.java new file mode 100644 index 0000000000..d2a4cb03dc --- /dev/null +++ b/src/main/java/hewwokitty/HewwoKitty.java @@ -0,0 +1,27 @@ +package hewwokitty; + +import java.util.Scanner; + +import hewwokitty.parser.Parser; +import hewwokitty.storage.Storage; +import hewwokitty.task.TaskList; +import hewwokitty.ui.Ui; + +/** + * Main chatbot class + */ +public class HewwoKitty { + public static void main(String[] args) { + boolean isRunning = true; + TaskList taskList = Storage.readFromFile(); + Parser parser = new Parser(); + Scanner sc = new Scanner(System.in); + + Ui.printStart(); + while (isRunning) { + String userInput = sc.nextLine(); + isRunning = parser.processUserCommands(userInput, taskList); + } + Ui.printBye(); + } +} diff --git a/src/main/java/hewwokitty/HewwoKittyGUI.java b/src/main/java/hewwokitty/HewwoKittyGUI.java new file mode 100644 index 0000000000..c480fc4aaa --- /dev/null +++ b/src/main/java/hewwokitty/HewwoKittyGUI.java @@ -0,0 +1,126 @@ +package hewwokitty; + +import javafx.application.Application; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.layout.VBox; +import javafx.scene.text.Text; +import javafx.scene.text.TextFlow; +import javafx.stage.Stage; + +import hewwokitty.parser.Parser; +import hewwokitty.storage.Storage; +import hewwokitty.task.TaskList; +import hewwokitty.ui.Ui; + +/** + * JavaFX GUI for HewwoKitty chatbot. + */ +@SuppressWarnings("checkstyle:AbbreviationAsWordInName") +public class HewwoKittyGUI extends Application { + private TaskList taskList; + private Parser parser; + private VBox chatArea; + private TextField userInput; + private ByteArrayOutputStream outputStream; + + /** + * Function for the initial creation of the GUI + * @param primaryStage A Stage + */ + @Override + public void start(Stage primaryStage) { + taskList = Storage.readFromFile(); + parser = new Parser(); + + primaryStage.setTitle("HewwoKitty Chatbot"); + + chatArea = new VBox(5); + chatArea.setPadding(new Insets(10)); + chatArea.setStyle("-fx-background-color: #ffd1dc;"); + + ScrollPane scrollPane = new ScrollPane(chatArea); + scrollPane.setFitToWidth(true); + scrollPane.setFitToHeight(true); + scrollPane.setPrefHeight(javafx.stage.Screen.getPrimary().getBounds().getHeight()); // Fits screen height + + userInput = new TextField(); + userInput.setPromptText("Type your message..."); + + Button sendButton = new Button("Send"); + sendButton.setOnAction(e -> handleUserInput()); + + VBox layout = new VBox(10, scrollPane, userInput, sendButton); + layout.setPadding(new Insets(10)); + layout.setPrefHeight(Double.MAX_VALUE); + VBox.setVgrow(scrollPane, javafx.scene.layout.Priority.ALWAYS); + + primaryStage.setScene(new Scene(layout, 500, 700)); + primaryStage.setMaximized(true); + primaryStage.show(); + + captureSystemOutput(); + Ui.printStart(); + appendCapturedOutput(); + } + + private void handleUserInput() { + String input = userInput.getText().trim(); + if (!input.isEmpty()) { + appendUserMessage(input); + + boolean isRunning = parser.processUserCommands(input, taskList); + appendCapturedOutput(); + userInput.clear(); + + if (!isRunning) { + Storage.writeToFile(taskList); + appendBotMessage("hewwo kitty is cwosing uwu~"); + System.exit(0); + } + } + } + + private void appendUserMessage(String message) { + Text text = new Text(message); + TextFlow textFlow = new TextFlow(text); + textFlow.setStyle("-fx-background-color: #d1e7ff; -fx-padding: 8px; -fx-background-radius: 10px;"); + textFlow.setMaxWidth(300); + VBox wrapper = new VBox(textFlow); + wrapper.setAlignment(Pos.CENTER_RIGHT); + chatArea.getChildren().add(wrapper); + } + + private void appendBotMessage(String message) { + Text text = new Text(message); + TextFlow textFlow = new TextFlow(text); + textFlow.setStyle("-fx-background-color: #ffffff; -fx-padding: 8px; -fx-background-radius: 10px;"); + textFlow.setMaxWidth(600); + VBox wrapper = new VBox(textFlow); + wrapper.setAlignment(Pos.CENTER_LEFT); + chatArea.getChildren().add(wrapper); + } + + private void captureSystemOutput() { + outputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outputStream)); + } + + private void appendCapturedOutput() { + String output = outputStream.toString().trim(); + if (!output.isEmpty()) { + appendBotMessage(output); + outputStream.reset(); + } + } + + public static void main(String[] args) { + launch(args); + } +} diff --git a/src/main/java/hewwokitty/Launcher.java b/src/main/java/hewwokitty/Launcher.java new file mode 100644 index 0000000000..37d8e998d6 --- /dev/null +++ b/src/main/java/hewwokitty/Launcher.java @@ -0,0 +1,10 @@ +package hewwokitty; + +import javafx.application.Application; + +public class Launcher { + public static void main(String[] args) { + assert args != null : "Application arguments should not be null"; + Application.launch(HewwoKittyGUI.class, args); + } +} diff --git a/src/main/java/hewwokitty/parser/Parser.java b/src/main/java/hewwokitty/parser/Parser.java new file mode 100644 index 0000000000..8de7da03a1 --- /dev/null +++ b/src/main/java/hewwokitty/parser/Parser.java @@ -0,0 +1,80 @@ +package hewwokitty.parser; + +import hewwokitty.storage.Storage; +import hewwokitty.task.TaskList; +import hewwokitty.ui.Ui; + +/** + * Parser parses user input + * Allows user to interact with the chatbot + */ +public class Parser { + private String userInput = ""; + + /** + * Returns a Parser object that reads input from the user + */ + public Parser() { + + } + + /** + * Returns a boolean value indicating whether a command is valid and has been executed + * @param userInput String containing input from the user + * @param taskList TaskList from main that consists of Tasks that have been added by the user + * @return false if command user input is "bye", else true + */ + public boolean processUserCommands(String userInput, TaskList taskList) { + assert userInput != null : "User input should not be null"; + assert taskList != null : "TaskList should not be null"; + this.userInput = userInput; + String userString = this.userInput.toLowerCase(); + switch (userString.split(" ", 2)[0]) { + case "bye": + return false; + case "list": + System.out.print(taskList); + break; + case "mark": + try { + int markTaskNum = Integer.parseInt(userString.split(" ")[1]); + taskList.markDone(markTaskNum); + Storage.writeToFile(taskList); + } catch (IllegalArgumentException e) { + Ui.printInvalidTaskNumber(); + } + break; + case "unmark": + try { + int unmarkTaskNum = Integer.parseInt(userString.split(" ")[1]); + taskList.unmarkDone(unmarkTaskNum); + Storage.writeToFile(taskList); + } catch (IllegalArgumentException e) { + Ui.printInvalidTaskNumber(); + } + break; + case "todo": + case "deadline": + case "event": + try { + taskList.addTask(userString); + Storage.writeToFile(taskList); + } catch (IllegalArgumentException e) { + Ui.printInvalidDate(); + } + break; + case "delete": + int deleteTaskNum = Integer.parseInt(userString.split(" ")[1]); + taskList.removeTask(deleteTaskNum); + Storage.writeToFile(taskList); + break; + case "find": + taskList.findTasks(userString); + break; + default: + Ui.printInvalidCommand(); + break; + } + return true; + } +} diff --git a/src/main/java/hewwokitty/storage/Storage.java b/src/main/java/hewwokitty/storage/Storage.java new file mode 100644 index 0000000000..f793e9c234 --- /dev/null +++ b/src/main/java/hewwokitty/storage/Storage.java @@ -0,0 +1,115 @@ +package hewwokitty.storage; + + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Scanner; + +import hewwokitty.task.Event; +import hewwokitty.task.Deadline; +import hewwokitty.task.TaskList; +import hewwokitty.task.Task; +import hewwokitty.task.Todo; + +/** + * Responsible for writing Tasks to and reading Tasks from file + * The created file is located at "data/hewwoTasks.txt" by default + */ +public class Storage { + /** + * Saves all the files in a given TaskList to file + * File is located at data/hewwoTasks.txt + * @param tasks TaskList generated by user + */ + public static void writeToFile(TaskList tasks) { + File file = new File("./data/hewwoTasks.txt"); + file.getParentFile().mkdirs(); + + try (FileWriter writer = new FileWriter(file, false)) { + writer.write(tasks.writeToFile()); + writer.close(); + } catch (IOException e) { + System.out.println("an ewwow occuwwed whiwe wwiting to the fiwe: " + e.getMessage()); + } + } + + /** + * Reads all the tasks saved in data/hewwoTasks.txt and converts them to a TaskList + * @return All tasks in data/hewwoTasks.txt as a TaskList + */ + public static TaskList readFromFile() { + File file = new File("./data/hewwoTasks.txt"); + TaskList taskList = new TaskList(); + if (!file.exists()) { + return taskList; + } + + try (Scanner scanner = new Scanner(file)) { + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + Task t = null; + String marked; + String command; + String temp; + boolean isMarked = false; + String message; + try { + command = line.split("\\|")[0]; + temp = line.split("\\|", 2)[1]; + } catch (Exception e) { + return taskList; + } + + switch (command) { + case "T": + marked = temp.split("\\|")[0]; + isMarked = checkMarked(marked); + message = temp.split("\\|", 2)[1]; + t = new Todo(message); + if (isMarked) { + t.markAsDoneFile(); + } + break; + case "D": + marked = temp.split("\\|")[0]; + isMarked = checkMarked(marked); + message = temp.split("\\|")[1]; + String byDate = temp.split("\\|")[2]; + t = new Deadline(message, byDate); + if (isMarked) { + t.markAsDoneFile(); + } + break; + case "E": + marked = temp.split("\\|")[0]; + isMarked = checkMarked(marked); + message = temp.split("\\|")[1]; + String fromDate = temp.split("\\|")[2]; + String toDate = temp.split("\\|")[3]; + t = new Event(message, fromDate, toDate); + if (isMarked) { + t.markAsDoneFile(); + } + break; + default: + break; + } + if (t != null) { + taskList.addTaskFromFile(t); + } + } + } catch (FileNotFoundException e) { + return taskList; + } + return taskList; + } + + private static boolean checkMarked(String s) { + if (s.equals("1")) { + return true; + } + return false; + } +} diff --git a/src/main/java/hewwokitty/task/Deadline.java b/src/main/java/hewwokitty/task/Deadline.java new file mode 100644 index 0000000000..acbc222cdd --- /dev/null +++ b/src/main/java/hewwokitty/task/Deadline.java @@ -0,0 +1,48 @@ +package hewwokitty.task; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +/** + * Represents a type of Task that needs to be completed before a certain date + */ +public class Deadline extends Task { + private LocalDate deadline; + + /** + * Returns a Deadline object + * @param description A string describing what the Deadline is for + * @param dateEntered A string in the format yyyy-MM-dd for when the task should be completed + */ + public Deadline(String description, String dateEntered) { + super(description); + try { + this.deadline = LocalDate.parse(dateEntered); + } catch (DateTimeParseException e) { + throw new IllegalArgumentException(""); + } + } + + /** + * Formats a string into the format meant to save to file + * @return A String that has been formatted with the type Deadline, isDone, and the deadline description and when it is due + */ + @Override + public String writeToFile() { + return "D|" + super.writeToFile() + "|" + this.deadline + "\n"; + } + + /** + * Formats a string into the format that is displayed to the user + * @return A String to display the Deadline information to the user + */ + @Override + public String toString() { + return "[D]" + super.toString() + "(by: " + this.printDeadline() + ")"; + } + + private String printDeadline() { + return this.deadline.format(DateTimeFormatter.ofPattern("MMM d yyyy")); + } +} diff --git a/src/main/java/hewwokitty/task/Event.java b/src/main/java/hewwokitty/task/Event.java new file mode 100644 index 0000000000..097eec78f3 --- /dev/null +++ b/src/main/java/hewwokitty/task/Event.java @@ -0,0 +1,39 @@ +package hewwokitty.task; + +/** + * Represents a type of Task that is an event carried out over a time period + */ +public class Event extends Task { + private String fromDate; + private String toDate; + + /** + * Returns an Event object + * @param message A string describing what the Event is about + * @param fromDate A string representing when the Event starts + * @param toDate A string representing when the Event ends + */ + public Event(String message, String fromDate, String toDate) { + super(message); + this.fromDate = fromDate; + this.toDate = toDate; + } + + /** + * Formats a string into the format meant to save to file + * @return A String that has been formatted with the type Event, isDone, fromDate and toDate + */ + @Override + public String writeToFile() { + return "E|" + super.writeToFile() + "|" + this.fromDate + "|" + this.toDate + "\n"; + } + + /** + * Formats a string into the format that is displayed to the user + * @return A String to display the Event information to the user + */ + @Override + public String toString() { + return "[E]" + super.toString() + "(from: " + this.fromDate + " to: " + this.toDate + ")"; + } +} diff --git a/src/main/java/hewwokitty/task/Task.java b/src/main/java/hewwokitty/task/Task.java new file mode 100644 index 0000000000..778f197368 --- /dev/null +++ b/src/main/java/hewwokitty/task/Task.java @@ -0,0 +1,86 @@ +package hewwokitty.task; + +/** + * Represents the task that user wants to keep track of, as an Object + */ +public abstract class Task { + private boolean isDone; + private String description; + + /** + * Returns a Task object containing the description + * @param description A String describing what the task is for + */ + public Task(String description) { + this.description = description; + this.isDone = false; + } + + /** + * Returns the description of the Task + * @return A String containing the task description + */ + public String getDescription() { + return this.description; + } + /** + * Marks a Task as completed when loading from file + * Does not print the Task completion message + */ + public void markAsDoneFile() { + this.isDone = true; + } + + /** + * Marks a Task as completed based on user input + * Prints a completion message + */ + public void markAsDone() { + this.isDone = true; + System.out.println("i am is so pwoud of youw fow compweting this task <3"); + System.out.println("[X]" + this.description); + } + + /** + * Unmarks a Task as completed + * Prints an incompletion message + */ + public void unmarkAsDone() { + this.isDone = false; + System.out.println("this task has been mawked as not done :("); + System.out.println("[ ]" + this.description); + } + + private String printIsDone() { + if (this.isDone) { + return "[X] "; + } + return "[ ] "; + } + + /** + * Formats a string into the format meant to save to file + * The string displays isDone as 0 or 1 if it has been completed + * @return A String that has been formatted with isDone and the Task description + */ + public String writeToFile() { + return this.getMarkAsInt() + "|" + this.description; + } + + private int getMarkAsInt() { + if (this.isDone) { + return 1; + } + return 0; + } + + /** + * Formats a string into the format that is displayed to the user + * The String displays isDone and the Task description + * @return A String to display the Task information to the user + */ + @Override + public String toString() { + return this.printIsDone() + this.description; + } +} diff --git a/src/main/java/hewwokitty/task/TaskList.java b/src/main/java/hewwokitty/task/TaskList.java new file mode 100644 index 0000000000..02965d5fe3 --- /dev/null +++ b/src/main/java/hewwokitty/task/TaskList.java @@ -0,0 +1,166 @@ +package hewwokitty.task; + +import java.util.ArrayList; + +import hewwokitty.ui.Ui; + +/** + * A list of Task objects + */ +public class TaskList { + private ArrayList tasks; + + /** + * Returns an empty TaskList + */ + public TaskList() { + this.tasks = new ArrayList(); + } + + /** + * Get the number of Tasks in a TaskList + * @return An int with the number of Tasks in the TaskList + */ + public int getSize() { + return this.tasks.size(); + } + + /** + * Marks Task as done at a given order in the TaskList + * @param i An int representing the order of the Task in TaskList + */ + public void markDone(int i) { + try { + this.tasks.get(i - 1).markAsDone(); + } catch (IndexOutOfBoundsException e) { + throw new IllegalArgumentException(""); + } + } + + /** + * Unmarks Task as done at a given order in the TaskList + * @param i An int representing the order of the Task in TaskList + */ + public void unmarkDone(int i) { + try { + this.tasks.get(i - 1).unmarkAsDone(); + } catch (IndexOutOfBoundsException e) { + throw new IllegalArgumentException(""); + } + } + + /** + * Adds a Task to the TaskList based on the user specifications + * Checks user input and creates a Todo, Deadline or Event object accordingly + * @param userString A String that consists of the user input + */ + public void addTask(String userString) { + assert userString != null; + Task t = null; + String message; + String command = userString.split(" ")[0]; + String temp; + + switch (command) { + case "todo": + temp = userString.split(" " , 2)[1]; + if (!temp.equals("")) { + t = new Todo(temp); + } else { + Ui.printInvalidDescription(); + } + break; + case "deadline": + temp = userString.split(" " , 2)[1]; + message = temp.split("/")[0]; + String date = temp.split("/")[1].split(" " , 2)[1]; + t = new Deadline(message, date); + break; + case "event": + temp = userString.split(" " , 2)[1]; + message = temp.split("/")[0]; + String fromDate = temp.split("/")[1].split(" " , 2)[1]; + String toDate = temp.split("/")[2].split(" " , 2)[1]; + t = new Event(message, fromDate, toDate); + break; + default: + t = null; + break; + } + if (t != null) { + this.tasks.add(t); + System.out.println("i've added youw new task: \n" + t); + System.out.println("you now hawve " + this.tasks.size() + " tasks, ganbatte"); + } + } + + /** + * Removes a Task from TaskList + * @param i An integer representing the order of the Task in the TaskList + */ + public void removeTask(int i) { + System.out.println("i've wemoved youw task: \n" + this.tasks.get(i - 1).toString()); + this.tasks.remove(i - 1); + System.out.println("you now hawve " + this.tasks.size() + " tasks, ganbatte"); + } + + /** + * Adds each Task in the data/hewwoTasks.txt file to a TaskList + * @param task A Task read from the data file + */ + public void addTaskFromFile(Task task) { + this.tasks.add(task); + } + + /** + * Formats all the Tasks in the TaskList to be written to an output file + * @return All the Tasks in TaskList as a String + */ + public String writeToFile() { + String s = ""; + for (Task t : tasks) { + s = s + t.writeToFile(); + } + return s; + } + + /** + * Formats all the Tasks in the TaskList to be displayed to the user + * @return All the Tasks in TaskList as a String + */ + @Override + public String toString() { + if (this.getSize() == 0) { + return "you hawve no tasks fow me to wist!"; + } + String s = ""; + for (int i = 0; i < this.tasks.size(); i++) { + int currTask = i + 1; + s += currTask + ". " + this.tasks.get(i).toString() + "\n"; + } + return "hewe awe aww youw tasks ono\n" + s; + } + + /** + * Finds a Task in TaskList that contains the keyword entered by the user + * @param userString A String representing user input + */ + public void findTasks(String userString) { + String title; + String s = ""; + String keyword = userString.split(" " , 2)[1]; + int count = 1; + for (Task t : this.tasks) { + if (t.getDescription().toLowerCase().contains(keyword)) { + s = s + count + "." + t.toString() + "\n"; + count++; + } + } + if (count == 1) { + title = "sowwy pookie, i couwdn't fiwnd any matches :3\n"; + } else { + title = "hewe awe the matching tasks in youw wist!\n"; + } + System.out.print(title + s); + } +} diff --git a/src/main/java/hewwokitty/task/Todo.java b/src/main/java/hewwokitty/task/Todo.java new file mode 100644 index 0000000000..72659e932d --- /dev/null +++ b/src/main/java/hewwokitty/task/Todo.java @@ -0,0 +1,33 @@ +package hewwokitty.task; + +/** + * Represents a type of Task with a description + */ +public class Todo extends Task { + /** + * Returns a Todo object + * @param message A string describing what the Todo is about + */ + public Todo(String message) { + super(message); + } + + /** + * Formats a string into the format meant to save to file + * @return A String that has been formatted with the type Todo, isDone and description + */ + @Override + public String writeToFile() { + return "T|" + super.writeToFile() + "\n"; + } + + /** + * Formats a string into the format that is displayed to the user + * @return A String to display the Todo information to the user + */ + @Override + public String toString() { + return "[T]" + super.toString(); + } + +} diff --git a/src/main/java/hewwokitty/ui/Ui.java b/src/main/java/hewwokitty/ui/Ui.java new file mode 100644 index 0000000000..c57da2307d --- /dev/null +++ b/src/main/java/hewwokitty/ui/Ui.java @@ -0,0 +1,66 @@ +package hewwokitty.ui; + +/** + * Consists of all the interface text displayed to the user + */ +public class Ui { + /** + * Displays the starting message upon launching the chatbot + */ + @SuppressWarnings("checkstyle:Regexp") + public static void printStart() { + String logo = "⠀⠀⠀⠀⢀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⣠⠾⠛⠶⣄⢀⣠⣤⠴⢦⡀⠀⠀⠀⠀\n" + + "⠀⠀⠀⢠⡿⠉⠉⠉⠛⠶⠶⠖⠒⠒⣾⠋⠀⢀⣀⣙⣯⡁⠀⠀⠀⣿⠀⠀⠀⠀\n" + + "⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⢸⡏⠀⠀⢯⣼⠋⠉⠙⢶⠞⠛⠻⣆⠀⠀⠀\n" + + "⠀⠀⠀⢸⣧⠆⠀⠀⠀⠀⠀⠀⠀⠀⠻⣦⣤⡤⢿⡀⠀⢀⣼⣷⠀⠀⣽⠀⠀⠀\n" + + "⠀⠀⠀⣼⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⢏⡉⠁⣠⡾⣇⠀⠀⠀\n" + + "⠀⠀⢰⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠋⠉⠀⢻⡀⠀⠀\n" + + "⣀⣠⣼⣧⣤⠀⠀⠀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡀⠀⠀⠐⠖⢻⡟⠓⠒\n" + + "⠀⠀⠈⣷⣀⡀⠀⠘⠿⠇⠀⠀⠀⢀⣀⣀⠀⠀⠀⠀⠿⠟⠀⠀⠀⠲⣾⠦⢤⠀\n" + + "⠀⠀⠋⠙⣧⣀⡀⠀⠀⠀⠀⠀⠀⠘⠦⠼⠃⠀⠀⠀⠀⠀⠀⠀⢤⣼⣏⠀⠀⠀\n" + + "⠀⠀⢀⠴⠚⠻⢧⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⠞⠉⠉⠓⠀⠀\n" + + "⠀⠀⠀⠀⠀⠀⠀⠈⠉⠛⠛⠶⠶⠶⣶⣤⣴⡶⠶⠶⠟⠛⠉⠀⠀⠀⠀⠀⠀⠀"; + + System.out.println(logo); + System.out.println("hewwo! i'm hewwo kitty!"); + System.out.println("i'm just a chatbot uwuwuuwuwuwuwuwuwuwuwuwuuwuwuw"); + } + + /** + * Displays the closing message when user ends the chatbot + */ + public static void printBye() { + System.out.println("goodbwye! uwu"); + } + + /** + * Displays a message to the user when their command is not recognised + */ + public static void printInvalidCommand() { + System.out.println("i hawve no ideaw what youwe twying to say :( twy again <3"); + } + + /** + * Displays a message to the user telling them that they have entered an invalid + * description for a Todo object + */ + public static void printInvalidDescription() { + System.out.println("descwiptwion of a todo cawn't be empty! twy again :3"); + } + + /** + * Displays a message to the user telling them that they have entered a date + * in an invalid format for a Deadline object + */ + public static void printInvalidDate() { + System.out.println("date and time entewed shouwd be in yyyy-MM-dd ACTUAL.TXT - -REM compare the output to the expected output -FC ACTUAL.TXT EXPECTED.TXT +@ECHO OFF + +REM create bin directory if it doesn't exist +if not exist ..\bin mkdir ..\bin + +REM delete output from previous run +if exist ACTUAL.TXT del ACTUAL.TXT + +REM compile the code into the bin folder +javac -cp ..\src\main\java -Xlint:none -d ..\bin ..\src\main\java\*.java +IF ERRORLEVEL 1 ( + echo ********** BUILD FAILURE ********** + exit /b 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 HewwoKitty < 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 index c9ec870033..cf8a36c1c2 --- a/text-ui-test/runtest.sh +++ b/text-ui-test/runtest.sh @@ -1,38 +1,38 @@ -#!/usr/bin/env bash - -# create bin directory if it doesn't exist -if [ ! -d "../bin" ] -then - mkdir ../bin -fi - -# delete output from previous run -if [ -e "./ACTUAL.TXT" ] -then - rm ACTUAL.TXT -fi - -# compile the code into the bin folder, terminates if error occurred -if ! javac -cp ../src/main/java -Xlint:none -d ../bin ../src/main/java/*.java -then - echo "********** BUILD FAILURE **********" - exit 1 -fi - -# 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 - -# convert to UNIX format -cp EXPECTED.TXT EXPECTED-UNIX.TXT -dos2unix ACTUAL.TXT EXPECTED-UNIX.TXT - -# compare the output to the expected output -diff ACTUAL.TXT EXPECTED-UNIX.TXT -if [ $? -eq 0 ] -then - echo "Test result: PASSED" - exit 0 -else - echo "Test result: FAILED" - exit 1 +#!/usr/bin/env bash + +# create bin directory if it doesn't exist +if [ ! -d "../bin" ] +then + mkdir ../bin +fi + +# delete output from previous run +if [ -e "./ACTUAL.TXT" ] +then + rm ACTUAL.TXT +fi + +# compile the code into the bin folder, terminates if error occurred +if ! javac -cp ../src/main/java -Xlint:none -d ../bin ../src/main/java/*.java +then + echo "********** BUILD FAILURE **********" + exit 1 +fi + +# 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 + +# convert to UNIX format +cp EXPECTED.TXT EXPECTED-UNIX.TXT +dos2unix ACTUAL.TXT EXPECTED-UNIX.TXT + +# compare the output to the expected output +diff ACTUAL.TXT EXPECTED-UNIX.TXT +if [ $? -eq 0 ] +then + echo "Test result: PASSED" + exit 0 +else + echo "Test result: FAILED" + exit 1 fi \ No newline at end of file