Skip to content

Commit

Permalink
Add some UT for the ux problem's services
Browse files Browse the repository at this point in the history
  • Loading branch information
zakariamaaraki committed Jan 7, 2024
1 parent 0f73ab1 commit 3922d2d
Show file tree
Hide file tree
Showing 5 changed files with 422 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import com.cp.compiler.contract.testcases.TestCaseResult;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
Expand All @@ -19,7 +19,7 @@
*
* @author Zakaria Maaraki
*/
@Getter
@Data
@NoArgsConstructor
@EqualsAndHashCode
@ApiModel(description = "The returned response")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package com.cp.compiler.contract;

import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.*;

@Getter
@Data
@NoArgsConstructor
@EqualsAndHashCode
@AllArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package com.cp.compiler.repositories;

import com.cp.compiler.contract.problems.Difficulty;
import com.cp.compiler.contract.problems.Problem;
import com.cp.compiler.exceptions.problems.InvalidProblemException;
import com.cp.compiler.exceptions.problems.ProblemNotFoundException;
import com.cp.compiler.repositories.problems.ProblemsRepositoryDefault;
import com.fasterxml.jackson.core.type.TypeReference;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.test.util.ReflectionTestUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

class ProblemsRepositoryTests {

@Mock
private TypeReference<ArrayList<Problem>> typeReference;

@InjectMocks
private ProblemsRepositoryDefault problemsRepository;

@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);
ReflectionTestUtils.setField(problemsRepository, "problems", new HashMap<>());
}

@Test
void getProblemById_ExistingProblem_ReturnsProblem() {
// Arrange
long problemId = 1L;
Problem expectedProblem = createSampleProblem(problemId);
callInit(2);

// Act
Problem actualProblem = problemsRepository.getProblemById(problemId);

// Assert
assertEquals(expectedProblem, actualProblem);
}

@Test
void getProblemById_NonExistingProblem_ThrowsProblemNotFoundException() {
// Arrange
long nonExistingProblemId = 99L;
callInit(1);

// Act and Assert
assertThrows(ProblemNotFoundException.class, () -> problemsRepository.getProblemById(nonExistingProblemId));
}

@Test
void getAllProblems_ReturnsAllProblems() {
// Arrange
List<Problem> expectedProblems = createSampleProblems(2);
callInit(2);

// Act
List<Problem> actualProblems = problemsRepository.getAllProblems();

// Assert
assertEquals(expectedProblems.size(), actualProblems.size());

for (int i = 0; i < actualProblems.size(); i++) {
assertEquals(actualProblems.get(i), expectedProblems.get(i));
}
}

@Test
void init_ValidProblems_LoadsProblems() {
// Act
callInit(1);

// Assert
HashMap<Long, Problem> loadedProblems = (HashMap<Long, Problem>) ReflectionTestUtils.getField(problemsRepository, "problems");
assertNotNull(loadedProblems);
assertFalse(loadedProblems.isEmpty());
}

private void callInit(int problemsCount) {
// Access the problems field using reflection and update it
HashMap<Long, Problem> problems = (HashMap<Long, Problem>) ReflectionTestUtils.getField(problemsRepository, "problems");
problems.clear();

for (int i = 0; i < problemsCount; i++) {
Problem createdProblem = createSampleProblem(i);
problems.put((long)i, createdProblem);
}
}



private Problem createSampleProblem(long problemId) {
return Problem.builder()
.id(problemId)
.title("Sample Problem")
.description("This is a sample problem.")
.timeLimit(1000)
.memoryLimit(256)
.testCases(new ArrayList<>())
.tags(List.of("tag1", "tag2"))
.difficulty(Difficulty.MEDIUM)
.build();
}

private List<Problem> createSampleProblems(int count) {
List<Problem> problems = new ArrayList<>();
for (long i = 0; i < count; i++) {
problems.add(createSampleProblem(i));
}
return problems;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
package com.cp.compiler.services.ux;

import com.cp.compiler.contract.Language;
import com.cp.compiler.contract.RemoteCodeCompilerExecutionResponse;
import com.cp.compiler.contract.RemoteCodeCompilerRequest;
import com.cp.compiler.contract.RemoteCodeCompilerResponse;
import com.cp.compiler.contract.problems.Difficulty;
import com.cp.compiler.contract.problems.Problem;
import com.cp.compiler.contract.problems.ProblemExecution;
import com.cp.compiler.contract.testcases.TestCase;
import com.cp.compiler.contract.testcases.TestCaseResult;
import com.cp.compiler.executions.Execution;
import com.cp.compiler.executions.ExecutionFactory;
import com.cp.compiler.executions.languages.JavaExecution;
import com.cp.compiler.models.Verdict;
import com.cp.compiler.models.testcases.TransformedTestCase;
import com.cp.compiler.repositories.problems.ProblemsRepository;
import com.cp.compiler.services.api.CompilerFacade;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

public class ExecutionServiceDefaultTests {

@Mock
private CompilerFacade compiler;

@Mock
private ProblemsRepository problemsRepository;

@InjectMocks
private ExecutionServiceDefault executionService;

@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);

ExecutionFactory.registerExecution(
Language.JAVA,
(MultipartFile sourceCode, List<TransformedTestCase> testCases, int timeLimit, int memoryLimit) -> new JavaExecution(
sourceCode,
testCases,
timeLimit,
memoryLimit));
}

