blob: f01b053a17d2d9dc354b7103c090807a38148887 [file] [log] [blame]
/*
* Copyright 2016 The Bazel Authors. All rights reserved.
*
* 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.idea.blaze.base;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.base.Joiner;
import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.io.VirtualFileSystemProvider;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.testFramework.fixtures.TempDirTestFixture;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
/** Creates temp files for integration tests. */
public class TestFileSystem {
private final Project project;
private final TempDirTestFixture tempDirTestFixture;
public TestFileSystem(Project project, TempDirTestFixture tempDirTestFixture) {
this.project = project;
this.tempDirTestFixture = tempDirTestFixture;
}
/** Returns the root directory of the file system */
public String getRootDir() {
return LightPlatformTestCase.getSourceRoot().getPath();
}
/** Creates an empty file in the temp file system */
public VirtualFile createFile(String filePath) {
filePath = makePathRelativeToTestFixture(filePath);
return tempDirTestFixture.createFile(filePath);
}
/** Creates a file with the specified contents in the temp file system */
public VirtualFile createFile(String filePath, String... contentLines) {
return createFile(filePath, Joiner.on("\n").join(contentLines));
}
/** Creates a file with the specified contents in the temp file system */
public VirtualFile createFile(String filePath, String contents) {
filePath = makePathRelativeToTestFixture(filePath);
try {
return tempDirTestFixture.createFile(filePath, contents);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/** Creates a directory in the temp file system */
public VirtualFile createDirectory(String path) {
path = makePathRelativeToTestFixture(path);
try {
return tempDirTestFixture.findOrCreateDir(path);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/** Creates a psi directory in the temp file system */
public PsiDirectory createPsiDirectory(String path) {
return getPsiDirectory(createDirectory(path));
}
/** Creates a psi file in the temp file system */
public PsiFile createPsiFile(String filePath) {
filePath = makePathRelativeToTestFixture(filePath);
return getPsiFile(tempDirTestFixture.createFile(filePath));
}
/** Creates a psi file with the specified contents and file path in the temp file system */
public PsiFile createPsiFile(String filePath, String... contentLines) {
return getPsiFile(createFile(filePath, contentLines));
}
/** Finds PsiFile, and asserts that it's not null. */
public PsiFile getPsiFile(VirtualFile file) {
return new ReadAction<PsiFile>() {
@Override
protected void run(Result<PsiFile> result) throws Throwable {
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
assertThat(psiFile).isNotNull();
result.setResult(psiFile);
}
}.execute().getResultObject();
}
/** Finds PsiDirectory, and asserts that it's not null. */
public PsiDirectory getPsiDirectory(VirtualFile file) {
return new ReadAction<PsiDirectory>() {
@Override
protected void run(Result<PsiDirectory> result) throws Throwable {
PsiDirectory psiFile = PsiManager.getInstance(project).findDirectory(file);
assertThat(psiFile).isNotNull();
result.setResult(psiFile);
}
}.execute().getResultObject();
}
public VirtualFile findFile(String filePath) {
VirtualFile vf = TempFileSystem.getInstance().findFileByPath(filePath);
if (vf == null) {
// this might be a relative path
filePath = makePathRelativeToTestFixture(filePath);
vf = tempDirTestFixture.getFile(filePath);
}
return vf;
}
public VirtualFile findOrCreateDirectory(String path) throws IOException {
path = makePathRelativeToTestFixture(path);
return tempDirTestFixture.findOrCreateDir(path);
}
/**
* Absolute file paths are prohibited -- the TempDirTestFixture used in these tests will prepend
* it's own root to the path.
*/
private String makePathRelativeToTestFixture(String filePath) {
if (!FileUtil.isAbsolute(filePath)) {
return filePath;
}
String tempDirPath = getRootDir();
assertThat(FileUtil.isAncestor(tempDirPath, filePath, true)).isTrue();
return FileUtil.getRelativePath(tempDirPath, filePath, File.separatorChar);
}
/** Redirects file system checks via the TempFileSystem used for these tests. */
public static class TempFileAttributeProvider extends FileAttributeProvider {
final TempFileSystem fileSystem = TempFileSystem.getInstance();
@Override
public boolean exists(File file) {
VirtualFile vf = getVirtualFile(file);
return vf != null && vf.exists();
}
@Override
public boolean isDirectory(File file) {
VirtualFile vf = getVirtualFile(file);
return vf != null && vf.isDirectory();
}
@Override
public boolean isFile(File file) {
VirtualFile vf = getVirtualFile(file);
return vf != null && vf.exists() && !vf.isDirectory();
}
@Override
public File[] listFiles(File file) {
VirtualFile vf = getVirtualFile(file);
if (vf == null) {
return null;
}
VirtualFile[] children = vf.getChildren();
if (children == null) {
return null;
}
return Arrays.stream(vf.getChildren()).map((f) -> new File(f.getPath())).toArray(File[]::new);
}
private VirtualFile getVirtualFile(File file) {
return fileSystem.findFileByPath(file.getPath());
}
}
/** Redirects VirtualFileSystem operations to the TempFileSystem used for these tests. */
public static class TempVirtualFileSystemProvider implements VirtualFileSystemProvider {
final TempFileSystem fileSystem = TempFileSystem.getInstance();
@Override
public LocalFileSystem getSystem() {
return fileSystem;
}
}
}