From d0c901fcf0926dee9cbffd85b0b52595f60e0fa1 Mon Sep 17 00:00:00 2001 From: Jason Zhang Date: Wed, 21 Jul 2021 15:34:16 -0700 Subject: [PATCH 1/3] implementing CPP on frontend --- frontend/package-lock.json | 5 + frontend/src/api/Language.ts | 6 +- pom.xml | 1 + .../main/exception/ProblemError.java | 2 +- .../CppDefaultCodeGeneratorService.java | 112 ++++++++++++++++++ .../com/codejoust/main/api/ProblemTests.java | 2 +- .../DefaultCodeGeneratorServiceTests.java | 19 +++ 7 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/codejoust/main/service/generators/CppDefaultCodeGeneratorService.java diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 735ab55e2..883fd8c44 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -4350,6 +4350,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz", "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==", + "hasInstallScript": true, "optional": true, "dependencies": { "node-gyp-build": "~3.7.0" @@ -9448,6 +9449,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -16898,6 +16900,7 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.2.tgz", "integrity": "sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw==", + "hasInstallScript": true, "optional": true, "dependencies": { "node-gyp-build": "~3.7.0" @@ -17102,6 +17105,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -17357,6 +17361,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "hasInstallScript": true, "optional": true, "os": [ "darwin" 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..29d9aec2d 100644 --- a/src/test/java/com/codejoust/main/api/ProblemTests.java +++ b/src/test/java/com/codejoust/main/api/ProblemTests.java @@ -379,7 +379,7 @@ public void getDefaultCodeSuccess() throws Exception { assertEquals(javaDefaultCode, actual.get(CodeLanguage.JAVA)); assertEquals(pythonDefaultCode, actual.get(CodeLanguage.PYTHON)); - assertEquals(2, actual.size()); + 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..bd6fef6da 100644 --- a/src/test/java/com/codejoust/main/service/generators/DefaultCodeGeneratorServiceTests.java +++ b/src/test/java/com/codejoust/main/service/generators/DefaultCodeGeneratorServiceTests.java @@ -43,6 +43,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 +79,9 @@ public void getDefaultCodeJava() { public void getDefaultCodePython() { getDefaultCodeSetupMethod(pythonDefaultCodeGeneratorService, pythonDefaultCode); } + + @Test + public void getDefaultCodeCpp() { + getDefaultCodeSetupMethod(cppDefaultCodeGeneratorService, cppDefaultCode); + } } From b499d5df1180e698364f0a36901ad1ddf8afc0fa Mon Sep 17 00:00:00 2001 From: Jason Zhang Date: Wed, 4 Aug 2021 16:10:53 -0700 Subject: [PATCH 2/3] adding test and fixing minor issues --- frontend/package-lock.json | 6 ------ .../java/com/codejoust/main/api/ProblemTests.java | 15 +++++++++++++++ .../DefaultCodeGeneratorServiceTests.java | 4 ++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 883fd8c44..4714b27d3 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -4350,7 +4350,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz", "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==", - "hasInstallScript": true, "optional": true, "dependencies": { "node-gyp-build": "~3.7.0" @@ -9449,7 +9448,6 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -16900,7 +16898,6 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.2.tgz", "integrity": "sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw==", - "hasInstallScript": true, "optional": true, "dependencies": { "node-gyp-build": "~3.7.0" @@ -17105,8 +17102,6 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "hasInstallScript": true, - "optional": true, "os": [ "darwin" ], @@ -17361,7 +17356,6 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "hasInstallScript": true, "optional": true, "os": [ "darwin" diff --git a/src/test/java/com/codejoust/main/api/ProblemTests.java b/src/test/java/com/codejoust/main/api/ProblemTests.java index 29d9aec2d..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,6 +393,7 @@ public void getDefaultCodeSuccess() throws Exception { assertEquals(javaDefaultCode, actual.get(CodeLanguage.JAVA)); assertEquals(pythonDefaultCode, actual.get(CodeLanguage.PYTHON)); + assertEquals(cppDefaultCode, actual.get(CodeLanguage.CPP)); assertEquals(3, actual.size()); } 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 bd6fef6da..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.*;", "", From 7a547403d6750fea604333246a8a342c4edcd0cd Mon Sep 17 00:00:00 2001 From: Jason Zhang Date: Wed, 4 Aug 2021 16:12:18 -0700 Subject: [PATCH 3/3] adding back deleted line in package-lock.json --- frontend/package-lock.json | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 4714b27d3..735ab55e2 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -17102,6 +17102,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "optional": true, "os": [ "darwin" ],