blob: 05659538da20ffaeb2026ba8b237c4c97d777773 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* 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.intellij.vcs.log.impl;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.Semaphore;
import static org.junit.Assert.assertEquals;
public class TestVcsLogProvider implements VcsLogProvider {
public static final VcsRefType BRANCH_TYPE = new VcsRefType() {
@Override
public boolean isBranch() {
return true;
}
@NotNull
@Override
public Color getBackgroundColor() {
return Color.white;
}
};
private static final String SAMPLE_SUBJECT = "Sample subject";
private static final VcsUser STUB_USER = new VcsUserImpl("John Smith", "John.Smith@mail.com");
@NotNull private final VirtualFile myRoot;
@NotNull private final List<TimedVcsCommit> myCommits;
@NotNull private final Set<VcsRef> myRefs;
@NotNull private final MockRefManager myRefManager;
@NotNull private final ReducibleSemaphore myFullLogSemaphore;
@NotNull private final ReducibleSemaphore myRefreshSemaphore;
private int myReadFirstBlockCounter;
private final Function<TimedVcsCommit, VcsCommitMetadata> myCommitToMetadataConvertor =
new Function<TimedVcsCommit, VcsCommitMetadata>() {
@Override
public VcsCommitMetadata fun(TimedVcsCommit commit) {
return new VcsCommitMetadataImpl(commit.getId(), commit.getParents(), commit.getTimestamp(), myRoot,
SAMPLE_SUBJECT, STUB_USER, SAMPLE_SUBJECT, STUB_USER, commit.getTimestamp());
}
};
public TestVcsLogProvider(@NotNull VirtualFile root) {
myRoot = root;
myCommits = ContainerUtil.newArrayList();
myRefs = ContainerUtil.newHashSet();
myRefManager = new MockRefManager();
myFullLogSemaphore = new ReducibleSemaphore();
myRefreshSemaphore = new ReducibleSemaphore();
}
@NotNull
@Override
public DetailedLogData readFirstBlock(@NotNull final VirtualFile root,
@NotNull Requirements requirements)
throws VcsException {
if (requirements instanceof VcsLogProviderRequirementsEx && ((VcsLogProviderRequirementsEx)requirements).isRefresh()) {
try {
myRefreshSemaphore.acquire();
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
myReadFirstBlockCounter++;
assertRoot(root);
List<VcsCommitMetadata> metadatas = ContainerUtil.map(myCommits.subList(0, requirements.getCommitCount()),
myCommitToMetadataConvertor);
return new LogDataImpl(Collections.<VcsRef>emptySet(), metadatas);
}
@NotNull
@Override
public LogData readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException {
try {
myFullLogSemaphore.acquire();
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
assertRoot(root);
for (TimedVcsCommit commit : myCommits) {
commitConsumer.consume(commit);
}
return new LogDataImpl(myRefs, Collections.<VcsUser>emptySet());
}
private void assertRoot(@NotNull VirtualFile root) {
assertEquals("Requested data for unknown root", myRoot, root);
}
@NotNull
@Override
public List<? extends VcsShortCommitDetails> readShortDetails(@NotNull VirtualFile root, @NotNull List<String> hashes)
throws VcsException {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public List<? extends VcsFullCommitDetails> readFullDetails(@NotNull VirtualFile root, @NotNull List<String> hashes) throws VcsException {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public VcsKey getSupportedVcs() {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public VcsLogRefManager getReferenceManager() {
return myRefManager;
}
@Override
public void subscribeToRootRefreshEvents(@NotNull Collection<VirtualFile> roots, @NotNull VcsLogRefresher refresher) {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public List<TimedVcsCommit> getCommitsMatchingFilter(@NotNull VirtualFile root,
@NotNull VcsLogFilterCollection filterCollection,
int maxCount) throws VcsException {
throw new UnsupportedOperationException();
}
@Nullable
@Override
public VcsUser getCurrentUser(@NotNull VirtualFile root) throws VcsException {
return STUB_USER;
}
@NotNull
@Override
public Collection<String> getContainingBranches(@NotNull VirtualFile root, @NotNull Hash commitHash) throws VcsException {
throw new UnsupportedOperationException();
}
public void appendHistory(@NotNull List<TimedVcsCommit> commits) {
myCommits.addAll(0, commits);
}
public void addRef(@NotNull VcsRef ref) {
myRefs.add(ref);
}
public void blockRefresh() {
myRefreshSemaphore.block();
}
public void unblockRefresh() {
myRefreshSemaphore.unblock();
}
public void blockFullLog() throws InterruptedException {
myFullLogSemaphore.block();
}
public void unblockFullLog() {
myFullLogSemaphore.unblock();
}
public void resetReadFirstBlockCounter() {
myReadFirstBlockCounter = 0;
}
public int getReadFirstBlockCounter() {
return myReadFirstBlockCounter;
}
private static class MockRefManager implements VcsLogRefManager {
@NotNull
@Override
public Comparator<VcsRef> getComparator() {
return new Comparator<VcsRef>() {
@Override
public int compare(VcsRef o1, VcsRef o2) {
return 0;
}
};
}
@NotNull
@Override
public List<RefGroup> group(Collection<VcsRef> refs) {
return ContainerUtil.map(refs, new Function<VcsRef, RefGroup>() {
@Override
public RefGroup fun(VcsRef ref) {
return new SingletonRefGroup(ref);
}
});
}
}
private static class ReducibleSemaphore extends Semaphore {
private boolean myBlocked;
public ReducibleSemaphore() {
super(1);
}
@Override
public void acquire() throws InterruptedException {
if (myBlocked) {
super.acquire();
}
}
public void block() {
myBlocked = true;
reducePermits(1);
}
public void unblock() {
myBlocked = false;
release();
}
}
}