Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix exporting of last token in match #1955

Merged
merged 4 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,11 @@ private BaseCodeMatch convertToBaseCodeMatch(Submission submission, Match match,
List<Token> tokens = submission.getTokenList().subList(takeLeft ? match.startOfFirst() : match.startOfSecond(),
(takeLeft ? match.endOfFirst() : match.endOfSecond()) + 1);

Comparator<? super Token> lineComparator = Comparator.comparingInt(Token::getLine);
Token start = tokens.stream().min(lineComparator).orElseThrow();
Token end = tokens.stream().max(lineComparator).orElseThrow();
Comparator<? super Token> lineStartComparator = Comparator.comparingInt(Token::getLine).thenComparingInt(Token::getColumn);
Comparator<? super Token> lineEndComparator = Comparator.comparingInt(Token::getLine)
.thenComparingInt((Token t) -> t.getColumn() + t.getLength());
Token start = tokens.stream().min(lineStartComparator).orElseThrow();
Token end = tokens.stream().max(lineEndComparator).orElseThrow();

CodePosition startPosition = new CodePosition(start.getLine(), start.getColumn() - 1,
takeLeft ? match.startOfFirst() : match.startOfSecond());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,14 @@ private Match convertMatchToReportMatch(JPlagComparison comparison, de.jplag.Mat
List<Token> tokensFirst = comparison.firstSubmission().getTokenList().subList(match.startOfFirst(), match.endOfFirst() + 1);
List<Token> tokensSecond = comparison.secondSubmission().getTokenList().subList(match.startOfSecond(), match.endOfSecond() + 1);

Comparator<? super Token> lineComparator = Comparator.comparingInt(Token::getLine).thenComparingInt(Token::getColumn);

Token startOfFirst = tokensFirst.stream().min(lineComparator).orElseThrow();
Token endOfFirst = tokensFirst.stream().max(lineComparator).orElseThrow();
Token startOfSecond = tokensSecond.stream().min(lineComparator).orElseThrow();
Token endOfSecond = tokensSecond.stream().max(lineComparator).orElseThrow();
Comparator<? super Token> lineStartComparator = Comparator.comparingInt(Token::getLine).thenComparingInt(Token::getColumn);
Comparator<? super Token> lineEndComparator = Comparator.comparingInt(Token::getLine)
.thenComparingInt((Token t) -> t.getColumn() + t.getLength());

Token startOfFirst = tokensFirst.stream().min(lineStartComparator).orElseThrow();
Token endOfFirst = tokensFirst.stream().max(lineEndComparator).orElseThrow();
Token startOfSecond = tokensSecond.stream().min(lineStartComparator).orElseThrow();
Token endOfSecond = tokensSecond.stream().max(lineEndComparator).orElseThrow();

String firstFileName = FilePathUtil.getRelativeSubmissionPath(startOfFirst.getFile(), comparison.firstSubmission(), submissionToIdFunction)
.toString();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package de.jplag.reporting.jsonfactory;

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

import java.nio.file.Path;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

import de.jplag.JPlagComparison;
import de.jplag.JPlagResult;
import de.jplag.Match;
import de.jplag.Submission;
import de.jplag.Token;
import de.jplag.options.JPlagOptions;
import de.jplag.reporting.FilePathUtil;
import de.jplag.reporting.reportobject.model.BaseCodeMatch;
import de.jplag.reporting.reportobject.model.CodePosition;
import de.jplag.reporting.reportobject.model.ComparisonReport;

class ReportTokenPositionTestTest {

@Test
void testCorrectTokenPositionsInComparisonReport() {
JPlagResult result = mock(JPlagResult.class);
JPlagOptions mockOptions = createMockOptions();
when(result.getOptions()).thenReturn(mockOptions);
JPlagComparison comparison = mock(JPlagComparison.class);
String firstID = "first";
String secondID = "second";
Submission firstSubmission = createMockSubmission(firstID);
Submission secondSubmission = createMockSubmission(secondID);
when(comparison.firstSubmission()).thenReturn(firstSubmission);
when(comparison.secondSubmission()).thenReturn(secondSubmission);
Match mockMatch = createMockMatch(0, 2, 0, 1);
when(comparison.matches()).thenReturn(List.of(mockMatch));

when(result.getComparisons(1)).thenReturn(List.of(comparison));

TestableReportWriter resultWriter = new TestableReportWriter();
Map<String, Map<String, String>> comparisonReportOutput;

try (MockedStatic<FilePathUtil> mockedFilePathUtil = Mockito.mockStatic(FilePathUtil.class)) {
mockedFilePathUtil.when(() -> FilePathUtil.getRelativeSubmissionPath(any(), any(), any())).thenReturn(Path.of("file.java"));
comparisonReportOutput = new ComparisonReportWriter(Submission::getName, resultWriter).writeComparisonReports(result);
}
ComparisonReport comparisonReport = (ComparisonReport) resultWriter.getJsonEntry(Path.of(comparisonReportOutput.get(firstID).get(secondID)));

assertEquals(1, comparisonReport.matches().size());

CodePosition startInFirst = comparisonReport.matches().get(0).startInFirst();
CodePosition endInFirst = comparisonReport.matches().get(0).endInFirst();
CodePosition startInSecond = comparisonReport.matches().get(0).startInSecond();
CodePosition endInSecond = comparisonReport.matches().get(0).endInSecond();

assertEquals(1, startInFirst.lineNumber());
assertEquals(0, startInFirst.column());
assertEquals(0, startInFirst.tokenListIndex());

assertEquals(2, endInFirst.lineNumber());
assertEquals(10, endInFirst.column());
assertEquals(2, endInFirst.tokenListIndex());

assertEquals(1, startInSecond.lineNumber());
assertEquals(0, startInSecond.column());
assertEquals(0, startInSecond.tokenListIndex());

assertEquals(2, endInSecond.lineNumber());
assertEquals(10, endInSecond.column());
assertEquals(1, endInSecond.tokenListIndex());
}

@Test
void testCorrectTokenPositionsInBasecodeReport() {
JPlagResult result = mock(JPlagResult.class);
JPlagOptions mockOptions = createMockOptions();
when(result.getOptions()).thenReturn(mockOptions);
JPlagComparison comparison = mock(JPlagComparison.class);
String submissionID = "first";
String basecodeID = "basecode";
Submission submission = createMockSubmission(submissionID);
Submission baseCodeSubmission = createMockSubmission(basecodeID);
when(comparison.firstSubmission()).thenReturn(submission);
when(comparison.secondSubmission()).thenReturn(baseCodeSubmission);
Match mockMatch = createMockMatch(0, 2, 0, 1);
when(comparison.matches()).thenReturn(List.of(mockMatch));
when(submission.getBaseCodeComparison()).thenReturn(comparison);

when(result.getComparisons(1)).thenReturn(List.of(comparison));

TestableReportWriter resultWriter = new TestableReportWriter();
try (MockedStatic<FilePathUtil> mockedFilePathUtil = Mockito.mockStatic(FilePathUtil.class)) {
mockedFilePathUtil.when(() -> FilePathUtil.getRelativeSubmissionPath(any(), any(), any())).thenReturn(Path.of("file.java"));
new BaseCodeReportWriter(Submission::getName, resultWriter).writeBaseCodeReport(result);
}

List<BaseCodeMatch> baseCodeMatches = (List<BaseCodeMatch>) resultWriter.getJsonEntry(Path.of("basecode", submissionID + ".json"));

assertEquals(1, baseCodeMatches.size());

CodePosition start = baseCodeMatches.get(0).start();
CodePosition end = baseCodeMatches.get(0).end();

assertEquals(1, start.lineNumber());
assertEquals(0, start.column());
assertEquals(0, start.tokenListIndex());

assertEquals(2, end.lineNumber());
assertEquals(10, end.column());
assertEquals(2, end.tokenListIndex());
}

JPlagOptions createMockOptions() {
JPlagOptions options = mock(JPlagOptions.class);
when(options.maximumNumberOfComparisons()).thenReturn(1);
return options;
}

Submission createMockSubmission(String name) {
Submission submission = mock(Submission.class);
when(submission.getName()).thenReturn(name);
List<Token> tokens = List.of(createMockToken(1, 1, 10), createMockToken(2, 1, 10), createMockToken(2, 3, 2), createMockToken(2, 10, 2));
when(submission.getTokenList()).thenReturn(tokens);
return submission;
}

Match createMockMatch(int startOfFirst, int endOfFirst, int startOfSecond, int endOfSecond) {
Match match = mock(Match.class);
when(match.startOfFirst()).thenReturn(startOfFirst);
when(match.endOfFirst()).thenReturn(endOfFirst);
when(match.startOfSecond()).thenReturn(startOfSecond);
when(match.endOfSecond()).thenReturn(endOfSecond);
return match;
}

Token createMockToken(int line, int column, int length) {
Token token = mock(Token.class);
when(token.getLine()).thenReturn(line);
when(token.getColumn()).thenReturn(column);
when(token.getLength()).thenReturn(length);
return token;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package de.jplag.reporting.jsonfactory;

import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

import de.jplag.reporting.reportobject.writer.DummyResultWriter;

public class TestableReportWriter extends DummyResultWriter {

public final Map<Path, Object> jsonEntries;

public TestableReportWriter() {
jsonEntries = new HashMap<>();
}

@Override
public void addJsonEntry(Object jsonContent, Path path) {
jsonEntries.put(path, jsonContent);
}

public Object getJsonEntry(Path path) {
return jsonEntries.get(path);
}
}