This repository was archived by the owner on Nov 19, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 76
Remote API to connect additional code review tools #737
Merged
Merged
Changes from all commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
372e4d8
adds model classes
aelfric-m 9ca1af4
adds LineCoverageViewModel class
aelfric-m f7070e9
Add test environment for coverage remote api model calculation
2738d94
adds LineCoverageViewModel class
aelfric-m b8e59bc
Merge branch 'dev' of github.com:aelfric-m/code-coverage-api-plugin i…
aelfric-m b0940cf
fixes LineCoverageViewModel class
aelfric-m 102fb85
adds test for LineCoverageViewModel class
aelfric-m ad3192a
adds first working model of ChangedAndCoveredLinesApi
aelfric-m eb1dc94
adds first working model of CoolApi
aelfric-m 2c99275
backup
aelfric-m 8095485
LineCoverageViewModel can now be passed as an argument to an Api
aelfric-m eca4317
properly names LineCoverageTest and removes unused code
aelfric-m 3076954
refacors model classes to better reflect their usage
3ab8736
makes model class attributes final and removes associated setters
fdc71c9
separates data from LineCoverageViewModel into LineCoverageApi
bbba7fc
changes unit test assertions to AssertJ and removes redundant test ro…
c3f0d7c
adds documentation to classes associated with the line coverage API
928e0e1
fixed out of bounds exception
7a779d7
fixes annotations for ModifiedLinesBlock class
ef4a9c9
fixes jenkins CheckStyle
45e5664
more checks fixes
68e4cde
reformatting and import optimization
de9da44
refactors the LineCoverageViewModel to CoverageApiUtil
165d80e
renames function to better reflect its job
b758d6d
improves unit tests and fixes some type-os
c56cf62
adds FileWithModifiedLinesTest class, moves some methods into parent …
dc1dd4b
integrates the logic from CoverageApiUtil into the Api class. More re…
07ab227
Adds restapi package to design.puml. Some renaming
94fefc4
Adds GerritCoverageController class for Gerrit fronteend communication
1531f76
Adds GerritCoverageController class for Gerrit fronteend communication
4366b71
Merge remote-tracking branch 'origin/dev' into dev
6d09435
removes GerritCoverageController class
cc8cdbd
visibility changes in restapi package
0328e16
Data provided by ModifiedLinesCoverageApi is now sorted by starting l…
b21c729
Data provided by ModifiedLinesCoverageApi is now sorted by starting l…
b16555d
Merge remote-tracking branch 'origin/dev' into dev
e5e5470
Merge branch 'jenkinsci:master' into dev
fo-code 5d3f660
Add modified lines API integration test
fo-code 972649d
Coverage API test
fo-code 617cf8e
Coverage API test
fo-code 9b96984
Implemented coverage API test and added README
fo-code 54389a9
Better implementation for calculating line blocks for REST API
fo-code 0edbb21
§Improved calculation of modified line blocks with the same coverage …
fo-code 04dfec4
Fix checkstyle
fo-code File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/FileWithModifiedLines.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package io.jenkins.plugins.coverage.metrics.restapi; | ||
|
||
import java.util.Objects; | ||
import java.util.SortedSet; | ||
|
||
import org.kohsuke.stapler.export.Exported; | ||
import org.kohsuke.stapler.export.ExportedBean; | ||
|
||
/** | ||
* Model class that describes the {@link LineCoverageType coverage} for modified code lines of a file. The file is | ||
* described by its fully qualified name. | ||
*/ | ||
@ExportedBean | ||
class FileWithModifiedLines { | ||
private final String fullyQualifiedFileName; | ||
private final SortedSet<ModifiedLinesBlock> modifiedLinesBlocks; | ||
|
||
FileWithModifiedLines(final String fullyQualifiedFileName, | ||
final SortedSet<ModifiedLinesBlock> modifiedLinesBlocks) { | ||
this.fullyQualifiedFileName = fullyQualifiedFileName; | ||
this.modifiedLinesBlocks = modifiedLinesBlocks; | ||
} | ||
|
||
@Exported(inline = true) | ||
public String getFullyQualifiedFileName() { | ||
return fullyQualifiedFileName; | ||
} | ||
|
||
@Exported(inline = true) | ||
public SortedSet<ModifiedLinesBlock> getModifiedLinesBlocks() { | ||
return modifiedLinesBlocks; | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
FileWithModifiedLines file = (FileWithModifiedLines) o; | ||
return Objects.equals(this.getFullyQualifiedFileName(), file.getFullyQualifiedFileName()) | ||
&& Objects.equals(this.getModifiedLinesBlocks(), file.getModifiedLinesBlocks()); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(getFullyQualifiedFileName(), getModifiedLinesBlocks()); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/LineCoverageType.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package io.jenkins.plugins.coverage.metrics.restapi; | ||
|
||
/** | ||
* Defines the type of line coverage. | ||
*/ | ||
enum LineCoverageType { | ||
COVERED, | ||
MISSED, | ||
PARTIALLY_COVERED | ||
} |
63 changes: 63 additions & 0 deletions
63
plugin/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/ModifiedLinesBlock.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package io.jenkins.plugins.coverage.metrics.restapi; | ||
|
||
import java.util.Objects; | ||
|
||
import org.kohsuke.stapler.export.Exported; | ||
import org.kohsuke.stapler.export.ExportedBean; | ||
|
||
/** | ||
* Model class containing data pertaining to consecutive lines of modified code. Each object possesses a starting and | ||
* ending line number and the type of coverage of the block. Each object is associated with a | ||
* {@link FileWithModifiedLines} object. The class implements {@link Comparable} and is ordered by the start line. Empty | ||
* lines and comments are also included in blocks. | ||
*/ | ||
@ExportedBean | ||
class ModifiedLinesBlock implements Comparable<ModifiedLinesBlock> { | ||
private final int startLine; | ||
private final int endLine; | ||
private final LineCoverageType type; | ||
|
||
ModifiedLinesBlock(final int startLine, final int endLine, final LineCoverageType type) { | ||
this.startLine = startLine; | ||
this.endLine = endLine; | ||
this.type = type; | ||
} | ||
|
||
@Exported | ||
public int getStartLine() { | ||
return startLine; | ||
} | ||
|
||
@Exported | ||
public int getEndLine() { | ||
return endLine; | ||
} | ||
|
||
@Exported | ||
public LineCoverageType getType() { | ||
return type; | ||
} | ||
|
||
@Override | ||
public int compareTo(final ModifiedLinesBlock other) { | ||
return this.startLine - other.startLine; | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
ModifiedLinesBlock that = (ModifiedLinesBlock) o; | ||
return getStartLine() == that.getStartLine() && getEndLine() == that.getEndLine() | ||
&& getType() == that.getType(); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(getStartLine(), getEndLine(), getType()); | ||
} | ||
} |
147 changes: 147 additions & 0 deletions
147
...n/src/main/java/io/jenkins/plugins/coverage/metrics/restapi/ModifiedLinesCoverageApi.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
package io.jenkins.plugins.coverage.metrics.restapi; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.TreeSet; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
|
||
import edu.hm.hafner.coverage.FileNode; | ||
import edu.hm.hafner.coverage.Node; | ||
|
||
import org.kohsuke.stapler.export.Exported; | ||
import org.kohsuke.stapler.export.ExportedBean; | ||
|
||
/** | ||
* Remote API to list the details of modified line coverage results. | ||
*/ | ||
@ExportedBean | ||
class ModifiedLinesCoverageApi { | ||
private final List<FileWithModifiedLines> filesWithModifiedLines; | ||
|
||
ModifiedLinesCoverageApi(final Node node) { | ||
this.filesWithModifiedLines = createListOfFilesWithModifiedLines(node); | ||
} | ||
|
||
@Exported(inline = true, name = "files") | ||
public List<FileWithModifiedLines> getFilesWithModifiedLines() { | ||
return filesWithModifiedLines; | ||
} | ||
|
||
/** | ||
* Finds all files with modified lines of code in a passed {@link Node} object. | ||
* | ||
* @param node | ||
* containing the file tree. | ||
* | ||
* @return a list of {@link FileWithModifiedLines} objects. | ||
*/ | ||
private List<FileWithModifiedLines> createListOfFilesWithModifiedLines(final Node node) { | ||
var result = new ArrayList<FileWithModifiedLines>(); | ||
|
||
for (FileNode fileNode : node.filterByModifiedLines().getAllFileNodes()) { | ||
var modifiedLines = new ArrayList<>(fileNode.getModifiedLines()); | ||
var modifiedLinesWithoutCoverage = modifiedLines.stream() | ||
.filter(line -> !fileNode.getLinesWithCoverage().contains(line)) | ||
.collect(Collectors.toList()); | ||
|
||
var missedLines = filterByModifiedLines(modifiedLines, fileNode.getMissedLines()); | ||
var partiallyCoveredLines = | ||
filterByModifiedLines(modifiedLines, fileNode.getPartiallyCoveredLines().keySet()); | ||
var coveredLines = fileNode.getLinesWithCoverage().stream() | ||
.filter(line -> fileNode.getMissedOfLine(line) == 0) | ||
.filter(modifiedLines::contains) | ||
.collect(Collectors.toList()); | ||
|
||
var modifiedLinesBlocks = new TreeSet<ModifiedLinesBlock>(); | ||
|
||
modifiedLinesBlocks.addAll( | ||
calculateModifiedLineBlocks(coveredLines, modifiedLinesWithoutCoverage, LineCoverageType.COVERED)); | ||
modifiedLinesBlocks.addAll( | ||
calculateModifiedLineBlocks(missedLines, modifiedLinesWithoutCoverage, LineCoverageType.MISSED)); | ||
modifiedLinesBlocks.addAll(calculateModifiedLineBlocks(partiallyCoveredLines, modifiedLinesWithoutCoverage, | ||
LineCoverageType.PARTIALLY_COVERED)); | ||
|
||
var changedFile = new FileWithModifiedLines(fileNode.getRelativePath(), modifiedLinesBlocks); | ||
result.add(changedFile); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
/** | ||
* Filters the given lines to only contain the given modified lines. | ||
* | ||
* @param modifiedLines | ||
* the lines that have been modified | ||
* @param lines | ||
* the lines that should be filtered for modified lines only | ||
* | ||
* @return the filtered lines | ||
*/ | ||
private List<Integer> filterByModifiedLines(final Collection<Integer> modifiedLines, | ||
final Collection<Integer> lines) { | ||
return lines.stream().filter(modifiedLines::contains).collect(Collectors.toList()); | ||
} | ||
|
||
/** | ||
* This method parses over the modified lines of a file and combines consecutive line numbers with the same coverage | ||
* type into a {@link ModifiedLinesBlock} object. If there are empty lines without coverage information between | ||
* lines with the same type, they will be included in the block. The result is sorted by the starting line number. | ||
* | ||
* @param modifiedLines | ||
* list containing the integer numbers of modified lines. | ||
* @param modifiedLinesWithoutCoverage | ||
* lines that have been modified but have no coverage information | ||
* @param type | ||
* type of coverage pertaining to each line of code ({@link LineCoverageType#COVERED}, | ||
* {@link LineCoverageType#MISSED}, or {@link LineCoverageType#PARTIALLY_COVERED}) | ||
* | ||
* @return the list of {@link ModifiedLinesBlock} | ||
*/ | ||
private List<ModifiedLinesBlock> calculateModifiedLineBlocks(final List<Integer> modifiedLines, | ||
final List<Integer> modifiedLinesWithoutCoverage, final LineCoverageType type) { | ||
var modifiedLinesBlocks = new ArrayList<ModifiedLinesBlock>(); | ||
if (modifiedLines.isEmpty()) { | ||
return modifiedLinesBlocks; | ||
} | ||
|
||
int start = modifiedLines.get(0); | ||
int last = start; | ||
if (modifiedLines.size() > 1) { | ||
for (int line : modifiedLines.subList(1, modifiedLines.size())) { | ||
if (line > last + 1 | ||
&& hasAnyLinesWithCoverageBetween(last, line, modifiedLinesWithoutCoverage)) { | ||
var modifiedLinesBlock = new ModifiedLinesBlock(start, last, type); | ||
modifiedLinesBlocks.add(modifiedLinesBlock); | ||
start = line; | ||
} | ||
last = line; | ||
} | ||
} | ||
var modifiedLinesBlock = new ModifiedLinesBlock(start, last, type); | ||
modifiedLinesBlocks.add(modifiedLinesBlock); | ||
|
||
return modifiedLinesBlocks; | ||
} | ||
uhafner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Checks whether the range between the first and the second given line contains any lines with coverage | ||
* information. | ||
* | ||
* @param start | ||
* the first line number | ||
* @param end | ||
* the second line number (must be greater than the first) | ||
* @param modifiedLinesWithoutCoverage | ||
* the modified lines without coverage information | ||
* | ||
* @return {@code true} whether there are any lines within the given line range that contains coverage information, | ||
* else {@code false} | ||
*/ | ||
private boolean hasAnyLinesWithCoverageBetween(final int start, final int end, | ||
final List<Integer> modifiedLinesWithoutCoverage) { | ||
return IntStream.range(start + 1, end).anyMatch(line -> !modifiedLinesWithoutCoverage.contains(line)); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.