mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-01 19:15:52 +01:00
added diff endpoint which returns a parsed diff as json
This commit is contained in:
@@ -29,6 +29,7 @@ public class VndMediaType {
|
|||||||
public static final String BRANCH = PREFIX + "branch" + SUFFIX;
|
public static final String BRANCH = PREFIX + "branch" + SUFFIX;
|
||||||
public static final String BRANCH_REQUEST = PREFIX + "branchRequest" + SUFFIX;
|
public static final String BRANCH_REQUEST = PREFIX + "branchRequest" + SUFFIX;
|
||||||
public static final String DIFF = PLAIN_TEXT_PREFIX + "diff" + PLAIN_TEXT_SUFFIX;
|
public static final String DIFF = PLAIN_TEXT_PREFIX + "diff" + PLAIN_TEXT_SUFFIX;
|
||||||
|
public static final String DIFF_PARSED = PREFIX + "diffParsed" + SUFFIX;;
|
||||||
public static final String USER_COLLECTION = PREFIX + "userCollection" + SUFFIX;
|
public static final String USER_COLLECTION = PREFIX + "userCollection" + SUFFIX;
|
||||||
public static final String GROUP_COLLECTION = PREFIX + "groupCollection" + SUFFIX;
|
public static final String GROUP_COLLECTION = PREFIX + "groupCollection" + SUFFIX;
|
||||||
public static final String REPOSITORY_COLLECTION = PREFIX + "repositoryCollection" + SUFFIX;
|
public static final String REPOSITORY_COLLECTION = PREFIX + "repositoryCollection" + SUFFIX;
|
||||||
|
|||||||
@@ -50,10 +50,15 @@ class LoadingDiff extends React.Component<Props, State> {
|
|||||||
this.setState({ loading: true });
|
this.setState({ loading: true });
|
||||||
apiClient
|
apiClient
|
||||||
.get(url)
|
.get(url)
|
||||||
.then(response => response.text())
|
.then(response => {
|
||||||
.then(parser.parse)
|
const contentType = response.headers.get("Content-Type");
|
||||||
// $FlowFixMe
|
if (contentType && contentType.toLowerCase() === "application/vnd.scmm-diffparsed+json;v=2") {
|
||||||
.then((diff: any) => {
|
return response.json().then(data => data.files);
|
||||||
|
} else {
|
||||||
|
return response.text().then(parser.parse);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((diff: File[]) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
diff: diff
|
diff: diff
|
||||||
|
|||||||
@@ -46,10 +46,17 @@ type Props = {
|
|||||||
className?: string;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const determineLanguage = (file: File) => {
|
||||||
|
if (file.language) {
|
||||||
|
return file.language.toLowerCase();
|
||||||
|
}
|
||||||
|
return "text";
|
||||||
|
};
|
||||||
|
|
||||||
const TokenizedDiffView: FC<Props> = ({ file, viewType, className, children }) => {
|
const TokenizedDiffView: FC<Props> = ({ file, viewType, className, children }) => {
|
||||||
const { tokens } = useTokenizeWorker(tokenize, {
|
const { tokens } = useTokenizeWorker(tokenize, {
|
||||||
hunks: file.hunks,
|
hunks: file.hunks,
|
||||||
language: file.language || "text"
|
language: determineLanguage(file)
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -11,13 +11,14 @@ type Props = WithTranslation & {
|
|||||||
|
|
||||||
class ChangesetDiff extends React.Component<Props> {
|
class ChangesetDiff extends React.Component<Props> {
|
||||||
isDiffSupported(changeset: Changeset) {
|
isDiffSupported(changeset: Changeset) {
|
||||||
return !!changeset._links.diff;
|
return changeset._links.diff || !!changeset._links.diffParsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
createUrl(changeset: Changeset) {
|
createUrl(changeset: Changeset) {
|
||||||
if (changeset._links.diff) {
|
if (changeset._links.diffParsed) {
|
||||||
const link = changeset._links.diff as Link;
|
return (changeset._links.diffParsed as Link).href;
|
||||||
return link.href + "?format=GIT";
|
} else if (changeset._links.diff) {
|
||||||
|
return (changeset._links.diff as Link).href + "?format=GIT";
|
||||||
}
|
}
|
||||||
throw new Error("diff link is missing");
|
throw new Error("diff link is missing");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ public abstract class DefaultChangesetToChangesetDtoMapper extends HalAppenderMa
|
|||||||
|
|
||||||
Embedded.Builder embeddedBuilder = embeddedBuilder();
|
Embedded.Builder embeddedBuilder = embeddedBuilder();
|
||||||
|
|
||||||
|
Links.Builder linksBuilder = linkingTo()
|
||||||
|
.self(resourceLinks.changeset().self(repository.getNamespace(), repository.getName(), source.getId()))
|
||||||
|
.single(link("diff", resourceLinks.diff().self(namespace, name, source.getId())))
|
||||||
|
.single(link("sources", resourceLinks.source().self(namespace, name, source.getId())))
|
||||||
|
.single(link("modifications", resourceLinks.modifications().self(namespace, name, source.getId())));
|
||||||
|
|
||||||
try (RepositoryService repositoryService = serviceFactory.create(repository)) {
|
try (RepositoryService repositoryService = serviceFactory.create(repository)) {
|
||||||
if (repositoryService.isSupported(Command.TAGS)) {
|
if (repositoryService.isSupported(Command.TAGS)) {
|
||||||
embeddedBuilder.with("tags", tagCollectionToDtoMapper.getTagDtoList(namespace, name,
|
embeddedBuilder.with("tags", tagCollectionToDtoMapper.getTagDtoList(namespace, name,
|
||||||
@@ -62,16 +68,13 @@ public abstract class DefaultChangesetToChangesetDtoMapper extends HalAppenderMa
|
|||||||
embeddedBuilder.with("branches", branchCollectionToDtoMapper.getBranchDtoList(namespace, name,
|
embeddedBuilder.with("branches", branchCollectionToDtoMapper.getBranchDtoList(namespace, name,
|
||||||
getListOfObjects(source.getBranches(), branchName -> Branch.normalBranch(branchName, source.getId()))));
|
getListOfObjects(source.getBranches(), branchName -> Branch.normalBranch(branchName, source.getId()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (repositoryService.isSupported(Command.DIFF_RESULT)) {
|
||||||
|
linksBuilder.single(link("diffParsed", resourceLinks.diff().parsed(namespace, name, source.getId())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
embeddedBuilder.with("parents", getListOfObjects(source.getParents(), parent -> changesetToParentDtoMapper.map(new Changeset(parent, 0L, null), repository)));
|
embeddedBuilder.with("parents", getListOfObjects(source.getParents(), parent -> changesetToParentDtoMapper.map(new Changeset(parent, 0L, null), repository)));
|
||||||
|
|
||||||
Links.Builder linksBuilder = linkingTo()
|
|
||||||
.self(resourceLinks.changeset().self(repository.getNamespace(), repository.getName(), source.getId()))
|
|
||||||
.single(link("diff", resourceLinks.diff().self(namespace, name, source.getId())))
|
|
||||||
.single(link("sources", resourceLinks.source().self(namespace, name, source.getId())))
|
|
||||||
.single(link("modifications", resourceLinks.modifications().self(namespace, name, source.getId())));
|
|
||||||
|
|
||||||
|
|
||||||
applyEnrichers(new EdisonHalAppender(linksBuilder, embeddedBuilder), source, repository);
|
applyEnrichers(new EdisonHalAppender(linksBuilder, embeddedBuilder), source, repository);
|
||||||
|
|
||||||
return new ChangesetDto(linksBuilder.build(), embeddedBuilder.build());
|
return new ChangesetDto(linksBuilder.build(), embeddedBuilder.build());
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import de.otto.edison.hal.HalRepresentation;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DiffResultDto extends HalRepresentation {
|
||||||
|
|
||||||
|
private List<FileDto> files;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
|
||||||
|
public static class FileDto {
|
||||||
|
|
||||||
|
private String oldPath;
|
||||||
|
private String newPath;
|
||||||
|
private boolean oldEndingNewLine;
|
||||||
|
private boolean newEndingNewLine;
|
||||||
|
private String oldRevision;
|
||||||
|
private String newRevision;
|
||||||
|
private String newMode;
|
||||||
|
private String oldMode;
|
||||||
|
private String type;
|
||||||
|
private String language;
|
||||||
|
private List<HunkDto> hunks;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
|
||||||
|
public static class HunkDto {
|
||||||
|
|
||||||
|
private String content;
|
||||||
|
private int oldStart;
|
||||||
|
private int newStart;
|
||||||
|
private int oldLines;
|
||||||
|
private int newLines;
|
||||||
|
private List<ChangeDto> changes;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
|
||||||
|
public static class ChangeDto {
|
||||||
|
|
||||||
|
private String content;
|
||||||
|
private String type;
|
||||||
|
@JsonProperty("isNormal")
|
||||||
|
private boolean isNormal;
|
||||||
|
@JsonProperty("isInsert")
|
||||||
|
private boolean isInsert;
|
||||||
|
@JsonProperty("isDelete")
|
||||||
|
private boolean isDelete;
|
||||||
|
private int lineNumber;
|
||||||
|
private int oldLineNumber;
|
||||||
|
private int newLineNumber;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import com.github.sdorra.spotter.ContentTypes;
|
||||||
|
import com.github.sdorra.spotter.Language;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import sonia.scm.repository.api.DiffFile;
|
||||||
|
import sonia.scm.repository.api.DiffLine;
|
||||||
|
import sonia.scm.repository.api.DiffResult;
|
||||||
|
import sonia.scm.repository.api.Hunk;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO conflicts, copy and rename
|
||||||
|
*/
|
||||||
|
final class DiffResultToDiffResultDtoMapper {
|
||||||
|
|
||||||
|
static final DiffResultToDiffResultDtoMapper INSTANCE = new DiffResultToDiffResultDtoMapper();
|
||||||
|
|
||||||
|
private DiffResultToDiffResultDtoMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiffResultDto map(DiffResult result) {
|
||||||
|
List<DiffResultDto.FileDto> files = new ArrayList<>();
|
||||||
|
for (DiffFile file : result) {
|
||||||
|
files.add(mapFile(file));
|
||||||
|
}
|
||||||
|
DiffResultDto dto = new DiffResultDto();
|
||||||
|
dto.setFiles(files);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiffResultDto.FileDto mapFile(DiffFile file) {
|
||||||
|
DiffResultDto.FileDto dto = new DiffResultDto.FileDto();
|
||||||
|
// ???
|
||||||
|
dto.setOldEndingNewLine(true);
|
||||||
|
dto.setNewEndingNewLine(true);
|
||||||
|
|
||||||
|
String newPath = file.getNewPath();
|
||||||
|
String oldPath = file.getOldPath();
|
||||||
|
|
||||||
|
String path;
|
||||||
|
if (isFilePath(newPath) && isFileNull(oldPath)) {
|
||||||
|
path = newPath;
|
||||||
|
dto.setType("add");
|
||||||
|
} else if (isFileNull(newPath) && isFilePath(oldPath)) {
|
||||||
|
path = oldPath;
|
||||||
|
dto.setType("delete");
|
||||||
|
} else if (isFilePath(newPath) && isFilePath(oldPath)) {
|
||||||
|
path = newPath;
|
||||||
|
dto.setType("modify");
|
||||||
|
} else {
|
||||||
|
// TODO copy and rename?
|
||||||
|
throw new IllegalStateException("no file without path");
|
||||||
|
}
|
||||||
|
|
||||||
|
dto.setNewPath(newPath);
|
||||||
|
dto.setNewRevision(file.getNewRevision());
|
||||||
|
|
||||||
|
dto.setOldPath(oldPath);
|
||||||
|
dto.setOldRevision(file.getOldRevision());
|
||||||
|
|
||||||
|
|
||||||
|
Optional<Language> language = ContentTypes.detect(path).getLanguage();
|
||||||
|
language.ifPresent(value -> dto.setLanguage(value.getName()));
|
||||||
|
|
||||||
|
List<DiffResultDto.HunkDto> hunks = new ArrayList<>();
|
||||||
|
for (Hunk hunk : file) {
|
||||||
|
hunks.add(mapHunk(hunk));
|
||||||
|
}
|
||||||
|
dto.setHunks(hunks);
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFilePath(String path) {
|
||||||
|
return !isFileNull(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFileNull(String path) {
|
||||||
|
return Strings.isNullOrEmpty(path) || "/dev/null".equals(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiffResultDto.HunkDto mapHunk(Hunk hunk) {
|
||||||
|
DiffResultDto.HunkDto dto = new DiffResultDto.HunkDto();
|
||||||
|
dto.setContent(hunk.getRawHeader());
|
||||||
|
|
||||||
|
dto.setNewStart(hunk.getNewStart());
|
||||||
|
dto.setNewLines(hunk.getNewLineCount());
|
||||||
|
|
||||||
|
dto.setOldStart(hunk.getOldStart());
|
||||||
|
dto.setOldLines(hunk.getOldLineCount());
|
||||||
|
|
||||||
|
List<DiffResultDto.ChangeDto> changes = new ArrayList<>();
|
||||||
|
for (DiffLine line : hunk) {
|
||||||
|
changes.add(mapLine(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
dto.setChanges(changes);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiffResultDto.ChangeDto mapLine(DiffLine line) {
|
||||||
|
DiffResultDto.ChangeDto dto = new DiffResultDto.ChangeDto();
|
||||||
|
dto.setContent(line.getContent());
|
||||||
|
|
||||||
|
OptionalInt newLineNumber = line.getNewLineNumber();
|
||||||
|
OptionalInt oldLineNumber = line.getOldLineNumber();
|
||||||
|
if (newLineNumber.isPresent() && !oldLineNumber.isPresent()) {
|
||||||
|
dto.setType("insert");
|
||||||
|
dto.setInsert(true);
|
||||||
|
dto.setLineNumber(newLineNumber.getAsInt());
|
||||||
|
} else if (!newLineNumber.isPresent() && oldLineNumber.isPresent()) {
|
||||||
|
dto.setType("delete");
|
||||||
|
dto.setDelete(true);
|
||||||
|
dto.setLineNumber(oldLineNumber.getAsInt());
|
||||||
|
} else if (newLineNumber.isPresent() && oldLineNumber.isPresent()) {
|
||||||
|
dto.setType("normal");
|
||||||
|
dto.setNormal(true);
|
||||||
|
dto.setNewLineNumber(newLineNumber.getAsInt());
|
||||||
|
dto.setOldLineNumber(oldLineNumber.getAsInt());
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("line without line number");
|
||||||
|
}
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import sonia.scm.NotFoundException;
|
|||||||
import sonia.scm.repository.NamespaceAndName;
|
import sonia.scm.repository.NamespaceAndName;
|
||||||
import sonia.scm.repository.api.DiffCommandBuilder;
|
import sonia.scm.repository.api.DiffCommandBuilder;
|
||||||
import sonia.scm.repository.api.DiffFormat;
|
import sonia.scm.repository.api.DiffFormat;
|
||||||
|
import sonia.scm.repository.api.DiffResult;
|
||||||
import sonia.scm.repository.api.RepositoryService;
|
import sonia.scm.repository.api.RepositoryService;
|
||||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||||
import sonia.scm.util.HttpUtil;
|
import sonia.scm.util.HttpUtil;
|
||||||
@@ -70,4 +71,23 @@ public class DiffRootResource {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{revision}.json")
|
||||||
|
@Produces(VndMediaType.DIFF_PARSED)
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode(code = 200, condition = "success"),
|
||||||
|
@ResponseCode(code = 400, condition = "Bad Request"),
|
||||||
|
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
|
||||||
|
@ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the diff"),
|
||||||
|
@ResponseCode(code = 404, condition = "not found, no revision with the specified param for the repository available or repository not found"),
|
||||||
|
@ResponseCode(code = 500, condition = "internal server error")
|
||||||
|
})
|
||||||
|
public Response getParsed(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision) throws IOException {
|
||||||
|
HttpUtil.checkForCRLFInjection(revision);
|
||||||
|
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||||
|
DiffResult diffResult = repositoryService.getDiffResultCommand().setRevision(revision).getDiffResult();
|
||||||
|
return Response.ok(DiffResultToDiffResultDtoMapper.INSTANCE.map(diffResult)).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -362,6 +362,10 @@ class ResourceLinks {
|
|||||||
return diffLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("diff").parameters().method("get").parameters(id).href();
|
return diffLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("diff").parameters().method("get").parameters(id).href();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String parsed(String namespace, String name, String id) {
|
||||||
|
return diffLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("diff").parameters().method("getParsed").parameters(id).href();
|
||||||
|
}
|
||||||
|
|
||||||
String all(String namespace, String name) {
|
String all(String namespace, String name) {
|
||||||
return diffLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("diff").parameters().method("getAll").parameters().href();
|
return diffLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("diff").parameters().method("getAll").parameters().href();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import sonia.scm.repository.api.DiffFile;
|
||||||
|
import sonia.scm.repository.api.DiffLine;
|
||||||
|
import sonia.scm.repository.api.DiffResult;
|
||||||
|
import sonia.scm.repository.api.Hunk;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class DiffResultToDiffResultDtoMapperTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldMapDiffResult() {
|
||||||
|
DiffResult result = result(
|
||||||
|
addedFile("A.java", "abc"),
|
||||||
|
modifiedFile("B.tsx", "def", "abc",
|
||||||
|
hunk("@@ -3,4 1,2 @@", 1, 2, 3, 4,
|
||||||
|
insertedLine("a", 1),
|
||||||
|
modifiedLine("b", 2),
|
||||||
|
deletedLine("c", 3)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
deletedFile("C.go", "ghi")
|
||||||
|
);
|
||||||
|
|
||||||
|
DiffResultDto dto = DiffResultToDiffResultDtoMapper.INSTANCE.map(result);
|
||||||
|
|
||||||
|
List<DiffResultDto.FileDto> files = dto.getFiles();
|
||||||
|
assertAddedFile(files.get(0), "A.java", "abc", "Java");
|
||||||
|
assertModifiedFile(files.get(1), "B.tsx", "abc", "def", "TypeScript");
|
||||||
|
assertDeletedFile(files.get(2), "C.go", "ghi", "Go");
|
||||||
|
|
||||||
|
DiffResultDto.HunkDto hunk = files.get(1).getHunks().get(0);
|
||||||
|
assertHunk(hunk, "@@ -3,4 1,2 @@", 1, 2, 3, 4);
|
||||||
|
|
||||||
|
List<DiffResultDto.ChangeDto> changes = hunk.getChanges();
|
||||||
|
assertInsertedLine(changes.get(0), "a", 1);
|
||||||
|
assertModifiedLine(changes.get(1), "b", 2);
|
||||||
|
assertDeletedLine(changes.get(2), "c", 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertInsertedLine(DiffResultDto.ChangeDto change, String content, int lineNumber) {
|
||||||
|
assertThat(change.getContent()).isEqualTo(content);
|
||||||
|
assertThat(change.getLineNumber()).isEqualTo(lineNumber);
|
||||||
|
assertThat(change.getType()).isEqualTo("insert");
|
||||||
|
assertThat(change.isInsert()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertModifiedLine(DiffResultDto.ChangeDto change, String content, int lineNumber) {
|
||||||
|
assertThat(change.getContent()).isEqualTo(content);
|
||||||
|
assertThat(change.getNewLineNumber()).isEqualTo(lineNumber);
|
||||||
|
assertThat(change.getOldLineNumber()).isEqualTo(lineNumber);
|
||||||
|
assertThat(change.getType()).isEqualTo("normal");
|
||||||
|
assertThat(change.isNormal()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertDeletedLine(DiffResultDto.ChangeDto change, String content, int lineNumber) {
|
||||||
|
assertThat(change.getContent()).isEqualTo(content);
|
||||||
|
assertThat(change.getLineNumber()).isEqualTo(lineNumber);
|
||||||
|
assertThat(change.getType()).isEqualTo("delete");
|
||||||
|
assertThat(change.isDelete()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertHunk(DiffResultDto.HunkDto hunk, String content, int newStart, int newLineCount, int oldStart, int oldLineCount) {
|
||||||
|
assertThat(hunk.getContent()).isEqualTo(content);
|
||||||
|
assertThat(hunk.getNewStart()).isEqualTo(newStart);
|
||||||
|
assertThat(hunk.getNewLines()).isEqualTo(newLineCount);
|
||||||
|
assertThat(hunk.getOldStart()).isEqualTo(oldStart);
|
||||||
|
assertThat(hunk.getOldLines()).isEqualTo(oldLineCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertAddedFile(DiffResultDto.FileDto file, String path, String revision, String language) {
|
||||||
|
assertThat(file.getNewPath()).isEqualTo(path);
|
||||||
|
assertThat(file.getNewRevision()).isEqualTo(revision);
|
||||||
|
assertThat(file.getType()).isEqualTo("add");
|
||||||
|
assertThat(file.getLanguage()).isEqualTo(language);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertModifiedFile(DiffResultDto.FileDto file, String path, String oldRevision, String newRevision, String language) {
|
||||||
|
assertThat(file.getNewPath()).isEqualTo(path);
|
||||||
|
assertThat(file.getNewRevision()).isEqualTo(newRevision);
|
||||||
|
assertThat(file.getOldPath()).isEqualTo(path);
|
||||||
|
assertThat(file.getOldRevision()).isEqualTo(oldRevision);
|
||||||
|
assertThat(file.getType()).isEqualTo("modify");
|
||||||
|
assertThat(file.getLanguage()).isEqualTo(language);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertDeletedFile(DiffResultDto.FileDto file, String path, String revision, String language) {
|
||||||
|
assertThat(file.getOldPath()).isEqualTo(path);
|
||||||
|
assertThat(file.getOldRevision()).isEqualTo(revision);
|
||||||
|
assertThat(file.getType()).isEqualTo("delete");
|
||||||
|
assertThat(file.getLanguage()).isEqualTo(language);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiffResult result(DiffFile... files) {
|
||||||
|
DiffResult result = mock(DiffResult.class);
|
||||||
|
when(result.iterator()).thenReturn(Arrays.asList(files).iterator());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiffFile addedFile(String path, String revision, Hunk... hunks) {
|
||||||
|
DiffFile file = mock(DiffFile.class);
|
||||||
|
when(file.getNewPath()).thenReturn(path);
|
||||||
|
when(file.getNewRevision()).thenReturn(revision);
|
||||||
|
when(file.iterator()).thenReturn(Arrays.asList(hunks).iterator());
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiffFile deletedFile(String path, String revision, Hunk... hunks) {
|
||||||
|
DiffFile file = mock(DiffFile.class);
|
||||||
|
when(file.getOldPath()).thenReturn(path);
|
||||||
|
when(file.getOldRevision()).thenReturn(revision);
|
||||||
|
when(file.iterator()).thenReturn(Arrays.asList(hunks).iterator());
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiffFile modifiedFile(String path, String newRevision, String oldRevision, Hunk... hunks) {
|
||||||
|
DiffFile file = mock(DiffFile.class);
|
||||||
|
when(file.getNewPath()).thenReturn(path);
|
||||||
|
when(file.getNewRevision()).thenReturn(newRevision);
|
||||||
|
when(file.getOldPath()).thenReturn(path);
|
||||||
|
when(file.getOldRevision()).thenReturn(oldRevision);
|
||||||
|
when(file.iterator()).thenReturn(Arrays.asList(hunks).iterator());
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Hunk hunk(String rawHeader, int newStart, int newLineCount, int oldStart, int oldLineCount, DiffLine... lines) {
|
||||||
|
Hunk hunk = mock(Hunk.class);
|
||||||
|
when(hunk.getRawHeader()).thenReturn(rawHeader);
|
||||||
|
when(hunk.getNewStart()).thenReturn(newStart);
|
||||||
|
when(hunk.getNewLineCount()).thenReturn(newLineCount);
|
||||||
|
when(hunk.getOldStart()).thenReturn(oldStart);
|
||||||
|
when(hunk.getOldLineCount()).thenReturn(oldLineCount);
|
||||||
|
when(hunk.iterator()).thenReturn(Arrays.asList(lines).iterator());
|
||||||
|
return hunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiffLine insertedLine(String content, int lineNumber) {
|
||||||
|
DiffLine line = mock(DiffLine.class);
|
||||||
|
when(line.getContent()).thenReturn(content);
|
||||||
|
when(line.getNewLineNumber()).thenReturn(OptionalInt.of(lineNumber));
|
||||||
|
when(line.getOldLineNumber()).thenReturn(OptionalInt.empty());
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiffLine modifiedLine(String content, int lineNumber) {
|
||||||
|
DiffLine line = mock(DiffLine.class);
|
||||||
|
when(line.getContent()).thenReturn(content);
|
||||||
|
when(line.getNewLineNumber()).thenReturn(OptionalInt.of(lineNumber));
|
||||||
|
when(line.getOldLineNumber()).thenReturn(OptionalInt.of(lineNumber));
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DiffLine deletedLine(String content, int lineNumber) {
|
||||||
|
DiffLine line = mock(DiffLine.class);
|
||||||
|
when(line.getContent()).thenReturn(content);
|
||||||
|
when(line.getNewLineNumber()).thenReturn(OptionalInt.empty());
|
||||||
|
when(line.getOldLineNumber()).thenReturn(OptionalInt.of(lineNumber));
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user