From 336ea01cf460781a096d52d07c36b98212c4c912 Mon Sep 17 00:00:00 2001 From: limhawjia Date: Wed, 23 Oct 2019 00:40:31 +0800 Subject: [PATCH] Add unit tests for CommandLogic and its components --- src/main/java/com/dukeacademy/MainApp.java | 34 ++++++++++++++----- .../dukeacademy/commons/util/StringUtil.java | 32 ++++++++++++----- .../logic/commands/CommandLogic.java | 10 ++++++ .../logic/commands/CommandLogicManager.java | 13 ++++++- .../logic/commands/CommandParser.java | 24 ++++++++++--- .../logic/commands/CommandSupplier.java | 2 -- .../InvalidCommandArgumentsException.java | 5 ++- .../commands/factory/CommandFactory.java | 3 +- .../program/ProgramSubmissionChannel.java | 2 +- .../logic/program/ProgramSubmissionLogic.java | 13 +++++++ .../ProgramSubmissionLogicManager.java | 17 ++++++++++ .../SubmissionChannelNotSetException.java | 8 +++++ .../StandardCompilerEnvironment.java | 2 +- src/main/java/com/dukeacademy/ui/Editor.java | 10 ++++++ .../java/com/dukeacademy/ui/MainWindow.java | 14 ++++---- .../java/com/dukeacademy/ui/UiManager.java | 6 ++-- .../commons/util/StringUtilTest.java | 7 +++- .../commands/CommandLogicManagerTest.java | 28 ++++++++++----- .../logic/commands/CommandParserTest.java | 27 ++++++++++----- .../logic/commands/MockCommand.java | 24 +++++++++++++ .../logic/commands/MockCommandFactory.java | 20 +++++++++++ .../ProgramSubmissionLogicManagerTest.java | 9 +++++ .../com/dukeacademy/testutil/TestUtil.java | 4 --- 23 files changed, 254 insertions(+), 60 deletions(-) create mode 100644 src/main/java/com/dukeacademy/logic/program/exceptions/SubmissionChannelNotSetException.java create mode 100644 src/test/java/com/dukeacademy/logic/commands/MockCommand.java create mode 100644 src/test/java/com/dukeacademy/logic/commands/MockCommandFactory.java diff --git a/src/main/java/com/dukeacademy/MainApp.java b/src/main/java/com/dukeacademy/MainApp.java index 6a246da5ad7..043bf8c72c7 100644 --- a/src/main/java/com/dukeacademy/MainApp.java +++ b/src/main/java/com/dukeacademy/MainApp.java @@ -12,9 +12,12 @@ import com.dukeacademy.commons.exceptions.DataConversionException; import com.dukeacademy.commons.util.ConfigUtil; import com.dukeacademy.commons.util.StringUtil; +import com.dukeacademy.logic.commands.CommandLogic; import com.dukeacademy.logic.commands.CommandLogicManager; +import com.dukeacademy.logic.program.ProgramSubmissionLogic; import com.dukeacademy.logic.program.ProgramSubmissionLogicManager; import com.dukeacademy.logic.program.exceptions.LogicCreationException; +import com.dukeacademy.logic.question.QuestionsLogic; import com.dukeacademy.logic.question.QuestionsLogicManager; import com.dukeacademy.model.prefs.ReadOnlyUserPrefs; import com.dukeacademy.model.prefs.UserPrefs; @@ -25,8 +28,8 @@ import com.dukeacademy.storage.question.JsonQuestionBankStorage; import com.dukeacademy.storage.question.QuestionBankStorage; import com.dukeacademy.ui.Ui; - import com.dukeacademy.ui.UiManager; + import javafx.application.Application; import javafx.stage.Stage; @@ -63,18 +66,27 @@ public void init() throws Exception { initLogging(config); + commandLogic = this.initCommandLogic(); questionsLogic = this.initQuestionsLogic(userPrefs); - programSubmissionLogic = this.initProgramSubmissionLogic(userPrefs); - commandLogic = this.initCommandLogic(userPrefs); - ui = this.initUi(userPrefs); + programSubmissionLogic = this.initProgramSubmissionLogic(); + ui = this.initUi(commandLogic, questionsLogic, programSubmissionLogic, userPrefs); } + /** + * Returns a new QuestionLogicManager based on the UserPrefs passed into the function. + * @param userPrefs a UserPrefs instance. + * @return a QuestionsLogicManager instance. + */ private QuestionsLogicManager initQuestionsLogic(ReadOnlyUserPrefs userPrefs) { QuestionBankStorage storage = new JsonQuestionBankStorage(userPrefs.getQuestionBankFilePath()); return new QuestionsLogicManager(storage); } - private ProgramSubmissionLogicManager initProgramSubmissionLogic(ReadOnlyUserPrefs userPrefs) { + /** + * Returns a new ProgramSubmissionLogicManager based on the UserPrefs passed into the function. + * @return a ProgramSubmissionLogicManager instance. + */ + private ProgramSubmissionLogicManager initProgramSubmissionLogic() { // TODO: eventually store program execution path in user prefs String outputPath = System.getProperty("user.home") + File.separator + "DukeAcademy"; File file = new File(outputPath); @@ -87,17 +99,23 @@ private ProgramSubmissionLogicManager initProgramSubmissionLogic(ReadOnlyUserPre } catch (LogicCreationException e) { logger.info("Fatal: failed to create program submission logic. Exiting app."); this.stop(); - throw new RuntimeException(); + return null; } } - private CommandLogicManager initCommandLogic(ReadOnlyUserPrefs userPrefs) { + /** + * Returns a new CommandLogicManager based on the UserPrefs passed into the function. Any commands to be registered + * in the CommandLogicManager is done in this method. + * @return a CommandLogicManger instance. + */ + private CommandLogicManager initCommandLogic() { CommandLogicManager commandLogicManager = new CommandLogicManager(); // TODO: create and register commands return commandLogicManager; } - private Ui initUi(ReadOnlyUserPrefs userPrefs) { + private Ui initUi(CommandLogic commandLogic, QuestionsLogic questionsLogic, + ProgramSubmissionLogic programSubmissionLogic, ReadOnlyUserPrefs userPrefs) { return new UiManager(commandLogic, questionsLogic, programSubmissionLogic, userPrefs.getGuiSettings()); } diff --git a/src/main/java/com/dukeacademy/commons/util/StringUtil.java b/src/main/java/com/dukeacademy/commons/util/StringUtil.java index 610ee30a1f8..c1862960814 100644 --- a/src/main/java/com/dukeacademy/commons/util/StringUtil.java +++ b/src/main/java/com/dukeacademy/commons/util/StringUtil.java @@ -1,15 +1,13 @@ package com.dukeacademy.commons.util; -import com.dukeacademy.commons.exceptions.IllegalValueException; - import static com.dukeacademy.commons.util.AppUtil.checkArgument; - import static java.util.Objects.requireNonNull; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Arrays; -import java.util.Optional; + +import com.dukeacademy.commons.exceptions.IllegalValueException; /** * Helper functions for handling strings. @@ -71,22 +69,38 @@ public static boolean isNonZeroUnsignedInteger(String s) { } } + /** + * Returns the first word of a string. + * @param s the string to be processed. + * @return the first word of the string. + * @throws IllegalValueException if the string does not contain a valid word. + */ public static String getFirstWord(String s) throws IllegalValueException { - if (!s.matches(VALID_WORD_REGEX)) { + String stripped = s.stripLeading(); + + if (!stripped.matches(VALID_WORD_REGEX)) { throw new IllegalValueException("String is not a valid word."); } - return s.split(" ", 2)[0].trim(); + return stripped.split("[\\s]+", 2)[0].trim(); } + /** + * Returns the a new string with the first word removed. + * @param s the string to be processed. + * @return the remainder of the string after the first word is removed. + * @throws IllegalValueException if the string does not contain a valid word. + */ public static String removeFirstWord(String s) throws IllegalValueException { - if (!s.matches(VALID_WORD_REGEX)) { + String stripped = s.stripLeading(); + + if (!stripped.matches(VALID_WORD_REGEX)) { throw new IllegalValueException("String is not a valid word."); } - if (s.split("\\s", 2).length == 1) { + if (stripped.split("[\\s]+", 2).length == 1) { return ""; } else { - return s.split("\\s", 2)[1].stripLeading(); + return stripped.split("[\\s]+", 2)[1].stripLeading(); } } } diff --git a/src/main/java/com/dukeacademy/logic/commands/CommandLogic.java b/src/main/java/com/dukeacademy/logic/commands/CommandLogic.java index dd28c59f2a2..448577a05e3 100644 --- a/src/main/java/com/dukeacademy/logic/commands/CommandLogic.java +++ b/src/main/java/com/dukeacademy/logic/commands/CommandLogic.java @@ -3,6 +3,16 @@ import com.dukeacademy.logic.commands.exceptions.CommandException; import com.dukeacademy.logic.parser.exceptions.ParseException; +/** + * Provides all the necessary methods needed to execute commands in the application. + */ public interface CommandLogic { + /** + * Executes a command based on the command text that is provided. + * @param commandText the command text that should contain the command keyword and the necessary arguments. + * @return a command result instance. + * @throws ParseException if the command text provided is invalid. + * @throws CommandException if the execution of the command fails. + */ CommandResult executeCommand(String commandText) throws ParseException, CommandException; } diff --git a/src/main/java/com/dukeacademy/logic/commands/CommandLogicManager.java b/src/main/java/com/dukeacademy/logic/commands/CommandLogicManager.java index bd7941bcb78..a7dc9766685 100644 --- a/src/main/java/com/dukeacademy/logic/commands/CommandLogicManager.java +++ b/src/main/java/com/dukeacademy/logic/commands/CommandLogicManager.java @@ -3,6 +3,11 @@ import com.dukeacademy.logic.commands.exceptions.CommandException; import com.dukeacademy.logic.parser.exceptions.ParseException; +/** + * Implementation of the CommandLogic interface. This implementation uses a helper class, CommandParser to help + * parse its commands. Any commands to be executed by this CommandLogic implementation has to be registered through + * the registerCommand method. + */ public class CommandLogicManager implements CommandLogic { private CommandParser commandParser; @@ -10,10 +15,16 @@ public CommandLogicManager() { this.commandParser = new CommandParser(); } + /** + * Registers a command that will now be executed by this CommandLogic instance. + * @param commandWord the keyword of the command. + * @param commandSupplier a supplier of command instances. + */ public void registerCommand(String commandWord, CommandSupplier commandSupplier) { - this.commandParser.registerCommandFactory(commandWord, commandSupplier); + this.commandParser.registerCommand(commandWord, commandSupplier); } + @Override public CommandResult executeCommand(String commandText) throws ParseException, CommandException { Command command = this.commandParser.parseCommandText(commandText); return command.execute(); diff --git a/src/main/java/com/dukeacademy/logic/commands/CommandParser.java b/src/main/java/com/dukeacademy/logic/commands/CommandParser.java index 857f907ec7d..260188a7349 100644 --- a/src/main/java/com/dukeacademy/logic/commands/CommandParser.java +++ b/src/main/java/com/dukeacademy/logic/commands/CommandParser.java @@ -1,14 +1,17 @@ package com.dukeacademy.logic.commands; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + import com.dukeacademy.commons.exceptions.IllegalValueException; import com.dukeacademy.commons.util.StringUtil; import com.dukeacademy.logic.commands.exceptions.InvalidCommandArgumentsException; import com.dukeacademy.logic.parser.exceptions.ParseException; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - +/** + * Helper class used by CommandLogicManager to keep track and instantiate registered Command classes. + */ public class CommandParser { private Map commandFactoryMap; @@ -16,10 +19,21 @@ public CommandParser() { this.commandFactoryMap = new HashMap<>(); } - public void registerCommandFactory(String commandWord, CommandSupplier commandSupplier) { + /** + * Registers a command into the command parser for future access. + * @param commandWord the keyword of the command. + * @param commandSupplier the supplier of the command. + */ + public void registerCommand(String commandWord, CommandSupplier commandSupplier) { this.commandFactoryMap.put(commandWord, commandSupplier); } + /** + * Instantiates and returns a Command class instance based on the command text provided. + * @param commandText the command text used to invoke the command. + * @return a command instance corresponding to the command text. + * @throws ParseException if the command keyword or arguments are invalid. + */ public Command parseCommandText(String commandText) throws ParseException { try { String commandWord = StringUtil.getFirstWord(commandText); diff --git a/src/main/java/com/dukeacademy/logic/commands/CommandSupplier.java b/src/main/java/com/dukeacademy/logic/commands/CommandSupplier.java index 9f978e5867a..81c239c9485 100644 --- a/src/main/java/com/dukeacademy/logic/commands/CommandSupplier.java +++ b/src/main/java/com/dukeacademy/logic/commands/CommandSupplier.java @@ -2,8 +2,6 @@ import com.dukeacademy.logic.commands.exceptions.InvalidCommandArgumentsException; -import java.util.Optional; - /** * Functional interface to represent a command supplier that accepts arguments for the command to act on. */ diff --git a/src/main/java/com/dukeacademy/logic/commands/exceptions/InvalidCommandArgumentsException.java b/src/main/java/com/dukeacademy/logic/commands/exceptions/InvalidCommandArgumentsException.java index d2f5c1b95f1..84bf2de0fc0 100644 --- a/src/main/java/com/dukeacademy/logic/commands/exceptions/InvalidCommandArgumentsException.java +++ b/src/main/java/com/dukeacademy/logic/commands/exceptions/InvalidCommandArgumentsException.java @@ -1,6 +1,9 @@ package com.dukeacademy.logic.commands.exceptions; -public class InvalidCommandArgumentsException extends Exception { +/** + * Exception thrown when the arguments provided for a command is invalid. + */ +public class InvalidCommandArgumentsException extends Exception { public InvalidCommandArgumentsException(String message) { super(message); } diff --git a/src/main/java/com/dukeacademy/logic/commands/factory/CommandFactory.java b/src/main/java/com/dukeacademy/logic/commands/factory/CommandFactory.java index 25f33e77512..d54ca058338 100644 --- a/src/main/java/com/dukeacademy/logic/commands/factory/CommandFactory.java +++ b/src/main/java/com/dukeacademy/logic/commands/factory/CommandFactory.java @@ -1,6 +1,7 @@ package com.dukeacademy.logic.commands.factory; import com.dukeacademy.logic.commands.Command; +import com.dukeacademy.logic.commands.exceptions.InvalidCommandArgumentsException; /** * Encapsulates the creation of commands and its dependencies and exposes an interface that can be injected into @@ -18,5 +19,5 @@ public interface CommandFactory { * @param commandArguments the command text from the user's input. * @return the corresponding command class instance. */ - Command getCommand(String commandArguments); + Command getCommand(String commandArguments) throws InvalidCommandArgumentsException; } diff --git a/src/main/java/com/dukeacademy/logic/program/ProgramSubmissionChannel.java b/src/main/java/com/dukeacademy/logic/program/ProgramSubmissionChannel.java index 4adb72cce19..a01d9c7e5d5 100644 --- a/src/main/java/com/dukeacademy/logic/program/ProgramSubmissionChannel.java +++ b/src/main/java/com/dukeacademy/logic/program/ProgramSubmissionChannel.java @@ -6,5 +6,5 @@ * Functional interface used by ProgramSubmissionLogicManagers to allow external components to submit user programs. */ public interface ProgramSubmissionChannel { - public void submitProgram(UserProgram program); + public UserProgram getProgram(); } diff --git a/src/main/java/com/dukeacademy/logic/program/ProgramSubmissionLogic.java b/src/main/java/com/dukeacademy/logic/program/ProgramSubmissionLogic.java index 2e91dc30a6e..09b68ffed1a 100644 --- a/src/main/java/com/dukeacademy/logic/program/ProgramSubmissionLogic.java +++ b/src/main/java/com/dukeacademy/logic/program/ProgramSubmissionLogic.java @@ -37,4 +37,17 @@ public interface ProgramSubmissionLogic { * @return True if the program was successfully tested. */ public boolean submitUserProgram(UserProgram userProgram); + + /** + * Sets a channel which allows the logic instance to retrieve user programs for submission. + * @param channel The channel to be set. + */ + public void setUserProgramSubmissionChannel(ProgramSubmissionChannel channel); + + /** + * Retrieves a user program from the submission channel and tests it against the current question being handled + * by the logic instance. + * @return True if the program was successfully tested. + */ + public boolean submitUserProgramFromSubmissionChannel(); } diff --git a/src/main/java/com/dukeacademy/logic/program/ProgramSubmissionLogicManager.java b/src/main/java/com/dukeacademy/logic/program/ProgramSubmissionLogicManager.java index bcba2e29c80..5e75e50f6f8 100644 --- a/src/main/java/com/dukeacademy/logic/program/ProgramSubmissionLogicManager.java +++ b/src/main/java/com/dukeacademy/logic/program/ProgramSubmissionLogicManager.java @@ -7,6 +7,7 @@ import com.dukeacademy.commons.core.LogsCenter; import com.dukeacademy.logic.program.exceptions.LogicCreationException; import com.dukeacademy.logic.program.exceptions.NoQuestionSetException; +import com.dukeacademy.logic.program.exceptions.SubmissionChannelNotSetException; import com.dukeacademy.logic.program.exceptions.SubmissionLogicManagerClosedException; import com.dukeacademy.model.program.TestResult; import com.dukeacademy.model.question.Question; @@ -37,6 +38,7 @@ public class ProgramSubmissionLogicManager implements ProgramSubmissionLogic { private CompilerEnvironment compilerEnvironment; private TestExecutor testExecutor; private boolean isClosed; + private ProgramSubmissionChannel submissionChannel; /** * Constructor. @@ -116,6 +118,21 @@ public boolean submitUserProgram(UserProgram userProgram) { return true; } + @Override + public void setUserProgramSubmissionChannel(ProgramSubmissionChannel channel) { + this.submissionChannel = channel; + } + + @Override + public boolean submitUserProgramFromSubmissionChannel() { + if (this.submissionChannel == null) { + throw new SubmissionChannelNotSetException(); + } + + UserProgram program = this.submissionChannel.getProgram(); + return this.submitUserProgram(program); + } + private void verifyNotClosed() { if (this.isClosed) { throw new SubmissionLogicManagerClosedException(); diff --git a/src/main/java/com/dukeacademy/logic/program/exceptions/SubmissionChannelNotSetException.java b/src/main/java/com/dukeacademy/logic/program/exceptions/SubmissionChannelNotSetException.java new file mode 100644 index 00000000000..401d148813f --- /dev/null +++ b/src/main/java/com/dukeacademy/logic/program/exceptions/SubmissionChannelNotSetException.java @@ -0,0 +1,8 @@ +package com.dukeacademy.logic.program.exceptions; + +/** + * Exception thrown when the ProgramSubmissionLogic instance does not have a submission channel set and attempts + * to submit a program through the submission channel. + */ +public class SubmissionChannelNotSetException extends RuntimeException { +} diff --git a/src/main/java/com/dukeacademy/testexecutor/environment/StandardCompilerEnvironment.java b/src/main/java/com/dukeacademy/testexecutor/environment/StandardCompilerEnvironment.java index 5a472ca0194..cabc60d16d7 100644 --- a/src/main/java/com/dukeacademy/testexecutor/environment/StandardCompilerEnvironment.java +++ b/src/main/java/com/dukeacademy/testexecutor/environment/StandardCompilerEnvironment.java @@ -136,7 +136,7 @@ public String getLocationPath() { private void createDirectory(Path path) throws CompilerEnvironmentException { try { String directoryPath = path.toUri().getPath(); - if (!new File(directoryPath).mkdir()) { + if (!new File(directoryPath).exists() && !new File(directoryPath).mkdir()) { throw new CompilerEnvironmentException(messageCreateEnvironmentFailed); } diff --git a/src/main/java/com/dukeacademy/ui/Editor.java b/src/main/java/com/dukeacademy/ui/Editor.java index d4efe8e51bb..b4e52c6e3e9 100644 --- a/src/main/java/com/dukeacademy/ui/Editor.java +++ b/src/main/java/com/dukeacademy/ui/Editor.java @@ -4,6 +4,8 @@ import java.io.FileWriter; import java.io.IOException; +import com.dukeacademy.model.question.UserProgram; + import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Button; @@ -73,4 +75,12 @@ public String onSubmitButtonClick(ActionEvent e) { System.out.println(textOutput.getText().strip()); return textOutput.getText().strip(); } + + /** + * Returns the current text in the editor. + * @return current text in editor. + */ + public UserProgram getUserProgram() { + return new UserProgram("Main", textOutput.getText().strip()); + } } diff --git a/src/main/java/com/dukeacademy/ui/MainWindow.java b/src/main/java/com/dukeacademy/ui/MainWindow.java index 4e2aebe9cf7..b7f87238006 100644 --- a/src/main/java/com/dukeacademy/ui/MainWindow.java +++ b/src/main/java/com/dukeacademy/ui/MainWindow.java @@ -6,7 +6,6 @@ import com.dukeacademy.commons.core.GuiSettings; import com.dukeacademy.commons.core.LogsCenter; import com.dukeacademy.logic.commands.CommandLogic; -import com.dukeacademy.logic.commands.CommandLogicManager; import com.dukeacademy.logic.commands.CommandResult; import com.dukeacademy.logic.commands.exceptions.CommandException; import com.dukeacademy.logic.parser.exceptions.ParseException; @@ -36,9 +35,9 @@ public class MainWindow extends UiPart { private final Logger logger = LogsCenter.getLogger(getClass()); private Stage primaryStage; - protected CommandLogic commandLogic; - protected QuestionsLogic questionsLogic; - protected ProgramSubmissionLogic programSubmissionLogic; + private CommandLogic commandLogic; + private QuestionsLogic questionsLogic; + private ProgramSubmissionLogic programSubmissionLogic; // Independent Ui parts residing in this Ui container private QuestionListPanel questionListPanel; @@ -68,7 +67,8 @@ public class MainWindow extends UiPart { @FXML private AnchorPane runCodeResultPlaceholder; - public MainWindow(Stage primaryStage, CommandLogic commandLogic, QuestionsLogic questionsLogic, ProgramSubmissionLogic programSubmissionLogic, GuiSettings guiSettings) { + public MainWindow(Stage primaryStage, CommandLogic commandLogic, QuestionsLogic questionsLogic, + ProgramSubmissionLogic programSubmissionLogic, GuiSettings guiSettings) { super(FXML, primaryStage); // Set dependencies @@ -82,7 +82,8 @@ public MainWindow(Stage primaryStage, CommandLogic commandLogic, QuestionsLogic setAccelerators(); - helpWindow = new HelpWindow(); } + helpWindow = new HelpWindow(); + } public Stage getPrimaryStage() { return primaryStage; @@ -141,6 +142,7 @@ void fillInnerParts() { editorPanel = new Editor(); editorPlaceholder.getChildren().add(editorPanel.getRoot()); + programSubmissionLogic.setUserProgramSubmissionChannel(editorPanel::getUserProgram); // Passing in sample test case and sample test case result into the constructor of RunCodeResult. // The sample problem in this context is an adder function. diff --git a/src/main/java/com/dukeacademy/ui/UiManager.java b/src/main/java/com/dukeacademy/ui/UiManager.java index 7c5c06ae4ee..faae085fecb 100644 --- a/src/main/java/com/dukeacademy/ui/UiManager.java +++ b/src/main/java/com/dukeacademy/ui/UiManager.java @@ -8,10 +8,9 @@ import com.dukeacademy.commons.util.StringUtil; import com.dukeacademy.logic.commands.CommandLogic; -import com.dukeacademy.logic.commands.CommandLogicManager; import com.dukeacademy.logic.program.ProgramSubmissionLogic; import com.dukeacademy.logic.question.QuestionsLogic; -import com.dukeacademy.model.prefs.UserPrefs; + import javafx.application.Platform; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; @@ -52,7 +51,8 @@ public void start(Stage primaryStage) { primaryStage.getIcons().add(getImage(ICON_APPLICATION)); try { - mainWindow = new MainWindow(primaryStage, commandLogic, questionsLogic, programSubmissionLogic, guiSettings); + mainWindow = new MainWindow(primaryStage, commandLogic, questionsLogic, + programSubmissionLogic, guiSettings); mainWindow.show(); //This should be called before creating other UI parts mainWindow.fillInnerParts(); diff --git a/src/test/java/com/dukeacademy/commons/util/StringUtilTest.java b/src/test/java/com/dukeacademy/commons/util/StringUtilTest.java index 9afea8446a5..4d8ca3e30f8 100644 --- a/src/test/java/com/dukeacademy/commons/util/StringUtilTest.java +++ b/src/test/java/com/dukeacademy/commons/util/StringUtilTest.java @@ -7,9 +7,10 @@ import java.io.FileNotFoundException; -import com.dukeacademy.commons.exceptions.IllegalValueException; import org.junit.jupiter.api.Test; +import com.dukeacademy.commons.exceptions.IllegalValueException; + public class StringUtilTest { //---------------- Tests for isNonZeroUnsignedInteger -------------------------------------- @@ -152,6 +153,10 @@ void getFirstWord() throws IllegalValueException { String actual1 = StringUtil.getFirstWord("Hello World!"); assertEquals(expected1, actual1); + String expected2 = "Hello"; + String actual2 = StringUtil.getFirstWord(" Hello World!"); + assertEquals(expected1, actual1); + assertThrows(IllegalValueException.class, () -> StringUtil.getFirstWord("")); assertThrows(IllegalValueException.class, () -> StringUtil.getFirstWord(" ")); } diff --git a/src/test/java/com/dukeacademy/logic/commands/CommandLogicManagerTest.java b/src/test/java/com/dukeacademy/logic/commands/CommandLogicManagerTest.java index 3b00a758630..4697289bf9d 100644 --- a/src/test/java/com/dukeacademy/logic/commands/CommandLogicManagerTest.java +++ b/src/test/java/com/dukeacademy/logic/commands/CommandLogicManagerTest.java @@ -1,18 +1,30 @@ package com.dukeacademy.logic.commands; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import com.dukeacademy.logic.commands.exceptions.CommandException; +import com.dukeacademy.logic.parser.exceptions.ParseException; class CommandLogicManagerTest { + private CommandLogicManager commandLogicManager = new CommandLogicManager(); @Test - void registerCommand() { - // TODO - } + void registerAndExecuteCommand() throws ParseException, CommandException { + MockCommandFactory mockCommandFactory = new MockCommandFactory(); + commandLogicManager.registerCommand(mockCommandFactory.getCommandWord(), mockCommandFactory::getCommand); - @Test - void executeCommand() { - // TODO + CommandResult result = commandLogicManager.executeCommand(mockCommandFactory.getCommandWord()); + assertEquals(MockCommand.getExpectedCommandResult(), result); + + CommandResult result1 = commandLogicManager.executeCommand(" " + + mockCommandFactory.getCommandWord() + " "); + assertEquals(MockCommand.getExpectedCommandResult(), result1); + + assertThrows(ParseException.class, () -> commandLogicManager.executeCommand("a@123")); + assertThrows(ParseException.class, () -> commandLogicManager + .executeCommand(mockCommandFactory.getCommandWord() + " abc")); } -} \ No newline at end of file +} diff --git a/src/test/java/com/dukeacademy/logic/commands/CommandParserTest.java b/src/test/java/com/dukeacademy/logic/commands/CommandParserTest.java index d1810ba5952..d22e2ffcedb 100644 --- a/src/test/java/com/dukeacademy/logic/commands/CommandParserTest.java +++ b/src/test/java/com/dukeacademy/logic/commands/CommandParserTest.java @@ -1,18 +1,27 @@ package com.dukeacademy.logic.commands; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import com.dukeacademy.logic.parser.exceptions.ParseException; class CommandParserTest { - + private final CommandParser commandParser = new CommandParser(); @Test - void registerCommandFactory() { - // TODO - } + void registerAndParseCommand() throws ParseException { + MockCommandFactory mockCommandFactory = new MockCommandFactory(); + commandParser.registerCommand(mockCommandFactory.getCommandWord(), mockCommandFactory::getCommand); - @Test - void parseCommandText() { - // TODO + Command command = commandParser.parseCommandText(mockCommandFactory.getCommandWord()); + assertTrue(command instanceof MockCommand); + + Command command1 = commandParser.parseCommandText(mockCommandFactory.getCommandWord() + " "); + assertTrue(command1 instanceof MockCommand); + + assertThrows(ParseException.class, () -> commandParser.parseCommandText("abcde")); + assertThrows(ParseException.class, () -> commandParser.parseCommandText(mockCommandFactory.getCommandWord() + + " 12345")); } -} \ No newline at end of file +} diff --git a/src/test/java/com/dukeacademy/logic/commands/MockCommand.java b/src/test/java/com/dukeacademy/logic/commands/MockCommand.java new file mode 100644 index 00000000000..4ac934533e0 --- /dev/null +++ b/src/test/java/com/dukeacademy/logic/commands/MockCommand.java @@ -0,0 +1,24 @@ +package com.dukeacademy.logic.commands; + +import com.dukeacademy.logic.commands.exceptions.CommandException; +import com.dukeacademy.logic.commands.exceptions.InvalidCommandArgumentsException; + +/** + * Mock class for testing purposes. + */ +public class MockCommand implements Command { + public MockCommand(String arguments) throws InvalidCommandArgumentsException { + if (arguments != "") { + throw new InvalidCommandArgumentsException("Invalid arguments"); + } + } + + public static CommandResult getExpectedCommandResult() { + return new CommandResult("AbCdEfG1315r!", false, false); + } + + @Override + public CommandResult execute() throws CommandException { + return getExpectedCommandResult(); + } +} diff --git a/src/test/java/com/dukeacademy/logic/commands/MockCommandFactory.java b/src/test/java/com/dukeacademy/logic/commands/MockCommandFactory.java new file mode 100644 index 00000000000..deb4cffd443 --- /dev/null +++ b/src/test/java/com/dukeacademy/logic/commands/MockCommandFactory.java @@ -0,0 +1,20 @@ +package com.dukeacademy.logic.commands; + +import com.dukeacademy.logic.commands.exceptions.InvalidCommandArgumentsException; +import com.dukeacademy.logic.commands.factory.CommandFactory; + +/** + * Mock class for testing purposes. + */ +public class MockCommandFactory implements CommandFactory { + + @Override + public String getCommandWord() { + return "test"; + } + + @Override + public Command getCommand(String commandArguments) throws InvalidCommandArgumentsException { + return new MockCommand(commandArguments); + } +} diff --git a/src/test/java/com/dukeacademy/logic/program/ProgramSubmissionLogicManagerTest.java b/src/test/java/com/dukeacademy/logic/program/ProgramSubmissionLogicManagerTest.java index c2c21a2dbbe..541104456b7 100644 --- a/src/test/java/com/dukeacademy/logic/program/ProgramSubmissionLogicManagerTest.java +++ b/src/test/java/com/dukeacademy/logic/program/ProgramSubmissionLogicManagerTest.java @@ -242,4 +242,13 @@ private Question createMockQuestion(String title, List testCases) { return new Question(title, status, difficulty, topics, testCases, new UserProgram("Main", "")); } + @Test + void setUserProgramSubmissionChannel() { + // TODO + } + + @Test + void submitUserProgramFromSubmissionChannel() { + // TODO + } } diff --git a/src/test/java/com/dukeacademy/testutil/TestUtil.java b/src/test/java/com/dukeacademy/testutil/TestUtil.java index 90d4f0df65c..87b0aaa22eb 100644 --- a/src/test/java/com/dukeacademy/testutil/TestUtil.java +++ b/src/test/java/com/dukeacademy/testutil/TestUtil.java @@ -5,9 +5,6 @@ import java.nio.file.Path; import java.nio.file.Paths; -import com.dukeacademy.commons.core.index.Index; -import com.dukeacademy.model.question.Question; - /** * A utility class for test cases. */ @@ -30,5 +27,4 @@ public static Path getFilePathInSandboxFolder(String fileName) { } return SANDBOX_FOLDER.resolve(fileName); } - }