blob: b254d6f78a7067e95bb503fbeb4f0a29025e41ce [file] [log] [blame] [edit]
// Copyright (C) 2019 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.git;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.git.ObjectIds.abbreviateName;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH;
import java.util.function.Function;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevBlob;
import org.junit.Test;
public class ObjectIdsTest {
private static final ObjectId ID =
ObjectId.fromString("0000000000100000000000000000000000000000");
private static final ObjectId AMBIGUOUS_BLOB_ID =
ObjectId.fromString("0000000000b36b6aa7ea4b75318ed078f55505c3");
private static final ObjectId AMBIGUOUS_TREE_ID =
ObjectId.fromString("0000000000cdcf04beb2fab69e65622616294984");
@Test
public void abbreviateNameDefaultLength() throws Exception {
assertRuntimeException(() -> abbreviateName(null));
assertThat(abbreviateName(ID)).isEqualTo("0000000");
assertThat(abbreviateName(AMBIGUOUS_BLOB_ID)).isEqualTo(abbreviateName(ID));
assertThat(abbreviateName(AMBIGUOUS_TREE_ID)).isEqualTo(abbreviateName(ID));
}
@Test
public void abbreviateNameCustomLength() throws Exception {
assertRuntimeException(() -> abbreviateName(null, 1));
assertRuntimeException(() -> abbreviateName(ID, -1));
assertRuntimeException(() -> abbreviateName(ID, 0));
assertRuntimeException(() -> abbreviateName(ID, 41));
assertThat(abbreviateName(ID, 5)).isEqualTo("00000");
assertThat(abbreviateName(ID, 40)).isEqualTo(ID.name());
}
@Test
public void abbreviateNameDefaultLengthWithReader() throws Exception {
assertRuntimeException(() -> abbreviateName(ID, null));
ObjectReader reader = newReaderWithAmbiguousIds();
assertThat(abbreviateName(ID, reader)).isEqualTo("00000000001");
}
@Test
public void abbreviateNameCustomLengthWithReader() throws Exception {
ObjectReader reader = newReaderWithAmbiguousIds();
assertRuntimeException(() -> abbreviateName(ID, -1, reader));
assertRuntimeException(() -> abbreviateName(ID, 0, reader));
assertRuntimeException(() -> abbreviateName(ID, 41, reader));
assertRuntimeException(() -> abbreviateName(ID, 5, null));
String shortest = "00000000001";
assertThat(abbreviateName(ID, 1, reader)).isEqualTo(shortest);
assertThat(abbreviateName(ID, 7, reader)).isEqualTo(shortest);
assertThat(abbreviateName(ID, shortest.length(), reader)).isEqualTo(shortest);
assertThat(abbreviateName(ID, shortest.length() + 1, reader)).isEqualTo("000000000010");
}
@Test
public void copyOrNull() throws Exception {
testCopy(ObjectIds::copyOrNull);
assertThat(ObjectIds.copyOrNull(null)).isNull();
}
@Test
public void copyOrZero() throws Exception {
testCopy(ObjectIds::copyOrZero);
assertThat(ObjectIds.copyOrZero(null)).isEqualTo(ObjectId.zeroId());
}
private void testCopy(Function<AnyObjectId, ObjectId> copyFunc) {
MyObjectId myId = new MyObjectId(ID);
assertThat(myId).isEqualTo(ID);
ObjectId copy = copyFunc.apply(myId);
assertThat(copy).isEqualTo(myId);
assertThat(copy).isNotSameInstanceAs(myId);
assertThat(copy.getClass()).isEqualTo(ObjectId.class);
}
@Test
public void matchesAbbreviation() throws Exception {
assertThat(ObjectIds.matchesAbbreviation(null, "")).isFalse();
assertThat(ObjectIds.matchesAbbreviation(null, "0")).isFalse();
assertThat(ObjectIds.matchesAbbreviation(null, "00000")).isFalse();
assertThat(ObjectIds.matchesAbbreviation(null, "not a SHA-1")).isFalse();
assertThat(ObjectIds.matchesAbbreviation(null, ID.name())).isFalse();
assertThat(ObjectIds.matchesAbbreviation(ID, "")).isTrue();
for (int i = 1; i <= OBJECT_ID_STRING_LENGTH; i++) {
String prefix = ID.name().substring(0, i);
assertWithMessage("match %s against %s", ID.name(), prefix)
.that(ObjectIds.matchesAbbreviation(ID, prefix))
.isTrue();
}
assertThat(ObjectIds.matchesAbbreviation(ID, "1")).isFalse();
assertThat(ObjectIds.matchesAbbreviation(ID, "x")).isFalse();
assertThat(ObjectIds.matchesAbbreviation(ID, "not a SHA-1")).isFalse();
assertThat(ObjectIds.matchesAbbreviation(ID, AMBIGUOUS_BLOB_ID.name())).isFalse();
}
@FunctionalInterface
private interface Func {
void call() throws Exception;
}
private static void assertRuntimeException(Func func) throws Exception {
assertThrows(RuntimeException.class, () -> func.call());
}
private static ObjectReader newReaderWithAmbiguousIds() throws Exception {
// Recipe for creating ambiguous IDs courtesy of git core:
// https://github.com/git/git/blob/df799f5d99ac51d4fc791d546de3f936088582fc/t/t1512-rev-parse-disambiguation.sh
try (TestRepository<Repository> tr =
new TestRepository<>(new InMemoryRepository(new DfsRepositoryDescription("repo")))) {
String blobData = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n\nb1rwzyc3\n";
RevBlob blob = tr.blob(blobData);
assertThat(blob.name()).isEqualTo(AMBIGUOUS_BLOB_ID.name());
assertThat(tr.tree(tr.file("a0blgqsjc", blob)).name()).isEqualTo(AMBIGUOUS_TREE_ID.name());
return tr.getRevWalk().getObjectReader();
}
}
private static class MyObjectId extends ObjectId {
private static final long serialVersionUID = 1L;
MyObjectId(AnyObjectId src) {
super(src);
}
}
}