Merge changes I48ef685e,Ibe09a864,I8a9ecc8a,I17a20a2b

* changes:
  Allow to specify the author of a new comment of the test API
  Allow to specify the tag of a new comment of the test API
  Explain and test rename/copy behavior of test API of changes
  TreeCreator: Explicitly reject overlapping modifications
This commit is contained in:
Alice Kober-Sotzek
2020-08-19 11:38:24 +00:00
committed by Gerrit Code Review
16 changed files with 368 additions and 28 deletions

View File

@@ -48,11 +48,28 @@ public class FileContentBuilder<T> {
return builder;
}
/** Deletes the file. */
public T delete() {
modificationToBuilderAdder.accept(new DeleteFileModification(filePath));
return builder;
}
/**
* Renames the file while keeping its content.
*
* <p>If you want to both rename the file and adjust its content, delete the old path via {@link
* #delete()} and provide the desired content for the new path via {@link #content(String)}. If
* you use that approach, make sure to use a new content which is similar enough to the old (at
* least 60% line similarity) as otherwise Gerrit/Git won't identify it as a rename.
*
* <p>To create copied files, you need to go even one step further. Also rename the file you copy
* at the same time (-> delete old path + add two paths with the old content)! If you also want to
* adjust the content of the copy, you need to also slightly modify the content of the renamed
* file. Adjust the content of the copy slightly more if you want to control which file ends up as
* copy and which as rename (but keep the 60% line similarity threshold in mind).
*
* @param newFilePath new path of the file
*/
public T renameTo(String newFilePath) {
modificationToBuilderAdder.accept(new RenameFileModification(filePath, newFilePath));
return builder;

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.acceptance.testsuite.change;
import static com.google.gerrit.server.CommentsUtil.setCommentCommitId;
import com.google.gerrit.acceptance.testsuite.change.TestCommentCreation.CommentSide;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.PatchSet;
@@ -30,6 +31,7 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.IdentifiedUser.GenericFactory;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.update.BatchUpdate;
@@ -103,10 +105,9 @@ public class PerPatchsetOperationsImpl implements PerPatchsetOperations {
RevWalk revWalk = new RevWalk(objectInserter.newReader())) {
Timestamp now = TimeUtil.nowTs();
// Use identity of change owner until the API allows to specify the commenter.
IdentifiedUser changeOwner = userFactory.create(changeNotes.getChange().getOwner());
IdentifiedUser author = getAuthor(commentCreation);
CommentAdditionOp commentAdditionOp = new CommentAdditionOp(commentCreation);
try (BatchUpdate batchUpdate = batchUpdateFactory.create(project, changeOwner, now)) {
try (BatchUpdate batchUpdate = batchUpdateFactory.create(project, author, now)) {
batchUpdate.setRepository(repository, revWalk, objectInserter);
batchUpdate.addOp(changeNotes.getChangeId(), commentAdditionOp);
batchUpdate.execute();
@@ -115,6 +116,11 @@ public class PerPatchsetOperationsImpl implements PerPatchsetOperations {
}
}
private IdentifiedUser getAuthor(TestCommentCreation commentCreation) {
Account.Id authorId = commentCreation.author().orElse(changeNotes.getChange().getOwner());
return userFactory.create(authorId);
}
private class CommentAdditionOp implements BatchUpdateOp {
private String createdCommentUuid;
private final TestCommentCreation commentCreation;
@@ -126,7 +132,10 @@ public class PerPatchsetOperationsImpl implements PerPatchsetOperations {
@Override
public boolean updateChange(ChangeContext context) throws Exception {
HumanComment comment = toNewComment(context, commentCreation);
context.getUpdate(patchsetId).putComment(HumanComment.Status.PUBLISHED, comment);
ChangeUpdate changeUpdate = context.getUpdate(patchsetId);
changeUpdate.putComment(HumanComment.Status.PUBLISHED, comment);
// Only the tag set on the ChangeUpdate matters. The tag field of HumanComment is ignored.
commentCreation.tag().ifPresent(changeUpdate::setTag);
createdCommentUuid = comment.key.uuid;
return true;
}

View File

@@ -18,6 +18,7 @@ import com.google.auto.value.AutoValue;
import com.google.gerrit.acceptance.testsuite.ThrowingFunction;
import com.google.gerrit.acceptance.testsuite.change.TestRange.Position;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Patch;
import java.util.Optional;
import java.util.function.Function;
@@ -41,6 +42,10 @@ public abstract class TestCommentCreation {
public abstract Optional<String> parentUuid();
public abstract Optional<String> tag();
public abstract Optional<Account.Id> author();
abstract ThrowingFunction<TestCommentCreation, String> commentCreator();
public static TestCommentCreation.Builder builder(
@@ -155,6 +160,12 @@ public abstract class TestCommentCreation {
*/
public abstract Builder parentUuid(String parentUuid);
/** Tag to attach to the comment. */
public abstract Builder tag(String value);
/** Author of the comment. Must be an existing user account. */
public abstract Builder author(Account.Id accountId);
abstract TestCommentCreation.Builder commentCreator(
ThrowingFunction<TestCommentCreation, String> commentCreator);

View File

@@ -0,0 +1,50 @@
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.extensions.common.testing;
import static com.google.common.truth.Truth.assertAbout;
import com.google.common.truth.FailureMetadata;
import com.google.common.truth.IntegerSubject;
import com.google.common.truth.Subject;
import com.google.gerrit.extensions.common.AccountInfo;
/** A Truth subject for {@link AccountInfo} instances. */
public class AccountInfoSubject extends Subject {
private final AccountInfo accountInfo;
public static AccountInfoSubject assertThat(AccountInfo accountInfo) {
return assertAbout(accounts()).that(accountInfo);
}
public static Factory<AccountInfoSubject, AccountInfo> accounts() {
return AccountInfoSubject::new;
}
private AccountInfoSubject(FailureMetadata metadata, AccountInfo accountInfo) {
super(metadata, accountInfo);
this.accountInfo = accountInfo;
}
public IntegerSubject id() {
return check("id").that(accountInfo()._accountId);
}
private AccountInfo accountInfo() {
isNotNull();
return accountInfo;
}
}

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.extensions.common.testing;
import static com.google.common.truth.Truth.assertAbout;
import static com.google.gerrit.extensions.common.testing.AccountInfoSubject.accounts;
import static com.google.gerrit.extensions.common.testing.RangeSubject.ranges;
import com.google.common.truth.BooleanSubject;
@@ -50,6 +51,10 @@ public class CommentInfoSubject extends Subject {
this.commentInfo = commentInfo;
}
public StringSubject uuid() {
return check("id").that(commentInfo().id);
}
public IntegerSubject patchSet() {
return check("patchSet").that(commentInfo().patchSet);
}
@@ -86,6 +91,14 @@ public class CommentInfoSubject extends Subject {
return check("inReplyTo").that(commentInfo().inReplyTo);
}
public AccountInfoSubject author() {
return check("author").about(accounts()).that(commentInfo().author);
}
public StringSubject tag() {
return check("tag").that(commentInfo().tag);
}
private CommentInfo commentInfo() {
isNotNull();
return commentInfo;

View File

@@ -19,6 +19,7 @@ import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger;
import com.google.common.io.ByteStreams;
import com.google.gerrit.extensions.restapi.RawInput;
@@ -55,8 +56,8 @@ public class ChangeFileContentModification implements TreeModification {
}
@Override
public String getFilePath() {
return filePath;
public ImmutableSet<String> getFilePaths() {
return ImmutableSet.of(filePath);
}
@VisibleForTesting

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.edit.tree;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.Collections;
import java.util.List;
import org.eclipse.jgit.dircache.DirCacheEditor;
@@ -38,7 +39,7 @@ public class DeleteFileModification implements TreeModification {
}
@Override
public String getFilePath() {
return filePath;
public ImmutableSet<String> getFilePaths() {
return ImmutableSet.of(filePath);
}
}

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.edit.tree;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.util.List;
import org.eclipse.jgit.dircache.DirCacheEditor;
@@ -57,7 +58,7 @@ public class RenameFileModification implements TreeModification {
}
@Override
public String getFilePath() {
return newFilePath;
public ImmutableSet<String> getFilePaths() {
return ImmutableSet.of(currentFilePath, newFilePath);
}
}

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.edit.tree;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
@@ -62,7 +63,7 @@ public class RestoreFileModification implements TreeModification {
}
@Override
public String getFilePath() {
return filePath;
public ImmutableSet<String> getFilePaths() {
return ImmutableSet.of(filePath);
}
}

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.server.edit.tree;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.util.Objects.requireNonNull;
import com.google.common.collect.ImmutableList;
@@ -56,7 +57,11 @@ public class TreeCreator {
/**
* Apply modifications to the tree which is taken as a basis. If this method is called multiple
* times, the modifications are applied subsequently in exactly the order they were provided.
* times, the modifications are applied subsequently in exactly the order they were provided
* (though JGit applies some internal optimizations which involve sorting, too).
*
* <p><strong>Beware:</strong> All provided {@link TreeModification}s (even from previous calls of
* this method) must touch different file paths!
*
* @param treeModifications modifications which should be applied to the base tree
*/
@@ -75,10 +80,32 @@ public class TreeCreator {
* @throws IOException if problems arise when accessing the repository
*/
public ObjectId createNewTreeAndGetId(Repository repository) throws IOException {
ensureTreeModificationsDoNotTouchSameFiles();
DirCache newTree = createNewTree(repository);
return writeAndGetId(repository, newTree);
}
private void ensureTreeModificationsDoNotTouchSameFiles() {
// The current implementation of TreeCreator doesn't properly support modifications which touch
// the same files even if they are provided in a logical order. According to JGit's
// documentation, DirCache applies some internal sorting to optimize the index modifications.
// The internal sorting doesn't seem to be the only issue, though. Even applying the
// modifications in batches within different, subsequent DirCaches just held in memory didn't
// seem to work. We might need to fully write each batch to disk before creating the next.
ImmutableList<String> filePaths =
treeModifications.stream()
.flatMap(treeModification -> treeModification.getFilePaths().stream())
.collect(toImmutableList());
long distinctFilePathNum = filePaths.stream().distinct().count();
if (filePaths.size() != distinctFilePathNum) {
throw new IllegalStateException(
String.format(
"TreeModifications must not refer to the same file paths. This would have"
+ " unexpected/wrong behavior! Found file paths: %s.",
filePaths));
}
}
private DirCache createNewTree(Repository repository) throws IOException {
DirCache newTree = readBaseTree(repository);
List<DirCacheEditor.PathEdit> pathEdits = getPathEdits(repository);

View File

@@ -14,8 +14,8 @@
package com.google.gerrit.server.edit.tree;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.util.List;
import org.eclipse.jgit.dircache.DirCacheEditor;
@@ -42,12 +42,10 @@ public interface TreeModification {
throws IOException;
/**
* Indicates a file path which is affected by this {@code TreeModification}. If the modification
* refers to several file paths (e.g. renaming a file), returning either of them is appropriate as
* long as the returned value is deterministic.
* Indicates all file paths affected by this {@code TreeModification}. If the modification refers
* to several file paths (e.g. renaming a file), all of them must be returned.
*
* @return an affected file path
* @return all affected file paths
*/
@VisibleForTesting
String getFilePath();
ImmutableSet<String> getFilePaths();
}

View File

@@ -18,10 +18,12 @@ import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
import static com.google.gerrit.extensions.common.testing.CommitInfoSubject.assertThat;
import static com.google.gerrit.extensions.common.testing.CommitInfoSubject.hasCommit;
import static com.google.gerrit.extensions.common.testing.DiffInfoSubject.assertThat;
import static com.google.gerrit.extensions.restapi.testing.BinaryResultSubject.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static com.google.gerrit.truth.MapSubject.assertThatMap;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
@@ -33,7 +35,9 @@ import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.client.ChangeKind;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ChangeType;
import com.google.gerrit.extensions.common.CommitInfo;
import com.google.gerrit.extensions.common.DiffInfo;
import com.google.gerrit.extensions.common.FileInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.restapi.BinaryResult;
@@ -439,6 +443,135 @@ public class ChangeOperationsImplTest extends AbstractDaemonTest {
assertThat(fileContent).asString().isEqualTo("Line one");
}
@Test
public void newPatchsetCanHaveRenamedFileWithModifiedContent() throws Exception {
// We need sufficient content so that the slightly modified content is considered similar enough
// (> 60% line similarity) for a rename.
Change.Id changeId =
changeOperations
.newChange()
.file("file1")
.content("Some content")
.file("file2")
.content("Line 1\nLine 2\nLine 3\n")
.create();
PatchSet.Id patchset1Id =
changeOperations.change(changeId).currentPatchset().get().patchsetId();
PatchSet.Id patchset2Id =
changeOperations
.change(changeId)
.newPatchset()
.file("file2")
.delete()
.file("renamed file")
.content("Line 1\nLine two\nLine 3\n")
.create();
ChangeInfo change = getChangeFromServer(changeId);
Map<String, FileInfo> files = change.revisions.get(change.currentRevision).files;
assertThatMap(files).keys().containsExactly("file1", "renamed file");
BinaryResult fileContent = getFileContent(changeId, patchset2Id, "renamed file");
assertThat(fileContent).asString().isEqualTo("Line 1\nLine two\nLine 3\n");
DiffInfo diff =
gApi.changes()
.id(changeId.get())
.revision(patchset2Id.get())
.file("renamed file")
.diffRequest()
.withBase(patchset1Id.getId())
.get();
assertThat(diff).changeType().isEqualTo(ChangeType.RENAMED);
}
@Test
public void newPatchsetCanHaveCopiedFile() throws Exception {
Change.Id changeId =
changeOperations
.newChange()
.file("file1")
.content("Some content")
.file("file2")
.content("Line 1")
.create();
PatchSet.Id patchset1Id =
changeOperations.change(changeId).currentPatchset().get().patchsetId();
// Copies currently can only happen if a rename happens at the same time.
PatchSet.Id patchset2Id =
changeOperations
.change(changeId)
.newPatchset()
.file("file2")
.renameTo("renamed/copied file 1")
.file("renamed/copied file 2")
.content("Line 1")
.create();
// We can't control which of the files Gerrit/Git considers as rename and which as copy.
// -> Check both for the copy.
DiffInfo diff1 =
gApi.changes()
.id(changeId.get())
.revision(patchset2Id.get())
.file("renamed/copied file 1")
.diffRequest()
.withBase(patchset1Id.getId())
.get();
DiffInfo diff2 =
gApi.changes()
.id(changeId.get())
.revision(patchset2Id.get())
.file("renamed/copied file 2")
.diffRequest()
.withBase(patchset1Id.getId())
.get();
assertThat(ImmutableSet.of(diff1.changeType, diff2.changeType)).contains(ChangeType.COPIED);
}
@Test
public void newPatchsetCanHaveCopiedFileWithModifiedContent() throws Exception {
Change.Id changeId =
changeOperations
.newChange()
.file("file1")
.content("Some content")
.file("file2")
.content("Line 1\nLine 2\nLine 3\nLine 4\n")
.create();
PatchSet.Id patchset1Id =
changeOperations.change(changeId).currentPatchset().get().patchsetId();
// A copy with modified content currently can only happen if the renamed file also has slightly
// modified content. Modify the copy slightly more as Gerrit/Git will then select it as the
// copied and not renamed file.
PatchSet.Id patchset2Id =
changeOperations
.change(changeId)
.newPatchset()
.file("file2")
.delete()
.file("renamed file")
.content("Line 1\nLine 1.1\nLine 2\nLine 3\nLine 4\n")
.file("copied file")
.content("Line 1\nLine 1.1\nLine 1.2\nLine 2\nLine 3\nLine 4\n")
.create();
DiffInfo diff =
gApi.changes()
.id(changeId.get())
.revision(patchset2Id.get())
.file("copied file")
.diffRequest()
.withBase(patchset1Id.getId())
.get();
assertThat(diff).changeType().isEqualTo(ChangeType.COPIED);
BinaryResult fileContent = getFileContent(changeId, patchset2Id, "copied file");
assertThat(fileContent)
.asString()
.isEqualTo("Line 1\nLine 1.1\nLine 1.2\nLine 2\nLine 3\nLine 4\n");
}
private ChangeInfo getChangeFromServer(Change.Id changeId) throws RestApiException {
return gApi.changes().id(changeId.get()).get();
}

View File

@@ -19,6 +19,8 @@ import static com.google.gerrit.extensions.common.testing.CommentInfoSubject.ass
import com.google.common.truth.Correspondence;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.PatchSet;
@@ -33,6 +35,7 @@ import org.junit.Test;
public class PatchsetOperationsImplTest extends AbstractDaemonTest {
@Inject private ChangeOperations changeOperations;
@Inject private AccountOperations accountOperations;
@Test
public void commentCanBeCreatedWithoutSpecifyingAnyParameters() throws Exception {
@@ -279,6 +282,34 @@ public class PatchsetOperationsImplTest extends AbstractDaemonTest {
assertThat(comment).inReplyTo().isEqualTo(parentCommentUuid);
}
@Test
public void tagCanBeAttachedToAComment() throws Exception {
Change.Id changeId = changeOperations.newChange().create();
String commentUuid =
changeOperations
.change(changeId)
.currentPatchset()
.newComment()
.tag("my special tag")
.create();
CommentInfo comment = getCommentFromServer(changeId, commentUuid);
assertThat(comment).tag().isEqualTo("my special tag");
}
@Test
public void commentIsCreatedWithSpecifiedAuthor() throws Exception {
Change.Id changeId = changeOperations.newChange().create();
Account.Id accountId = accountOperations.newAccount().create();
String commentUuid =
changeOperations.change(changeId).currentPatchset().newComment().author(accountId).create();
CommentInfo comment = getCommentFromServer(changeId, commentUuid);
assertThat(comment).author().id().isEqualTo(accountId.get());
}
private List<CommentInfo> getCommentsFromServer(Change.Id changeId) throws RestApiException {
return gApi.changes().id(changeId.get()).commentsAsList();
}

View File

@@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertAbout;
import com.google.common.io.CharStreams;
import com.google.common.truth.FailureMetadata;
import com.google.common.truth.IterableSubject;
import com.google.common.truth.StringSubject;
import com.google.common.truth.Subject;
import com.google.gerrit.extensions.restapi.RawInput;
@@ -45,9 +46,9 @@ public class ChangeFileContentModificationSubject extends Subject {
this.modification = modification;
}
public StringSubject filePath() {
public IterableSubject filePaths() {
isNotNull();
return check("getFilePath()").that(modification.getFilePath());
return check("getFilePaths()").that(modification.getFilePaths());
}
public StringSubject newContent() throws IOException {

View File

@@ -15,6 +15,7 @@
package com.google.gerrit.server.edit.tree;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
@@ -92,6 +93,48 @@ public class TreeCreatorTest {
assertThat(isEmptyTree(newTreeId)).isTrue();
}
@Test
public void modificationsMustNotReferToSameFilePaths() {
TreeCreator treeCreator = TreeCreator.basedOnEmptyTree();
treeCreator.addTreeModifications(
ImmutableList.of(
new RenameFileModification("oldFileName", "newFileName"),
new ChangeFileContentModification(
"newFileName", RawInputUtil.create("Different content"))));
IllegalStateException exception =
assertThrows(
IllegalStateException.class, () -> treeCreator.createNewTreeAndGetId(repository));
assertThat(exception).hasMessageThat().contains("oldFileName");
assertThat(exception).hasMessageThat().contains("newFileName");
}
@Test
public void fileContentModificationRefersToModifiedFile() {
ChangeFileContentModification contentModification =
new ChangeFileContentModification("myFileName", RawInputUtil.create("Some content"));
assertThat(contentModification.getFilePaths()).containsExactly("myFileName");
}
@Test
public void renameFileModificationRefersToOldAndNewFilePath() {
RenameFileModification fileModification =
new RenameFileModification("oldFileName", "newFileName");
assertThat(fileModification.getFilePaths()).containsExactly("oldFileName", "newFileName");
}
@Test
public void deleteFileModificationRefersToDeletedFile() {
DeleteFileModification fileModification = new DeleteFileModification("myFileName");
assertThat(fileModification.getFilePaths()).containsExactly("myFileName");
}
@Test
public void restoreFileModificationRefersToRestoredFile() {
RestoreFileModification fileModification = new RestoreFileModification("myFileName");
assertThat(fileModification.getFilePaths()).containsExactly("myFileName");
}
private String getFileContent(ObjectId treeId, String filePath) throws Exception {
try (RevWalk revWalk = new RevWalk(repository);
ObjectReader reader = revWalk.getObjectReader()) {

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.server.fixes;
import static com.google.gerrit.server.edit.tree.TreeModificationSubject.assertThatList;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.Comparator.comparing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -28,7 +29,6 @@ import com.google.gerrit.server.change.FileContentUtil;
import com.google.gerrit.server.edit.tree.TreeModification;
import com.google.gerrit.server.project.ProjectState;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
@@ -73,8 +73,8 @@ public class FixReplacementInterpreterTest {
assertThatList(sortedTreeModifications)
.element(0)
.asChangeFileContentModification()
.filePath()
.isEqualTo(filePath1);
.filePaths()
.containsExactly(filePath1);
assertThatList(sortedTreeModifications)
.element(0)
.asChangeFileContentModification()
@@ -83,8 +83,8 @@ public class FixReplacementInterpreterTest {
assertThatList(sortedTreeModifications)
.element(1)
.asChangeFileContentModification()
.filePath()
.isEqualTo(filePath2);
.filePaths()
.containsExactly(filePath2);
assertThatList(sortedTreeModifications)
.element(1)
.asChangeFileContentModification()
@@ -340,7 +340,10 @@ public class FixReplacementInterpreterTest {
private static List<TreeModification> getSortedCopy(List<TreeModification> treeModifications) {
List<TreeModification> sortedTreeModifications = new ArrayList<>(treeModifications);
sortedTreeModifications.sort(Comparator.comparing(TreeModification::getFilePath));
// The sorting is only necessary to get a deterministic order. The exact order doesn't matter.
sortedTreeModifications.sort(
comparing(
treeModification -> treeModification.getFilePaths().stream().findFirst().orElse("")));
return sortedTreeModifications;
}
}