Skip to content

Commit

Permalink
Merge pull request #1955 from jplag/fix-col-calc
Browse files Browse the repository at this point in the history
Fix exporting of last token in match
  • Loading branch information
tsaglam authored Aug 30, 2024
2 parents b853591 + 96967c6 commit 04905d0
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 9 deletions.
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);
}
}

0 comments on commit 04905d0

Please sign in to comment.