@Test
void execute_ValidProblem_ReturnsCompilerResponse() throws IOException {
// Arrange
long problemId = 1L;
Problem problem = createSampleProblem(problemId);
ProblemExecution problemExecution = createSampleProblemExecution(problemId);
RemoteCodeCompilerRequest expectedRequest = createSampleCompilerRequest(problem, problemExecution);
Execution expectedExecution = createSampleExecution(expectedRequest);

when(problemsRepository.getProblemById(problemId)).thenReturn(problem);
when(compiler.compile(any(), eq(false), eq(null), eq(null))).thenReturn(createSampleCompilerResponse(expectedRequest));

// Act
ResponseEntity<RemoteCodeCompilerResponse> responseEntity = executionService.execute(problemExecution);

// Assert
assertNotNull(responseEntity);
assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
RemoteCodeCompilerResponse compilerResponse = responseEntity.getBody();
assertNotNull(compilerResponse);
assertEquals(expectedRequest.getLanguage(), compilerResponse.getExecution().getLanguage());
assertEquals(expectedRequest.getTimeLimit(), compilerResponse.getExecution().getTimeLimit());
assertEquals(expectedRequest.getMemoryLimit(), compilerResponse.getExecution().getMemoryLimit());
assertEquals(Verdict.ACCEPTED.getStatusResponse(), compilerResponse.getExecution().getVerdict());

Map<String, TestCaseResult> testCasesResult = compilerResponse.getExecution().getTestCasesResult();
assertNotNull(testCasesResult);
assertEquals(2, testCasesResult.size());

int index = 0;
for (TestCaseResult testCaseResult : testCasesResult.values()) {
if (index++ < 2) {
assertNotNull(testCaseResult.getExpectedOutput());
} else {
assertEquals("**Hidden**", testCaseResult.getExpectedOutput());
assertEquals("**Hidden**", testCaseResult.getOutputDiff());
}
}
}

private Problem createSampleProblem(long problemId) {
return Problem.builder()
.id(problemId)
.title("Sample Problem " + problemId)
.description("Description of Sample Problem " + problemId)
.difficulty(Difficulty.MEDIUM)
.tags(Arrays.asList("tag1", "tag2"))
.testCases(Arrays.asList(
new TestCase("input1", "output1"),
new TestCase("input2", "output2"),
new TestCase("input3", "output3")
))
.timeLimit(1000)
.memoryLimit(256)
.build();
}

private ProblemExecution createSampleProblemExecution(long problemId) {
return new ProblemExecution(
problemId,
"Sample source code",
Language.JAVA);
}

private RemoteCodeCompilerRequest createSampleCompilerRequest(Problem problem, ProblemExecution problemExecution) {
LinkedHashMap<String, TestCase> testCases = new LinkedHashMap<>();
int index = 0;

for (TestCase testCase : problem.getTestCases()) {
testCases.put(String.valueOf(index++), testCase);
}

return new RemoteCodeCompilerRequest(
problemExecution.getSourceCode(),
problemExecution.getLanguage(),
problem.getTimeLimit(),
problem.getMemoryLimit(),
testCases);
}

private Execution createSampleExecution(RemoteCodeCompilerRequest compilerRequest) throws IOException {
return ExecutionFactory.createExecution(
compilerRequest.getSourcecodeFile(),
compilerRequest.getConvertedTestCases(),
compilerRequest.getTimeLimit(),
compilerRequest.getMemoryLimit(),
compilerRequest.getLanguage());
}

private ResponseEntity<RemoteCodeCompilerResponse> createSampleCompilerResponse(RemoteCodeCompilerRequest compilerRequest) {
var execution = new RemoteCodeCompilerExecutionResponse();
execution.setLanguage(compilerRequest.getLanguage());
execution.setTimeLimit(compilerRequest.getTimeLimit());
execution.setMemoryLimit(compilerRequest.getMemoryLimit());
execution.setVerdict(Verdict.ACCEPTED.getStatusResponse());

// Create two sample TestCaseResult instances
TestCaseResult testCaseResult1 = new TestCaseResult(
Verdict.ACCEPTED,
"Sample Output 1",
null,
"Expected Output 1",
1000
);

TestCaseResult testCaseResult2 = new TestCaseResult(
Verdict.WRONG_ANSWER,
"Sample Output 2",
null,
"Expected Output 2",
1500
);

execution.setTestCasesResult(new LinkedHashMap<>());
execution.getTestCasesResult().put("0", testCaseResult1);
execution.getTestCasesResult().put("1", testCaseResult2);

RemoteCodeCompilerResponse compilerResponse = new RemoteCodeCompilerResponse();
compilerResponse.setExecution(execution);

return new ResponseEntity<>(compilerResponse, HttpStatus.OK);
}
}
Loading

0 comments on commit 3922d2d

Please sign in to comment.