| /* |
| * 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.testFramework.vcs; |
| |
| import com.intellij.execution.process.ProcessOutput; |
| import com.intellij.openapi.Disposable; |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.command.WriteCommandAction; |
| import com.intellij.openapi.components.ProjectComponent; |
| import com.intellij.openapi.diff.LineTokenizer; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.util.Disposer; |
| import com.intellij.openapi.util.io.FileUtil; |
| import com.intellij.openapi.vcs.*; |
| import com.intellij.openapi.vcs.annotate.AnnotationProvider; |
| import com.intellij.openapi.vcs.annotate.FileAnnotation; |
| import com.intellij.openapi.vcs.changes.*; |
| import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl; |
| import com.intellij.openapi.vfs.LocalFileSystem; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.testFramework.UsefulTestCase; |
| import com.intellij.testFramework.builders.EmptyModuleFixtureBuilder; |
| import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; |
| import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; |
| import com.intellij.testFramework.fixtures.TestFixtureBuilder; |
| import com.intellij.util.Processor; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| import org.junit.Assert; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.*; |
| import java.util.concurrent.atomic.AtomicReference; |
| |
| /** |
| * @author yole |
| */ |
| @SuppressWarnings({"UseOfSystemOutOrSystemErr"}) |
| public abstract class AbstractVcsTestCase { |
| protected boolean myTraceClient = false; |
| protected Project myProject; |
| protected VirtualFile myWorkingCopyDir; |
| protected File myClientBinaryPath; |
| protected IdeaProjectTestFixture myProjectFixture; |
| protected boolean myInitChangeListManager = true; |
| |
| protected abstract String getPluginName(); |
| |
| protected TestClientRunner createClientRunner() { |
| return createClientRunner(null); |
| } |
| |
| protected TestClientRunner createClientRunner(@Nullable Map<String, String> clientEnvironment) { |
| return new TestClientRunner(myTraceClient, myClientBinaryPath, clientEnvironment); |
| } |
| |
| public void setVcsMappings(VcsDirectoryMapping... mappings) { |
| setVcsMappings(Arrays.asList(mappings)); |
| } |
| |
| protected void setVcsMappings(List<VcsDirectoryMapping> mappings) { |
| ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject); |
| vcsManager.setDirectoryMappings(mappings); |
| vcsManager.updateActiveVcss(); |
| ChangeListManagerImpl.getInstanceImpl(myProject).waitUntilRefreshed(); |
| } |
| |
| protected static void refreshVfs() { |
| UsefulTestCase.edt(new Runnable() { |
| @Override |
| public void run() { |
| LocalFileSystem.getInstance().refresh(false); |
| } |
| }); |
| } |
| |
| protected void initProject(final File clientRoot, String testName) throws Exception { |
| final String key = "idea.load.plugins.id"; |
| final String was = System.getProperty(key); |
| try { |
| final String pluginName = getPluginName(); |
| if (pluginName != null) { |
| System.setProperty(key, pluginName); |
| } |
| String name = testName; |
| final TestFixtureBuilder<IdeaProjectTestFixture> testFixtureBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(name); |
| myProjectFixture = testFixtureBuilder.getFixture(); |
| testFixtureBuilder.addModule(EmptyModuleFixtureBuilder.class).addContentRoot(clientRoot.toString()); |
| myProjectFixture.setUp(); |
| myProject = myProjectFixture.getProject(); |
| |
| projectCreated(); |
| |
| if (myInitChangeListManager) { |
| ((ProjectComponent) ChangeListManager.getInstance(myProject)).projectOpened(); |
| } |
| ((ProjectComponent) VcsDirtyScopeManager.getInstance(myProject)).projectOpened(); |
| |
| ApplicationManager.getApplication().runWriteAction(new Runnable() { |
| @Override |
| public void run() { |
| myWorkingCopyDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(clientRoot); |
| assert myWorkingCopyDir != null; |
| } |
| }); |
| } |
| finally { |
| if (was != null) { |
| System.setProperty(key, was); |
| } else { |
| System.clearProperty(key); |
| } |
| } |
| ((ProjectLevelVcsManagerImpl)ProjectLevelVcsManager.getInstance(myProject)).waitForInitialized(); |
| } |
| |
| protected void projectCreated() { |
| } |
| |
| protected void activateVCS(final String vcsName) { |
| ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject); |
| vcsManager.setDirectoryMapping(myWorkingCopyDir.getPath(), vcsName); |
| vcsManager.updateActiveVcss(); |
| |
| AbstractVcs vcs = vcsManager.findVcsByName(vcsName); |
| Assert.assertEquals(1, vcsManager.getRootsUnderVcs(vcs).length); |
| } |
| |
| public VirtualFile createFileInCommand(final String name, @Nullable final String content) { |
| return createFileInCommand(myWorkingCopyDir, name, content); |
| } |
| |
| public VirtualFile createFileInCommand(final VirtualFile parent, final String name, @Nullable final String content) { |
| return VcsTestUtil.createFile(myProject, parent, name, content); |
| } |
| |
| public VirtualFile createDirInCommand(final VirtualFile parent, final String name) { |
| return VcsTestUtil.createDir(myProject, parent, name); |
| } |
| |
| protected void clearDirInCommand(final VirtualFile dir, final Processor<VirtualFile> filter) { |
| new WriteCommandAction.Simple(myProject) { |
| @Override |
| protected void run() throws Throwable { |
| int numOfRuns = 5; |
| for (int i = 0; i < numOfRuns; i++) { |
| try { |
| final VirtualFile[] children = dir.getChildren(); |
| for (VirtualFile child : children) { |
| if (filter != null && filter.process(child)) { |
| child.delete(AbstractVcsTestCase.this); |
| } |
| } |
| return; |
| } |
| catch (IOException e) { |
| if (i == (numOfRuns - 1)) { |
| // last run |
| throw e; |
| } |
| Thread.sleep(50); |
| continue; |
| } |
| } |
| } |
| }.execute(); |
| } |
| |
| protected void tearDownProject() throws Exception { |
| if (myProject != null) { |
| ((ProjectComponent) VcsDirtyScopeManager.getInstance(myProject)).projectClosed(); |
| ((ProjectComponent) ChangeListManager.getInstance(myProject)).projectClosed(); |
| ((ChangeListManagerImpl)ChangeListManager.getInstance(myProject)).stopEveryThingIfInTestMode(); |
| ((ProjectComponent)ProjectLevelVcsManager.getInstance(myProject)).projectClosed(); |
| myProject = null; |
| } |
| if (myProjectFixture != null) { |
| myProjectFixture.tearDown(); |
| myProjectFixture = null; |
| } |
| } |
| |
| public void setStandardConfirmation(final String vcsName, final VcsConfiguration.StandardConfirmation op, |
| final VcsShowConfirmationOption.Value value) { |
| setStandardConfirmation(myProject, vcsName, op, value); |
| } |
| |
| public static void setStandardConfirmation(Project project, String vcsName, VcsConfiguration.StandardConfirmation op, |
| VcsShowConfirmationOption.Value value) { |
| ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project); |
| AbstractVcs vcs = vcsManager.findVcsByName(vcsName); |
| VcsShowConfirmationOption option = vcsManager.getStandardConfirmation(op, vcs); |
| option.setValue(value); |
| } |
| |
| public static void verify(final ProcessOutput runResult) { |
| Assert.assertEquals(runResult.getStderr(), 0, runResult.getExitCode()); |
| } |
| |
| protected static void verify(final ProcessOutput runResult, final String... stdoutLines) { |
| verify(runResult, false, stdoutLines); |
| } |
| |
| protected static void verifySorted(final ProcessOutput runResult, final String... stdoutLines) { |
| verify(runResult, true, stdoutLines); |
| } |
| |
| private static void verify(final ProcessOutput runResult, final boolean sorted, final String... stdoutLines) { |
| verify(runResult); |
| final String[] lines = new LineTokenizer(runResult.getStdout()).execute(); |
| if (sorted) { |
| Arrays.sort(lines); |
| } |
| Assert.assertEquals(runResult.getStdout(), stdoutLines.length, lines.length); |
| for(int i=0; i<stdoutLines.length; i++) { |
| Assert.assertEquals(stdoutLines [i], compressWhitespace(lines [i])); |
| } |
| } |
| |
| private static String compressWhitespace(String line) { |
| while(line.indexOf(" ") > 0) { |
| line = line.replace(" ", " "); |
| } |
| return line.trim(); |
| } |
| |
| protected VcsDirtyScope getDirtyScopeForFile(VirtualFile file) { |
| VcsDirtyScopeManager dirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject); |
| dirtyScopeManager.retrieveScopes(); // ensure that everything besides the file is clean |
| dirtyScopeManager.fileDirty(file); |
| List<VcsDirtyScope> scopes = dirtyScopeManager.retrieveScopes().getScopes(); |
| Assert.assertEquals(1, scopes.size()); |
| return scopes.get(0); |
| } |
| |
| protected void renameFileInCommand(final VirtualFile file, final String newName) { |
| VcsTestUtil.renameFileInCommand(myProject, file, newName); |
| } |
| |
| public void deleteFileInCommand(final VirtualFile file) { |
| VcsTestUtil.deleteFileInCommand(myProject, file); |
| } |
| |
| public void editFileInCommand(final VirtualFile file, final String newContent) { |
| VcsTestUtil.editFileInCommand(myProject, file, newContent); |
| } |
| |
| protected VirtualFile copyFileInCommand(final VirtualFile file, final String toName) { |
| final AtomicReference<VirtualFile> res = new AtomicReference<VirtualFile>(); |
| new WriteCommandAction.Simple(myProject) { |
| @Override |
| protected void run() throws Throwable { |
| try { |
| res.set(file.copy(this, file.getParent(), toName)); |
| } |
| catch (IOException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| }.execute(); |
| return res.get(); |
| } |
| |
| protected void moveFileInCommand(final VirtualFile file, final VirtualFile newParent) { |
| VcsTestUtil.moveFileInCommand(myProject, file, newParent); |
| } |
| |
| protected void verifyChange(final Change c, final String beforePath, final String afterPath) { |
| if (beforePath == null) { |
| Assert.assertNull(c.getBeforeRevision()); |
| } |
| else { |
| verifyRevision(c.getBeforeRevision(), beforePath); |
| } |
| if (afterPath == null) { |
| Assert.assertNull(c.getAfterRevision()); |
| } |
| else { |
| verifyRevision(c.getAfterRevision(), afterPath); |
| } |
| } |
| |
| public VirtualFile getWorkingCopyDir() { |
| return myWorkingCopyDir; |
| } |
| |
| private void verifyRevision(final ContentRevision beforeRevision, final String beforePath) { |
| File beforeFile = new File(myWorkingCopyDir.getPath(), beforePath); |
| String beforeFullPath = FileUtil.toSystemIndependentName(beforeFile.getPath()); |
| final String beforeRevPath = FileUtil.toSystemIndependentName(beforeRevision.getFile().getPath()); |
| Assert.assertTrue(beforeFullPath + "!=" + beforeRevPath, beforeFullPath.equalsIgnoreCase(beforeRevPath)); |
| } |
| |
| public static void sortChanges(final List<Change> changes) { |
| Collections.sort(changes, new Comparator<Change>() { |
| @Override |
| public int compare(final Change o1, final Change o2) { |
| final String p1 = FileUtil.toSystemIndependentName(ChangesUtil.getFilePath(o1).getPath()); |
| final String p2 = FileUtil.toSystemIndependentName(ChangesUtil.getFilePath(o2).getPath()); |
| return p1.compareTo(p2); |
| } |
| }); |
| } |
| |
| public FileAnnotation createTestAnnotation(@NotNull AnnotationProvider provider, VirtualFile file) throws VcsException { |
| final FileAnnotation annotation = provider.annotate(file); |
| Disposer.register(myProject, new Disposable() { |
| @Override |
| public void dispose() { |
| annotation.dispose(); |
| } |
| }); |
| return annotation; |
| } |
| |
| } |