diff --git a/frontend/src/api/Language.ts b/frontend/src/api/Language.ts index ed6f22ca4..b5babbb47 100644 --- a/frontend/src/api/Language.ts +++ b/frontend/src/api/Language.ts @@ -2,7 +2,7 @@ enum Language { Python = 'PYTHON', // Ruby = 'RUBY', // Swift = 'SWIFT', - // CPP = 'CPP', + CPP = 'CPP', // PHP = 'PHP', // C = 'C', Java = 'JAVA', @@ -31,8 +31,8 @@ export const languageToEditorLanguage = (key: Language): string => { return 'python'; // case Language.Ruby: // return 'ruby'; - // case Language.CPP: - // return 'c++'; + case Language.CPP: + return 'c++'; // case Language.PHP: // return 'php'; // case Language.C: diff --git a/pom.xml b/pom.xml index 535215342..43c19c618 100644 --- a/pom.xml +++ b/pom.xml @@ -94,6 +94,7 @@ org.projectlombok lombok + 1.18.20 true diff --git a/src/main/java/com/codejoust/main/exception/ProblemError.java b/src/main/java/com/codejoust/main/exception/ProblemError.java index d67b3cc5c..4bb0c3406 100644 --- a/src/main/java/com/codejoust/main/exception/ProblemError.java +++ b/src/main/java/com/codejoust/main/exception/ProblemError.java @@ -16,7 +16,7 @@ public enum ProblemError implements ApiError { INCORRECT_INPUT_COUNT(HttpStatus.BAD_REQUEST, "Please specify the correct number of parameters for this problem."), INVALID_INPUT(HttpStatus.BAD_REQUEST, "Please ensure each line of test case input/output is valid and is of the correct type."), INVALID_NUMBER_REQUEST(HttpStatus.BAD_REQUEST, "Please request a valid number of problems (between 1-10)."), - INVALID_VARIABLE_NAME(HttpStatus.BAD_REQUEST, "Please ensure all variable names are valid for Java and Python."), + INVALID_VARIABLE_NAME(HttpStatus.BAD_REQUEST, "Please ensure all variable names are valid for Java, Python, and C++."), EMPTY_FIELD(HttpStatus.BAD_REQUEST, "Please enter a value for each required field."), INTERNAL_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "An internal error occurred when attempting to find a problem."), NOT_ENOUGH_FOUND(HttpStatus.NOT_FOUND, "Not enough problems could be found with the given criteria."), diff --git a/src/main/java/com/codejoust/main/service/generators/CppDefaultCodeGeneratorService.java b/src/main/java/com/codejoust/main/service/generators/CppDefaultCodeGeneratorService.java new file mode 100644 index 000000000..96948094d --- /dev/null +++ b/src/main/java/com/codejoust/main/service/generators/CppDefaultCodeGeneratorService.java @@ -0,0 +1,112 @@ +package com.codejoust.main.service.generators; + +import java.util.List; + +import com.codejoust.main.exception.ProblemError; +import com.codejoust.main.exception.api.ApiException; +import com.codejoust.main.model.problem.ProblemIOType; +import com.codejoust.main.model.problem.ProblemInput; +import com.codejoust.main.model.report.CodeLanguage; + +import org.springframework.stereotype.Service; + +@Service +public class CppDefaultCodeGeneratorService implements DefaultCodeGeneratorService { + + @Override + public String getDefaultCode(List problemInputs, ProblemIOType outputType) { + boolean needStringImport = false; + boolean needVectorImport = false; + + if (outputType == ProblemIOType.ARRAY_STRING) { + needStringImport = true; + needVectorImport = true; + } else if (outputType == ProblemIOType.STRING) { + needStringImport = true; + } else if (outputType.getClassType().isArray()) { + needVectorImport = true; + } + + // Initialize method line StringBuilder with the output type. + StringBuilder methodLineBuilder = new StringBuilder(); + methodLineBuilder.append(String.format("\t\t%s solve(", typeInstantiationToString(outputType))); + + // Add all of the method inputs and names. + String prefix = ""; + for (ProblemInput problemInput : problemInputs) { + if (problemInput.getType() == ProblemIOType.ARRAY_STRING) { + needStringImport = true; + needVectorImport = true; + } else if (problemInput.getType() == ProblemIOType.STRING) { + needStringImport = true; + } else if (problemInput.getType().getClassType().isArray()) { + needVectorImport = true; + } + + methodLineBuilder.append(prefix); + prefix = ", "; + methodLineBuilder.append(String.format("%s %s", + typeInstantiationToString(problemInput.getType()), + problemInput.getName() + )); + } + methodLineBuilder.append(") {"); + + StringBuilder importLineBuilder = new StringBuilder(); + if (needStringImport) { + importLineBuilder.append("#include \n"); + } else if (needVectorImport) { + importLineBuilder.append("#include \n"); + } + + return String.join("\n", + importLineBuilder.toString(), + "using namespace std;", + "", + "class Solution {", + "\tpublic:", + methodLineBuilder.toString(), + "\t\t\t", + "\t\t}", + "}", + "" + ); + } + + @Override + public String typeInstantiationToString(ProblemIOType ioType) { + if (ioType == null) { + throw new ApiException(ProblemError.BAD_IOTYPE); + } + + switch (ioType) { + case STRING: + return "string"; + case INTEGER: + return "int"; + case DOUBLE: + return "double"; + case CHARACTER: + return "char"; + case BOOLEAN: + return "bool"; + case ARRAY_STRING: + return "vector"; + case ARRAY_INTEGER: + return "vector"; + case ARRAY_DOUBLE: + return "vector"; + case ARRAY_CHARACTER: + return "vector"; + case ARRAY_BOOLEAN: + return "vector"; + default: + throw new ApiException(ProblemError.BAD_IOTYPE); + } + } + + @Override + public CodeLanguage getLanguage() { + return CodeLanguage.CPP; + } +} diff --git a/src/test/java/com/codejoust/main/api/ProblemTests.java b/src/test/java/com/codejoust/main/api/ProblemTests.java index f8c42a633..663051cc4 100644 --- a/src/test/java/com/codejoust/main/api/ProblemTests.java +++ b/src/test/java/com/codejoust/main/api/ProblemTests.java @@ -72,6 +72,20 @@ class ProblemTests { "\t\t" ).replaceAll("\t", " "); + public static final String cppDefaultCode = String.join("\n", + "#include ", + "", + "using namespace std;", + "", + "class Solution {", + "\tpublic:", + "\t\tvector solve(vector nums) {", + "\t\t\t", + "\t\t}", + "}", + "" + ).replaceAll("\t", " "); + @Test public void getProblemNonExistent() throws Exception { ApiError ERROR = ProblemError.NOT_FOUND; @@ -379,7 +393,8 @@ public void getDefaultCodeSuccess() throws Exception { assertEquals(javaDefaultCode, actual.get(CodeLanguage.JAVA)); assertEquals(pythonDefaultCode, actual.get(CodeLanguage.PYTHON)); - assertEquals(2, actual.size()); + assertEquals(cppDefaultCode, actual.get(CodeLanguage.CPP)); + assertEquals(3, actual.size()); } @Test diff --git a/src/test/java/com/codejoust/main/service/generators/DefaultCodeGeneratorServiceTests.java b/src/test/java/com/codejoust/main/service/generators/DefaultCodeGeneratorServiceTests.java index d5f10ae68..6f587bb70 100644 --- a/src/test/java/com/codejoust/main/service/generators/DefaultCodeGeneratorServiceTests.java +++ b/src/test/java/com/codejoust/main/service/generators/DefaultCodeGeneratorServiceTests.java @@ -25,6 +25,10 @@ public class DefaultCodeGeneratorServiceTests { @InjectMocks private PythonDefaultCodeGeneratorService pythonDefaultCodeGeneratorService; + @Spy + @InjectMocks + private CppDefaultCodeGeneratorService cppDefaultCodeGeneratorService; + private static final String javaDefaultCode = String.join("\n", "import java.util.*;", "", @@ -43,6 +47,20 @@ public class DefaultCodeGeneratorServiceTests { "\t\t" ); + private static final String cppDefaultCode = String.join("\n", + "#include ", + "", + "using namespace std;", + "", + "class Solution {", + "\tpublic:", + "\t\tvector solve(vector nums) {", + "\t\t\t", + "\t\t}", + "}", + "" + ); + /** * Helper method to test the "getDefaultCode" method across languages. * @@ -65,4 +83,9 @@ public void getDefaultCodeJava() { public void getDefaultCodePython() { getDefaultCodeSetupMethod(pythonDefaultCodeGeneratorService, pythonDefaultCode); } + + @Test + public void getDefaultCodeCpp() { + getDefaultCodeSetupMethod(cppDefaultCodeGeneratorService, cppDefaultCode); + } }