Snapshot of commit d5ec1d5018ed24f1b4f32b1d09df6dbd7e2fc425
from branch master of git://git.jetbrains.org/idea/community.git
diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
new file mode 100644
index 0000000..240e7e5
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
@@ -0,0 +1,736 @@
+/*
+ * Copyright 2000-2009 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.codeInsight;
+
+import com.intellij.codeInsight.highlighting.HighlightUsagesHandler;
+import com.intellij.ide.DataManager;
+import com.intellij.injected.editor.EditorWindow;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.command.undo.UndoManager;
+import com.intellij.openapi.editor.*;
+import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
+import com.intellij.openapi.editor.actionSystem.EditorActionManager;
+import com.intellij.openapi.editor.actionSystem.TypedAction;
+import com.intellij.openapi.editor.impl.DocumentImpl;
+import com.intellij.openapi.editor.impl.EditorImpl;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.fileEditor.TextEditor;
+import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.impl.source.PostprocessReformattingAspect;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.testFramework.PsiTestCase;
+import com.intellij.testFramework.PsiTestData;
+import com.intellij.testFramework.PsiTestUtil;
+import com.intellij.testFramework.VfsTestUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+/**
+ * @author Mike
+ */
+public abstract class CodeInsightTestCase extends PsiTestCase {
+ protected Editor myEditor;
+
+ protected Editor createEditor(VirtualFile file) {
+ final FileEditorManager instance = FileEditorManager.getInstance(myProject);
+
+ if (file.getFileType().isBinary()) return null;
+
+ Editor editor = instance.openTextEditor(new OpenFileDescriptor(myProject, file, 0), false);
+ ((EditorImpl)editor).setCaretActive();
+ return editor;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ FileEditorManager editorManager = FileEditorManager.getInstance(myProject);
+ VirtualFile[] openFiles = editorManager.getOpenFiles();
+ for (VirtualFile openFile : openFiles) {
+ editorManager.closeFile(openFile);
+ }
+ myEditor = null;
+ super.tearDown();
+ }
+
+ @Override
+ protected PsiTestData createData() {
+ return new CodeInsightTestData();
+ }
+
+ public static final String CARET_MARKER = "<caret>";
+ @NonNls public static final String SELECTION_START_MARKER = "<selection>";
+ @NonNls public static final String SELECTION_END_MARKER = "</selection>";
+
+ protected void configureByFile(@NonNls String filePath) throws Exception {
+ configureByFile(filePath, null);
+ }
+ protected VirtualFile configureByFiles(@Nullable String projectRoot,String... files) throws Exception {
+ final VirtualFile[] vFiles = new VirtualFile[files.length];
+ for (int i = 0; i < files.length; i++) {
+ String path = files[i];
+ final String fullPath = FileUtil.toSystemIndependentName(getTestDataPath() + path);
+ VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath);
+ vFiles[i] = vFile;
+ assertNotNull("file " + fullPath + " not found", vFile);
+ }
+
+ File projectFile = projectRoot == null ? null : new File(getTestDataPath() + projectRoot);
+
+ return configureByFiles(projectFile, vFiles);
+ }
+ protected VirtualFile configureByFile(@NonNls String filePath, String projectRoot) throws Exception {
+ String fullPath = getTestDataPath() + filePath;
+
+ final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
+ assertNotNull("file " + fullPath + " not found", vFile);
+
+ File projectFile = projectRoot == null ? null : new File(getTestDataPath() + projectRoot);
+
+ return configureByFile(vFile, projectFile);
+ }
+
+ protected PsiFile configureByText(final FileType fileType, @NonNls final String text) throws Exception {
+ return configureByText(fileType, text, null);
+ }
+
+ protected PsiFile configureByText(final FileType fileType, @NonNls final String text, @Nullable String _extension) throws Exception {
+ final String extension = _extension == null ? fileType.getDefaultExtension():_extension;
+
+ File dir = createTempDirectory();
+ final File tempFile = FileUtil.createTempFile(dir, "aaa", "." + extension, true);
+ final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+ if (fileTypeManager.getFileTypeByExtension(extension) != fileType) {
+ new WriteCommandAction(getProject()) {
+ @Override
+ protected void run(Result result) throws Exception {
+ fileTypeManager.associateExtension(fileType, extension);
+ }
+ }.execute();
+ }
+ final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile);
+ assert vFile != null;
+ VfsUtil.saveText(vFile, text);
+
+ final VirtualFile vdir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(dir);
+
+ PsiTestUtil.addSourceRoot(myModule, vdir);
+
+ configureByExistingFile(vFile);
+
+ assertEquals(fileType, myFile.getVirtualFile().getFileType());
+ return myFile;
+ }
+
+
+ @Override
+ protected String getTestDataPath() {
+ return PathManagerEx.getTestDataPath();
+ }
+
+ protected void configureByFile(final VirtualFile vFile) throws IOException {
+ configureByFile(vFile, null);
+ }
+
+ protected void configureByExistingFile(final VirtualFile virtualFile) {
+ myFile = null;
+ myEditor = null;
+
+ final Editor editor = createEditor(virtualFile);
+
+ final Document document = editor.getDocument();
+ final EditorInfo editorInfo = new EditorInfo(document.getText());
+
+ final String newFileText = editorInfo.getNewFileText();
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ if (!document.getText().equals(newFileText)) {
+ document.setText(newFileText);
+ }
+
+ PsiFile file = myPsiManager.findFile(virtualFile);
+ if (myFile == null) myFile = file;
+
+ if (myEditor == null) myEditor = editor;
+
+ editorInfo.applyToEditor(editor);
+ }
+ });
+
+
+ PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+ }
+
+ protected VirtualFile configureByFiles(@Nullable final File rawProjectRoot, final VirtualFile... vFiles) throws IOException {
+ myFile = null;
+ myEditor = null;
+
+ final File toDirIO = createTempDirectory();
+ final VirtualFile toDir = getVirtualFile(toDirIO);
+
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule);
+ final ModifiableRootModel rootModel = rootManager.getModifiableModel();
+ if (clearModelBeforeConfiguring()) {
+ rootModel.clear();
+ }
+
+ // auxiliary files should be copied first
+ VirtualFile[] reversed = ArrayUtil.reverseArray(vFiles);
+ final LinkedHashMap<VirtualFile, EditorInfo> editorInfos;
+ if (rawProjectRoot != null) {
+ final File projectRoot = rawProjectRoot.getCanonicalFile();
+ FileUtil.copyDir(projectRoot, toDirIO);
+ VirtualFile fromDir = getVirtualFile(projectRoot);
+ editorInfos =
+ copyFilesFillingEditorInfos(fromDir, toDir, ContainerUtil.map2Array(reversed, String.class, new Function<VirtualFile, String>() {
+ @Override
+ public String fun(final VirtualFile s) {
+ return s.getPath().substring(projectRoot.getPath().length());
+ }
+ }));
+
+ toDir.refresh(false, true);
+ }
+ else {
+ editorInfos = new LinkedHashMap<VirtualFile, EditorInfo>();
+ for (final VirtualFile vFile : reversed) {
+ VirtualFile parent = vFile.getParent();
+ assert parent.isDirectory() : parent;
+ editorInfos.putAll(copyFilesFillingEditorInfos(parent, toDir, vFile.getName()));
+ }
+ }
+
+ boolean sourceRootAdded = false;
+ if (isAddDirToContentRoot()) {
+ final ContentEntry contentEntry = rootModel.addContentEntry(toDir);
+ if (isAddDirToSource()) {
+ sourceRootAdded = true;
+ contentEntry.addSourceFolder(toDir, isAddDirToTests());
+ }
+ }
+ doCommitModel(rootModel);
+ if (sourceRootAdded) {
+ sourceRootAdded(toDir);
+ }
+
+ openEditorsAndActivateLast(editorInfos);
+ }
+ catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+ });
+
+
+ return toDir;
+ }
+
+ protected boolean isAddDirToTests() {
+ return false;
+ }
+
+ protected void doCommitModel(final ModifiableRootModel rootModel) {
+ rootModel.commit();
+ }
+
+ protected void sourceRootAdded(final VirtualFile dir) {
+ }
+
+ protected LinkedHashMap<VirtualFile, EditorInfo> copyFilesFillingEditorInfos(String testDataFromDir,
+ final VirtualFile toDir,
+ final String... relativePaths) throws IOException {
+ if (!testDataFromDir.startsWith("/")) testDataFromDir = "/" + testDataFromDir;
+ return copyFilesFillingEditorInfos(LocalFileSystem.getInstance().refreshAndFindFileByPath(getTestDataPath() + testDataFromDir), toDir, relativePaths);
+ }
+
+ protected LinkedHashMap<VirtualFile, EditorInfo> copyFilesFillingEditorInfos(final VirtualFile fromDir, final VirtualFile toDir, final String... relativePaths) throws IOException {
+ LinkedHashMap<VirtualFile, EditorInfo> editorInfos = new LinkedHashMap<VirtualFile, EditorInfo>();
+
+ List<OutputStream> streamsToClose = new ArrayList<OutputStream>();
+
+ for (String relativePath : relativePaths) {
+ if (relativePath.startsWith("/")) {
+ relativePath = relativePath.substring(1);
+ }
+ final VirtualFile fromFile = fromDir.findFileByRelativePath(relativePath);
+ assertNotNull(fromDir.getPath() + "/" + relativePath, fromFile);
+ VirtualFile toFile = toDir.findFileByRelativePath(relativePath);
+ if (toFile == null) {
+ final File file = new File(toDir.getPath(), relativePath);
+ FileUtil.createIfDoesntExist(file);
+ toFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+ assertNotNull(file.getCanonicalPath(), toFile);
+ }
+ toFile.putUserData(VfsTestUtil.TEST_DATA_FILE_PATH, FileUtil.toSystemDependentName(fromFile.getPath()));
+ editorInfos.put(toFile, copyContent(fromFile, toFile, streamsToClose));
+ }
+
+ for(int i = streamsToClose.size() -1; i >= 0 ; --i) {
+ streamsToClose.get(i).close();
+ }
+ return editorInfos;
+ }
+
+ /*protected LinkedHashMap<VirtualFile, EditorInfo> copyFilesFillingEditorInfos(final VirtualFile fromDir, final VirtualFile toDir) throws IOException {
+ final LinkedHashMap<VirtualFile, EditorInfo> map = new LinkedHashMap<VirtualFile, EditorInfo>();
+ copyFilesFillingEditorInfos(fromDir, toDir, map);
+ return map;
+ }
+
+
+ private void copyFilesFillingEditorInfos(final VirtualFile fromDir, final VirtualFile toDir, LinkedHashMap<VirtualFile, EditorInfo> editorInfos) throws IOException {
+
+ List<OutputStream> streamsToClose = new ArrayList<OutputStream>();
+
+ final VirtualFile[] files = fromDir.getChildren();
+ for (final VirtualFile fromFile : files) {
+ if (fromFile.isDirectory()) {
+ copyFilesFillingEditorInfos(fromFile, toDir.createChildDirectory(this, fromFile.getName()), editorInfos);
+ } else {
+ final VirtualFile toFile = toDir.createChildData(this, fromFile.getName());
+ editorInfos.put(toFile, copyContent(fromFile, toFile, streamsToClose));
+ }
+ }
+
+ for(int i = streamsToClose.size() -1; i >= 0 ; --i) {
+ streamsToClose.get(i).close();
+ }
+ }*/
+
+ private EditorInfo copyContent(final VirtualFile from, final VirtualFile to, final List<OutputStream> streamsToClose) throws IOException {
+ byte[] content = from.getFileType().isBinary() ? from.contentsToByteArray(): null;
+ final String fileText = from.getFileType().isBinary() ? null : StringUtil.convertLineSeparators(VfsUtil.loadText(from));
+
+ EditorInfo editorInfo = fileText != null ? new EditorInfo(fileText) : null;
+ String newFileText = fileText != null ? editorInfo.getNewFileText() : null;
+ doWrite(newFileText, to, content, streamsToClose);
+ return editorInfo;
+ }
+
+ protected final void setActiveEditor(Editor editor) {
+ myEditor = editor;
+ myFile = getPsiFile(editor.getDocument());
+ }
+
+ protected List<Editor> openEditorsAndActivateLast(final LinkedHashMap<VirtualFile, EditorInfo> editorInfos) {
+ final List<Editor> list = openEditors(editorInfos);
+ setActiveEditor(list.get(list.size() - 1));
+ return list;
+ }
+
+ protected final List<Editor> openEditors(final LinkedHashMap<VirtualFile, EditorInfo> editorInfos) {
+ return ContainerUtil.map(editorInfos.keySet(), new Function<VirtualFile, Editor>() {
+ @Override
+ public Editor fun(final VirtualFile newVFile) {
+ PsiFile file = myPsiManager.findFile(newVFile);
+ if (myFile == null) myFile = file;
+
+ Editor editor = createEditor(newVFile);
+ if (myEditor == null) myEditor = editor;
+
+ EditorInfo editorInfo = editorInfos.get(newVFile);
+ if (editorInfo != null) {
+ editorInfo.applyToEditor(editor);
+ }
+ return editor;
+ }
+ });
+ }
+
+ private void doWrite(final String newFileText, final VirtualFile newVFile, final byte[] content, final List<OutputStream> streamsToClose) throws IOException {
+ if (newFileText != null) {
+ VfsUtil.saveText(newVFile, newFileText);
+ } else {
+ final OutputStream outputStream = newVFile.getOutputStream(this, -1, -1);
+ outputStream.write(content);
+ streamsToClose.add(outputStream);
+ }
+ }
+
+ protected boolean isAddDirToContentRoot() {
+ return true;
+ }
+
+ protected boolean isAddDirToSource() {
+ return true;
+ }
+
+ protected VirtualFile configureByFile(final VirtualFile vFile, final File projectRoot) throws IOException {
+ return configureByFiles(projectRoot, vFile);
+ }
+
+ protected boolean clearModelBeforeConfiguring() {
+ return false;
+ }
+
+ protected void setupCursorAndSelection(final Editor editor) {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ public void run() {
+ Document document = editor.getDocument();
+ final String text = document.getText();
+
+ int caretIndex = text.indexOf(CARET_MARKER);
+ int selStartIndex = text.indexOf(SELECTION_START_MARKER);
+ int selEndIndex = text.indexOf(SELECTION_END_MARKER);
+
+ final RangeMarker caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
+ final RangeMarker selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
+ final RangeMarker selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
+
+ if (caretMarker != null) {
+ document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
+ }
+ if (selStartMarker != null) {
+ document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
+ }
+ if (selEndMarker != null) {
+ document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
+ }
+
+ final String newText = document.getText();
+
+ if (caretMarker != null) {
+ int caretLine = StringUtil.offsetToLineNumber(newText, caretMarker.getStartOffset());
+ int caretCol = caretMarker.getStartOffset() - StringUtil.lineColToOffset(newText, caretLine, 0);
+ LogicalPosition pos = new LogicalPosition(caretLine, caretCol);
+ editor.getCaretModel().moveToLogicalPosition(pos);
+ }
+
+ if (selStartMarker != null) {
+ editor.getSelectionModel().setSelection(selStartMarker.getStartOffset(), selEndMarker.getStartOffset());
+ }
+
+ PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+ }
+ });
+ }
+
+ @Override
+ protected void configure(String path, String dataName) throws Exception {
+ super.configure(path, dataName);
+
+ myEditor = createEditor(myFile.getVirtualFile());
+
+ CodeInsightTestData data = (CodeInsightTestData) myTestDataBefore;
+
+ LogicalPosition pos = new LogicalPosition(data.getLineNumber() - 1, data.getColumnNumber() - 1);
+ myEditor.getCaretModel().moveToLogicalPosition(pos);
+
+ int selectionEnd;
+ int selectionStart = selectionEnd = myEditor.getCaretModel().getOffset();
+
+ if (data.getSelectionStartColumnNumber() >= 0) {
+ selectionStart = myEditor.logicalPositionToOffset(new LogicalPosition(data.getSelectionEndLineNumber() - 1, data.getSelectionStartColumnNumber() - 1));
+ selectionEnd = myEditor.logicalPositionToOffset(new LogicalPosition(data.getSelectionEndLineNumber() - 1, data.getSelectionEndColumnNumber() - 1));
+ }
+
+ myEditor.getSelectionModel().setSelection(selectionStart, selectionEnd);
+ }
+
+ protected void checkResultByFile(@NonNls String filePath) throws Exception {
+ checkResultByFile(filePath, false);
+ }
+
+ protected void checkResultByFile(@NonNls final String filePath, final boolean stripTrailingSpaces) throws Exception {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ getProject().getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
+ if (stripTrailingSpaces) {
+ ((DocumentImpl)myEditor.getDocument()).stripTrailingSpaces();
+ }
+
+ PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+ String fullPath = getTestDataPath() + filePath;
+
+ final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
+ assertNotNull("Cannot find file " + fullPath, vFile);
+ String ft = null;
+ try {
+ ft = VfsUtil.loadText(vFile);
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ String fileText = StringUtil.convertLineSeparators(ft);
+ Document document = EditorFactory.getInstance().createDocument(fileText);
+
+ int caretIndex = fileText.indexOf(CARET_MARKER);
+ int selStartIndex = fileText.indexOf(SELECTION_START_MARKER);
+ int selEndIndex = fileText.indexOf(SELECTION_END_MARKER);
+
+ final RangeMarker caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
+ final RangeMarker selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
+ final RangeMarker selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
+
+ if (caretMarker != null) {
+ document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
+ }
+ if (selStartMarker != null) {
+ document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
+ }
+ if (selEndMarker != null) {
+ document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
+ }
+
+ String newFileText = document.getText();
+ String newFileText1 = newFileText;
+ if (stripTrailingSpaces) {
+ Document document1 = EditorFactory.getInstance().createDocument(newFileText);
+ ((DocumentImpl)document1).stripTrailingSpaces();
+ newFileText1 = document1.getText();
+ }
+
+ if (myEditor instanceof EditorWindow) {
+ myEditor = ((EditorWindow)myEditor).getDelegate();
+ myFile = PsiDocumentManager.getInstance(getProject()).getPsiFile(myEditor.getDocument());
+ }
+
+ String text = myFile.getText();
+ text = StringUtil.convertLineSeparators(text);
+
+ assertEquals("Text mismatch in file " + filePath, newFileText1, text);
+
+ if (caretMarker != null) {
+ int caretLine = StringUtil.offsetToLineNumber(newFileText, caretMarker.getStartOffset());
+ int caretCol = caretMarker.getStartOffset() - StringUtil.lineColToOffset(newFileText, caretLine, 0);
+
+ assertEquals("caretLine", caretLine + 1, myEditor.getCaretModel().getLogicalPosition().line + 1);
+ assertEquals("caretColumn", caretCol + 1, myEditor.getCaretModel().getLogicalPosition().column + 1);
+ }
+
+ if (selStartMarker != null && selEndMarker != null) {
+ int selStartLine = StringUtil.offsetToLineNumber(newFileText, selStartMarker.getStartOffset());
+ int selStartCol = selStartMarker.getStartOffset() - StringUtil.lineColToOffset(newFileText, selStartLine, 0);
+
+ int selEndLine = StringUtil.offsetToLineNumber(newFileText, selEndMarker.getEndOffset());
+ int selEndCol = selEndMarker.getEndOffset() - StringUtil.lineColToOffset(newFileText, selEndLine, 0);
+
+ assertEquals("selectionStartLine", selStartLine + 1,
+ StringUtil.offsetToLineNumber(newFileText, myEditor.getSelectionModel().getSelectionStart()) + 1);
+
+ assertEquals("selectionStartCol", selStartCol + 1,
+ myEditor.getSelectionModel().getSelectionStart() - StringUtil.lineColToOffset(newFileText, selStartLine, 0) + 1);
+
+ assertEquals("selectionEndLine", selEndLine + 1,
+ StringUtil.offsetToLineNumber(newFileText, myEditor.getSelectionModel().getSelectionEnd()) + 1);
+
+ assertEquals("selectionEndCol", selEndCol + 1,
+ myEditor.getSelectionModel().getSelectionEnd() - StringUtil.lineColToOffset(newFileText, selEndLine, 0) + 1);
+ }
+ else {
+ assertTrue("should has no selection, but was: ("+myEditor.getSelectionModel().getSelectionStart()+", "+myEditor.getSelectionModel().getSelectionEnd()+")",
+ !myEditor.getSelectionModel().hasSelection());
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void checkResult(String dataName) throws Exception {
+ PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+ super.checkResult(dataName);
+
+ CodeInsightTestData data = (CodeInsightTestData) myTestDataAfter;
+
+ if (data.getColumnNumber() >= 0) {
+ assertEquals(dataName + ":caretColumn", data.getColumnNumber(), myEditor.getCaretModel().getLogicalPosition().column + 1);
+ }
+ if (data.getLineNumber() >= 0) {
+ assertEquals(dataName + ":caretLine", data.getLineNumber(), myEditor.getCaretModel().getLogicalPosition().line + 1);
+ }
+
+ int selectionStart = myEditor.getSelectionModel().getSelectionStart();
+ int selectionEnd = myEditor.getSelectionModel().getSelectionEnd();
+ LogicalPosition startPosition = myEditor.offsetToLogicalPosition(selectionStart);
+ LogicalPosition endPosition = myEditor.offsetToLogicalPosition(selectionEnd);
+
+ if (data.getSelectionStartColumnNumber() >= 0) {
+ assertEquals(dataName + ":selectionStartColumn", data.getSelectionStartColumnNumber(), startPosition.column + 1);
+ }
+ if (data.getSelectionStartLineNumber() >= 0) {
+ assertEquals(dataName + ":selectionStartLine", data.getSelectionStartLineNumber(), startPosition.line + 1);
+ }
+ if (data.getSelectionEndColumnNumber() >= 0) {
+ assertEquals(dataName + ":selectionEndColumn", data.getSelectionEndColumnNumber(), endPosition.column + 1);
+ }
+ if (data.getSelectionEndLineNumber() >= 0) {
+ assertEquals(dataName + ":selectionEndLine", data.getSelectionEndLineNumber(), endPosition.line + 1);
+ }
+ }
+
+ @Override
+ public Object getData(String dataId) {
+ return PlatformDataKeys.EDITOR.is(dataId) ? myEditor : super.getData(dataId);
+ }
+
+ protected VirtualFile getVirtualFile(@NonNls String filePath) {
+ String fullPath = getTestDataPath() + filePath;
+
+ final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
+ assertNotNull("file " + fullPath + " not found", vFile);
+ return vFile;
+ }
+
+ protected String getTestRoot(){
+ return FileUtil.toSystemIndependentName(getTestDataPath());
+ }
+
+ public Editor getEditor() {
+ return myEditor;
+ }
+
+ protected void type(char c) {
+ type(c, getEditor());
+ }
+
+ protected static void type(char c, Editor editor) {
+ EditorActionManager actionManager = EditorActionManager.getInstance();
+ DataContext dataContext = DataManager.getInstance().getDataContext();
+ if (c == '\n') {
+ actionManager.getActionHandler(IdeActions.ACTION_EDITOR_ENTER).execute(editor, dataContext);
+ return;
+ }
+ TypedAction action = actionManager.getTypedAction();
+ action.actionPerformed(editor, c, dataContext);
+ }
+
+ protected void caretRight() {
+ EditorActionManager actionManager = EditorActionManager.getInstance();
+ EditorActionHandler action = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT);
+ action.execute(getEditor(), DataManager.getInstance().getDataContext());
+ }
+ protected void caretUp() {
+ EditorActionManager actionManager = EditorActionManager.getInstance();
+ EditorActionHandler action = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_UP);
+ action.execute(getEditor(), DataManager.getInstance().getDataContext());
+ }
+ protected void deleteLine() {
+ EditorActionManager actionManager = EditorActionManager.getInstance();
+ EditorActionHandler action = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_DELETE_LINE);
+ action.execute(getEditor(), DataManager.getInstance().getDataContext());
+ }
+
+ protected void type(@NonNls String s) {
+ for (char c : s.toCharArray()) {
+ type(c);
+ }
+ }
+
+ protected void undo() {
+ UndoManager undoManager = UndoManager.getInstance(myProject);
+ TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(getEditor());
+ undoManager.undo(textEditor);
+ }
+
+ protected void backspace() {
+ backspace(getEditor());
+ }
+ protected void backspace(final Editor editor) {
+ CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
+ @Override
+ public void run() {
+ EditorActionManager actionManager = EditorActionManager.getInstance();
+ EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE);
+
+ actionHandler.execute(editor, DataManager.getInstance().getDataContext());
+ }
+ }, "backspace", editor.getDocument());
+ }
+
+ protected void ctrlShiftF7() {
+ HighlightUsagesHandler.invoke(getProject(), getEditor(), getFile());
+ }
+
+ public static void ctrlW() {
+ AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_SELECT_WORD_AT_CARET);
+ DataContext dataContext = DataManager.getInstance().getDataContext();
+ AnActionEvent event = new AnActionEvent(null, dataContext, "", action.getTemplatePresentation(), ActionManager.getInstance(), 0);
+ event.setInjectedContext(true);
+ action.actionPerformed(event);
+ }
+
+ public static void ctrlD() {
+ AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_DUPLICATE);
+ DataContext dataContext = DataManager.getInstance().getDataContext();
+ AnActionEvent event = new AnActionEvent(null, dataContext, "", action.getTemplatePresentation(), ActionManager.getInstance(), 0);
+ event.setInjectedContext(true);
+ action.actionPerformed(event);
+ }
+
+ @NotNull
+ protected PsiClass findClass(@NotNull @NonNls final String name) {
+ final PsiClass aClass = myJavaFacade.findClass(name, ProjectScope.getProjectScope(getProject()));
+ assertNotNull("Class " + name + " not found", aClass);
+ return aClass;
+ }
+
+ @NotNull
+ protected PsiPackage findPackage(@NotNull @NonNls final String name) {
+ final PsiPackage aPackage = myJavaFacade.findPackage(name);
+ assertNotNull("Package " + name + " not found", aPackage);
+ return aPackage;
+ }
+
+ protected void delete(@NotNull final Editor editor) {
+ CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
+ @Override
+ public void run() {
+ EditorActionManager actionManager = EditorActionManager.getInstance();
+ EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_DELETE);
+
+ actionHandler.execute(editor, DataManager.getInstance().getDataContext());
+ }
+ }, "delete", editor.getDocument());
+ }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestData.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestData.java
new file mode 100644
index 0000000..202db1b
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestData.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2009 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.codeInsight;
+
+import com.intellij.testFramework.PsiTestData;
+
+/**
+ * @author Mike
+ */
+public class CodeInsightTestData extends PsiTestData{
+ public int LINE_NUMBER = -1;
+ public int COLUMN_NUMBER = -1;
+ public int SELECTION_START_LINE_NUMBER = -1;
+ public int SELECTION_START_COLUMN_NUMBER = -1;
+ public int SELECTION_END_LINE_NUMBER = -1;
+ public int SELECTION_END_COLUMN_NUMBER = -1;
+
+ public CodeInsightTestData() {
+ }
+
+ public int getLineNumber() {
+ return LINE_NUMBER;
+ }
+
+ public int getColumnNumber() {
+ return COLUMN_NUMBER;
+ }
+
+ public int getSelectionStartLineNumber() {
+ return SELECTION_START_LINE_NUMBER;
+ }
+
+ public int getSelectionStartColumnNumber() {
+ return SELECTION_START_COLUMN_NUMBER;
+ }
+
+ public int getSelectionEndLineNumber() {
+ return SELECTION_END_LINE_NUMBER;
+ }
+
+ public int getSelectionEndColumnNumber() {
+ return SELECTION_END_COLUMN_NUMBER;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/EditorInfo.java b/java/testFramework/src/com/intellij/codeInsight/EditorInfo.java
new file mode 100644
index 0000000..d770d7e
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/EditorInfo.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2009 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.codeInsight;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.*;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author cdr
+ */
+public class EditorInfo {
+ @NonNls public static final String CARET_MARKER = "<caret>";
+ @NonNls public static final String SELECTION_START_MARKER = "<selection>";
+ @NonNls public static final String SELECTION_END_MARKER = "</selection>";
+
+ String newFileText = null;
+ public RangeMarker caretMarker = null;
+ RangeMarker selStartMarker = null;
+ RangeMarker selEndMarker = null;
+
+ public EditorInfo(final String fileText) {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ updateCaretAndSelection(EditorFactory.getInstance().createDocument(fileText));
+ }
+ });
+ }
+
+ private boolean updateCaretAndSelection(final Document document) {
+ newFileText = document.getText();
+
+ int caretIndex = newFileText.indexOf(CARET_MARKER);
+ int selStartIndex = newFileText.indexOf(SELECTION_START_MARKER);
+ int selEndIndex = newFileText.indexOf(SELECTION_END_MARKER);
+
+ caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
+ selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
+ selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
+
+ if (caretMarker != null) {
+ document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
+ }
+ if (selStartMarker != null) {
+ document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
+ }
+ if (selEndMarker != null) {
+ document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
+ }
+
+ newFileText = document.getText();
+ return caretMarker != null || selStartMarker != null || selEndMarker != null;
+ }
+
+ public String getNewFileText() {
+ return newFileText;
+ }
+
+ public void applyToEditor(Editor editor) {
+ if (caretMarker != null) {
+ int caretLine = StringUtil.offsetToLineNumber(newFileText, caretMarker.getStartOffset());
+ int caretCol = caretMarker.getStartOffset() - StringUtil.lineColToOffset(newFileText, caretLine, 0);
+ LogicalPosition pos = new LogicalPosition(caretLine, caretCol);
+ editor.getCaretModel().moveToLogicalPosition(pos);
+ }
+
+ if (selStartMarker != null) {
+ editor.getSelectionModel().setSelection(selStartMarker.getStartOffset(), selEndMarker.getStartOffset());
+ }
+ }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy
new file mode 100644
index 0000000..9a05e8d
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2010 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.codeInsight.completion
+
+import com.intellij.codeInsight.lookup.LookupManager
+import com.intellij.codeInsight.lookup.impl.LookupImpl
+import com.intellij.testFramework.fixtures.CompletionAutoPopupTester
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
+/**
+ * @author peter
+ */
+abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCase {
+ protected CompletionAutoPopupTester myTester
+
+ @Override protected void setUp() {
+ super.setUp()
+ myTester = new CompletionAutoPopupTester(myFixture)
+ }
+
+ void type(String s) {
+ myTester.typeWithPauses(s)
+ }
+
+ @Override protected boolean runInDispatchThread() {
+ return false;
+ }
+
+ @Override protected void invokeTestRunnable(Runnable runnable) {
+ myTester.runWithAutoPopupEnabled(runnable)
+ }
+
+ LookupImpl getLookup() {
+ (LookupImpl)LookupManager.getActiveLookup(myFixture.getEditor())
+ }
+
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/completion/CompletionTestCase.java b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionTestCase.java
new file mode 100644
index 0000000..714408d
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionTestCase.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2000-2011 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.codeInsight.completion;
+
+import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupManager;
+import com.intellij.codeInsight.lookup.impl.LookupImpl;
+import com.intellij.testFramework.PlatformTestCase;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author mike
+ */
+@PlatformTestCase.WrapInCommand
+public abstract class CompletionTestCase extends DaemonAnalyzerTestCase {
+ protected String myPrefix;
+ protected LookupElement[] myItems;
+ private CompletionType myType = CompletionType.BASIC;
+
+ @Override
+ protected void tearDown() throws Exception {
+ try {
+ LookupManager.getInstance(myProject).hideActiveLookup();
+ }
+ finally {
+ super.tearDown();
+ }
+ myItems = null;
+ }
+
+ @Override
+ protected void configureByFile(String filePath) throws Exception {
+ super.configureByFile(filePath);
+
+ complete();
+ }
+
+ protected void configureByFileNoCompletion(String filePath) throws Exception {
+ super.configureByFile(filePath);
+ }
+
+ protected void complete() {
+ complete(1);
+ }
+
+ protected void complete(final int time) {
+ new CodeCompletionHandlerBase(myType).invokeCompletion(myProject, myEditor, time);
+
+ LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
+ myItems = lookup == null ? null : lookup.getItems().toArray(new LookupElement[lookup.getItems().size()]);
+ myPrefix = lookup == null ? "" : lookup.itemPattern(lookup.getItems().get(0));
+ }
+
+ public void setType(CompletionType type) {
+ myType = type;
+ }
+
+ protected void selectItem(LookupElement item, char ch) {
+ final LookupImpl lookup = (LookupImpl)LookupManager.getInstance(myProject).getActiveLookup();
+ assert lookup != null;
+ lookup.setCurrentItem(item);
+ lookup.finishLookup(ch);
+ }
+
+ protected void selectItem(LookupElement item) {
+ selectItem(item, (char)0);
+ }
+
+ protected void doTestByCount(int finalCount, String... values) {
+ int index = 0;
+ if (myItems == null) {
+ assertEquals(0, finalCount);
+ return;
+ }
+ for (final LookupElement myItem : myItems) {
+ for (String value : values) {
+ if (value == null) {
+ assertFalse("Unacceptable value reached", true);
+ }
+ if (value.equals(myItem.getLookupString())) {
+ index++;
+ break;
+ }
+ }
+ }
+ assertEquals(Arrays.toString(myItems), finalCount, index);
+ }
+
+ @Nullable
+ protected LookupImpl getActiveLookup() {
+ return (LookupImpl)LookupManager.getActiveLookup(myEditor);
+ }
+
+ protected void assertStringItems(String... strings) {
+ assertNotNull(myItems);
+ List<String> actual = ContainerUtil.map(myItems, new Function<LookupElement, String>() {
+ @Override
+ public String fun(LookupElement element) {
+ return element.getLookupString();
+ }
+ });
+ assertOrderedEquals(actual, strings);
+ }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/completion/LightCompletionTestCase.java b/java/testFramework/src/com/intellij/codeInsight/completion/LightCompletionTestCase.java
new file mode 100644
index 0000000..5f435b0
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/completion/LightCompletionTestCase.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2000-2011 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.codeInsight.completion;
+
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupManager;
+import com.intellij.codeInsight.lookup.impl.LookupImpl;
+import com.intellij.testFramework.LightCodeInsightTestCase;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * @author mike
+ */
+public abstract class LightCompletionTestCase extends LightCodeInsightTestCase {
+ protected String myPrefix;
+ protected LookupElement[] myItems;
+ private CompletionType myType = CompletionType.BASIC;
+
+ @Override
+ protected void tearDown() throws Exception {
+ LookupManager.getInstance(getProject()).hideActiveLookup();
+ super.tearDown();
+ }
+
+ @Override
+ protected void configureByFile(@NotNull String filePath) {
+ super.configureByFile(filePath);
+
+ complete();
+ }
+
+ protected void configureByFileNoComplete(String filePath) throws Exception {
+ super.configureByFile(filePath);
+ }
+
+ protected void complete() {
+ complete(1);
+ }
+
+ protected void complete(final int time) {
+ new CodeCompletionHandlerBase(myType).invokeCompletion(getProject(), getEditor(), time);
+
+ LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
+ myItems = lookup == null ? null : lookup.getItems().toArray(LookupElement.EMPTY_ARRAY);
+ myPrefix = lookup == null ? null : lookup.itemPattern(lookup.getItems().get(0));
+ }
+
+ public void setType(CompletionType type) {
+ myType = type;
+ }
+
+ protected void selectItem(LookupElement item) {
+ selectItem(item, (char)0);
+ }
+
+ protected void selectItem(LookupElement item, char completionChar) {
+ final LookupImpl lookup = (LookupImpl)LookupManager.getInstance(getProject()).getActiveLookup();
+ lookup.setCurrentItem(item);
+ if (completionChar == 0 || completionChar == '\n' || completionChar == '\t') {
+ lookup.finishLookup(completionChar);
+ } else {
+ type(completionChar);
+ }
+ }
+
+ protected void testByCount(int finalCount, @NonNls String... values) {
+ if (myItems == null) {
+ assertEquals(finalCount, 0);
+ return;
+ }
+ int index = 0;
+ for (final LookupElement myItem : myItems) {
+ for (String value : values) {
+ if (value == null) {
+ assertFalse("Unacceptable value reached: " + myItem.getLookupString(), true);
+ }
+ if (value.equals(myItem.getLookupString())) {
+ index++;
+ break;
+ }
+ }
+ }
+ assertEquals(finalCount, index);
+ }
+
+ protected void assertStringItems(@NonNls String... items) {
+ assertOrderedEquals(getLookupStrings(new ArrayList<String>()), items);
+ }
+
+ protected void assertContainsItems(final String... expected) {
+ final Set<String> actual = getLookupStrings(new HashSet<String>());
+ for (String s : expected) {
+ assertTrue("Expected '" + s + "' not found in " + actual,
+ actual.contains(s));
+ }
+ }
+
+ protected void assertNotContainItems(final String... unexpected) {
+ final Set<String> actual = getLookupStrings(new HashSet<String>());
+ for (String s : unexpected) {
+ assertFalse("Unexpected '" + s + "' presented in " + actual,
+ actual.contains(s));
+ }
+ }
+
+ private <T extends Collection<String>> T getLookupStrings(T actual) {
+ if (myItems != null) {
+ for (LookupElement lookupElement : myItems) {
+ actual.add(lookupElement.getLookupString());
+ }
+ }
+ return actual;
+ }
+
+ protected static LookupImpl getLookup() {
+ return (LookupImpl)LookupManager.getActiveLookup(myEditor);
+ }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java
new file mode 100644
index 0000000..ae80acc
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java
@@ -0,0 +1,481 @@
+/*
+ * Copyright 2000-2012 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.codeInsight.daemon;
+
+import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.codeHighlighting.Pass;
+import com.intellij.codeInsight.CodeInsightTestCase;
+import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
+import com.intellij.codeInsight.daemon.impl.HighlightInfo;
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInsight.intention.IntentionManager;
+import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.intellij.codeInspection.InspectionToolProvider;
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.codeInspection.ModifiableModel;
+import com.intellij.codeInspection.ex.*;
+import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.ide.startup.StartupManagerEx;
+import com.intellij.ide.startup.impl.StartupManagerImpl;
+import com.intellij.lang.ExternalAnnotatorsFilter;
+import com.intellij.lang.LanguageAnnotators;
+import com.intellij.lang.StdLanguages;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.lang.injection.InjectedLanguageManager;
+import com.intellij.lang.java.JavaLanguage;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.*;
+import com.intellij.profile.codeInspection.InspectionProfileManager;
+import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.JavaPsiFacadeEx;
+import com.intellij.psi.impl.cache.CacheManager;
+import com.intellij.psi.impl.search.IndexPatternBuilder;
+import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
+import com.intellij.psi.impl.source.tree.TreeElement;
+import com.intellij.psi.impl.source.tree.TreeUtil;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.UsageSearchContext;
+import com.intellij.psi.xml.XmlFileNSInfoProvider;
+import com.intellij.testFramework.ExpectedHighlightingData;
+import com.intellij.testFramework.FileTreeAccessFilter;
+import com.intellij.testFramework.HighlightTestInfo;
+import com.intellij.testFramework.LightPlatformTestCase;
+import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.xml.XmlSchemaProvider;
+import gnu.trove.THashMap;
+import gnu.trove.TIntArrayList;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
+ private final Map<String, InspectionToolWrapper> myAvailableTools = new THashMap<String, InspectionToolWrapper>();
+ private final FileTreeAccessFilter myFileTreeAccessFilter = new FileTreeAccessFilter();
+
+ @Override
+ protected boolean isRunInWriteAction() {
+ return false;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final LocalInspectionTool[] tools = configureLocalInspectionTools();
+ for (LocalInspectionTool tool : tools) {
+ enableInspectionTool(tool);
+ }
+
+ final InspectionProfileImpl profile = new InspectionProfileImpl(LightPlatformTestCase.PROFILE) {
+ @Override
+ @NotNull
+ public ModifiableModel getModifiableModel() {
+ mySource = this;
+ return this;
+ }
+
+ @Override
+ @NotNull
+ public InspectionTool[] getInspectionTools(PsiElement element) {
+ Collection<InspectionToolWrapper> values = myAvailableTools.values();
+ return values.toArray(new InspectionTool[values.size()]);
+ }
+
+ @Override
+ public List<ToolsImpl> getAllEnabledInspectionTools(Project project) {
+ List<ToolsImpl> result = new ArrayList<ToolsImpl>();
+ for (InspectionProfileEntry entry : getInspectionTools(null)) {
+ result.add(new ToolsImpl(entry, entry.getDefaultLevel(), true));
+ }
+ return result;
+ }
+
+ @Override
+ public boolean isToolEnabled(HighlightDisplayKey key, PsiElement element) {
+ return key != null && myAvailableTools.containsKey(key.toString());
+ }
+
+ @Override
+ public HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey key, PsiElement element) {
+ final InspectionProfileEntry localInspectionTool = myAvailableTools.get(key.toString());
+ return localInspectionTool != null ? localInspectionTool.getDefaultLevel() : HighlightDisplayLevel.WARNING;
+ }
+
+ @Override
+ public InspectionTool getInspectionTool(@NotNull String shortName, @NotNull PsiElement element) {
+ return myAvailableTools.get(shortName);
+ }
+ };
+ final InspectionProfileManager inspectionProfileManager = InspectionProfileManager.getInstance();
+ inspectionProfileManager.addProfile(profile);
+ inspectionProfileManager.setRootProfile(LightPlatformTestCase.PROFILE);
+ Disposer.register(getProject(), new Disposable() {
+ @Override
+ public void dispose() {
+ inspectionProfileManager.deleteProfile(LightPlatformTestCase.PROFILE);
+ }
+ });
+ InspectionProjectProfileManager.getInstance(getProject()).updateProfile(profile);
+ InspectionProjectProfileManager.getInstance(getProject()).setProjectProfile(profile.getName());
+ DaemonCodeAnalyzerImpl daemonCodeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject());
+ daemonCodeAnalyzer.prepareForTest();
+ final StartupManagerImpl startupManager = (StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject());
+ startupManager.runStartupActivities();
+ startupManager.startCacheUpdate();
+ startupManager.runPostStartupActivities();
+ DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
+
+ if (isPerformanceTest()) {
+ IntentionManager.getInstance().getAvailableIntentionActions(); // hack to avoid slowdowns in PyExtensionFactory
+ PathManagerEx.getTestDataPath(); // to cache stuff
+ ReferenceProvidersRegistry.getInstance(); // pre-load tons of classes
+ InjectedLanguageManager.getInstance(getProject()); // zillion of Dom Sem classes
+ LanguageAnnotators.INSTANCE.allForLanguage(JavaLanguage.INSTANCE); // pile of annotator classes loads
+ LanguageAnnotators.INSTANCE.allForLanguage(StdLanguages.XML);
+ ProblemHighlightFilter.EP_NAME.getExtensions();
+ Extensions.getExtensions(ImplicitUsageProvider.EP_NAME);
+ Extensions.getExtensions(XmlSchemaProvider.EP_NAME);
+ Extensions.getExtensions(XmlFileNSInfoProvider.EP_NAME);
+ Extensions.getExtensions(ExternalAnnotatorsFilter.EXTENSION_POINT_NAME);
+ Extensions.getExtensions(IndexPatternBuilder.EP_NAME);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ ((StartupManagerImpl)StartupManager.getInstance(getProject())).checkCleared();
+ ((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest(!LightPlatformTestCase.isLight(getProject()));
+ super.tearDown();
+ //((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).assertPointersDisposed();
+ }
+
+ protected void enableInspectionTool(InspectionProfileEntry tool){
+ InspectionToolWrapper wrapper = InspectionToolRegistrar.wrapTool(tool);
+ final String shortName = wrapper.getShortName();
+ final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
+ if (key == null) {
+ HighlightDisplayKey.register(shortName, wrapper.getDisplayName(), ((LocalInspectionToolWrapper)wrapper).getID());
+ }
+ myAvailableTools.put(shortName, wrapper);
+ }
+
+ protected void enableInspectionToolsFromProvider(InspectionToolProvider toolProvider){
+ try {
+ for(Class c:toolProvider.getInspectionClasses()) {
+ enableInspectionTool((LocalInspectionTool)c.newInstance());
+ }
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected void disableInspectionTool(String shortName){
+ myAvailableTools.remove(shortName);
+ }
+
+ protected LocalInspectionTool[] configureLocalInspectionTools() {
+ return LocalInspectionTool.EMPTY_ARRAY;
+ }
+
+ protected static LocalInspectionTool[] createLocalInspectionTools(final InspectionToolProvider... provider) {
+ final ArrayList<LocalInspectionTool> result = new ArrayList<LocalInspectionTool>();
+ for (InspectionToolProvider toolProvider : provider) {
+ for (Class aClass : toolProvider.getInspectionClasses()) {
+ try {
+ final Object tool = aClass.newInstance();
+ assertTrue(tool instanceof LocalInspectionTool);
+ result.add((LocalInspectionTool)tool);
+ }
+ catch (Exception e) {
+ LOG.error(e);
+ }
+ }
+ }
+ return result.toArray(new LocalInspectionTool[result.size()]);
+ }
+
+ protected void doTest(@NonNls @NotNull String filePath, boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings) throws Exception {
+ configureByFile(filePath);
+ doDoTest(checkWarnings, checkInfos, checkWeakWarnings);
+ }
+
+ protected void doTest(@NonNls @NotNull String filePath, boolean checkWarnings, boolean checkInfos) throws Exception {
+ doTest(filePath, checkWarnings, checkInfos, false);
+ }
+
+ protected void doTest(@NonNls @NotNull String filePath, @NonNls String projectRoot, boolean checkWarnings, boolean checkInfos) throws Exception {
+ configureByFile(filePath, projectRoot);
+ doDoTest(checkWarnings, checkInfos);
+ }
+
+ @NotNull
+ @SuppressWarnings("TestMethodWithIncorrectSignature")
+ protected HighlightTestInfo testFile(@NonNls @NotNull String... filePath) {
+ return new HighlightTestInfo(getTestRootDisposable(), filePath){
+ @Override
+ public HighlightTestInfo doTest() throws Exception {
+ configureByFiles(projectRoot, filePaths);
+ ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
+ if (checkSymbolNames) data.checkSymbolNames();
+ checkHighlighting(data);
+ return this;
+ }
+ };
+ }
+
+ protected void doTest(@NotNull VirtualFile vFile, boolean checkWarnings, boolean checkInfos) throws Exception {
+ doTest(new VirtualFile[] { vFile }, checkWarnings, checkInfos );
+ }
+
+ protected void doTest(@NotNull VirtualFile[] vFile, boolean checkWarnings, boolean checkInfos) throws Exception {
+ configureByFiles(null, vFile);
+ doDoTest(checkWarnings, checkInfos);
+ }
+
+ protected void doTest(boolean checkWarnings, boolean checkInfos, String ... files) throws Exception {
+ configureByFiles(null, files);
+ doDoTest(checkWarnings, checkInfos);
+ }
+
+ @NotNull
+ protected Collection<HighlightInfo> doDoTest(boolean checkWarnings, boolean checkInfos) {
+ return doDoTest(checkWarnings, checkInfos, false);
+ }
+
+ protected Collection<HighlightInfo> doDoTest(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings) {
+ return checkHighlighting(new ExpectedHighlightingData(myEditor.getDocument(),checkWarnings, checkWeakWarnings, checkInfos, myFile));
+ }
+
+ @NotNull
+ protected Collection<HighlightInfo> checkHighlighting(@NotNull final ExpectedHighlightingData data) {
+ data.init();
+ PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+ //to load text
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ TreeUtil.clearCaches((TreeElement)myFile.getNode());
+ }
+ });
+
+
+ //to initialize caches
+ if (!DumbService.isDumb(getProject())) {
+ CacheManager.SERVICE.getInstance(myProject).getFilesWithWord("XXX", UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(myProject), true);
+ }
+ final JavaPsiFacadeEx facade = getJavaFacade();
+ if (facade != null) {
+ facade.setAssertOnFileLoadingFilter(myFileTreeAccessFilter); // check repository work
+ }
+
+ Collection<HighlightInfo> infos = doHighlighting();
+
+ if (facade != null) {
+ facade.setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
+ }
+
+ String text = myEditor.getDocument().getText();
+ data.checkLineMarkers(DaemonCodeAnalyzerImpl.getLineMarkers(getDocument(getFile()), getProject()), text);
+ data.checkResult(infos, text);
+ return infos;
+ }
+
+ public void allowTreeAccessForFile(@NotNull VirtualFile file) {
+ myFileTreeAccessFilter.allowTreeAccessForFile(file);
+ }
+
+ @NotNull
+ protected List<HighlightInfo> highlightErrors() {
+ return doHighlighting(HighlightSeverity.ERROR);
+ }
+
+ @NotNull
+ protected List<HighlightInfo> doHighlighting(@NotNull HighlightSeverity minSeverity) {
+ return filter(doHighlighting(), minSeverity);
+ }
+
+ @NotNull
+ protected List<HighlightInfo> doHighlighting() {
+ PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+ TIntArrayList toIgnore = new TIntArrayList();
+ if (!doTestLineMarkers()) {
+ toIgnore.add(Pass.UPDATE_OVERRIDEN_MARKERS);
+ toIgnore.add(Pass.VISIBLE_LINE_MARKERS);
+ toIgnore.add(Pass.LINE_MARKERS);
+ }
+
+ if (!doExternalValidation()) {
+ toIgnore.add(Pass.EXTERNAL_TOOLS);
+ }
+ if (forceExternalValidation()) {
+ toIgnore.add(Pass.LINE_MARKERS);
+ toIgnore.add(Pass.LOCAL_INSPECTIONS);
+ toIgnore.add(Pass.POPUP_HINTS);
+ toIgnore.add(Pass.POST_UPDATE_ALL);
+ toIgnore.add(Pass.UPDATE_ALL);
+ toIgnore.add(Pass.UPDATE_OVERRIDEN_MARKERS);
+ toIgnore.add(Pass.VISIBLE_LINE_MARKERS);
+ }
+
+ boolean canChange = canChangeDocumentDuringHighlighting();
+ List<HighlightInfo> infos = CodeInsightTestFixtureImpl.instantiateAndRun(getFile(), getEditor(), toIgnore.toNativeArray(), canChange);
+
+ if (!canChange) {
+ Document document = getDocument(getFile());
+ ((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).getFileStatusMap().assertAllDirtyScopesAreNull(document);
+ }
+
+ return infos;
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ElementType.METHOD, ElementType.TYPE})
+ public @interface CanChangeDocumentDuringHighlighting {}
+
+ private boolean canChangeDocumentDuringHighlighting() {
+ return annotatedWith(CanChangeDocumentDuringHighlighting.class);
+ }
+
+ @NotNull
+ public static List<HighlightInfo> filter(@NotNull List<HighlightInfo> infos, @NotNull HighlightSeverity minSeverity) {
+ ArrayList<HighlightInfo> result = new ArrayList<HighlightInfo>();
+ for (final HighlightInfo info : infos) {
+ if (info.getSeverity().compareTo(minSeverity) >= 0) result.add(info);
+ }
+ return result;
+ }
+
+ protected boolean doTestLineMarkers() {
+ return false;
+ }
+
+ protected boolean doExternalValidation() {
+ return true;
+ }
+
+ protected boolean forceExternalValidation() {
+ return false;
+ }
+
+ protected static void findAndInvokeIntentionAction(@NotNull Collection<HighlightInfo> infos, @NotNull String intentionActionName, @NotNull Editor editor,
+ @NotNull PsiFile file) throws IncorrectOperationException {
+ IntentionAction intentionAction = findIntentionAction(infos, intentionActionName, editor, file);
+
+ assertNotNull(intentionActionName, intentionAction);
+ assertTrue(ShowIntentionActionsHandler.chooseActionAndInvoke(file, editor, intentionAction, intentionActionName));
+ }
+
+ protected static IntentionAction findIntentionAction(@NotNull Collection<HighlightInfo> infos, @NotNull String intentionActionName, @NotNull Editor editor,
+ @NotNull PsiFile file) {
+ List<IntentionAction> actions = LightQuickFixTestCase.getAvailableActions(editor, file);
+ IntentionAction intentionAction = LightQuickFixTestCase.findActionWithText(actions, intentionActionName);
+
+ if (intentionAction == null) {
+ final List<IntentionAction> availableActions = new ArrayList<IntentionAction>();
+
+ for (HighlightInfo info :infos) {
+ if (info.quickFixActionRanges != null) {
+ for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
+ IntentionAction action = pair.first.getAction();
+ if (action.isAvailable(file.getProject(), editor, file)) availableActions.add(action);
+ }
+ }
+ }
+
+ intentionAction = LightQuickFixTestCase.findActionWithText(
+ availableActions,
+ intentionActionName
+ );
+ }
+ return intentionAction;
+ }
+
+ public void checkHighlighting(Editor editor, boolean checkWarnings, boolean checkInfos) {
+ setActiveEditor(editor);
+ doDoTest(checkWarnings, checkInfos);
+ }
+
+ public PsiClass createClass(String text) throws IOException {
+ return createClass(myModule, text);
+ }
+
+ protected PsiClass createClass(final Module module, final String text) throws IOException {
+ return new WriteCommandAction<PsiClass>(getProject()) {
+ @Override
+ protected void run(Result<PsiClass> result) throws Throwable {
+ final PsiFileFactory factory = PsiFileFactory.getInstance(getProject());
+ final PsiJavaFile javaFile = (PsiJavaFile)factory.createFileFromText("a.java", JavaFileType.INSTANCE, text);
+ final String qname = javaFile.getClasses()[0].getQualifiedName();
+ assertNotNull(qname);
+ final VirtualFile[] files = ModuleRootManager.getInstance(module).getSourceRoots();
+ File dir;
+ if (files.length > 0) {
+ dir = VfsUtilCore.virtualToIoFile(files[0]);
+ }
+ else {
+ dir = createTempDirectory();
+ VirtualFile vDir =
+ LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/'));
+ addSourceContentToRoots(module, vDir);
+ }
+
+ File file = new File(dir, qname.replace('.', '/') + ".java");
+ FileUtil.createIfDoesntExist(file);
+ VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(file.getCanonicalPath().replace(File.separatorChar, '/'));
+ assertNotNull(vFile);
+ VfsUtil.saveText(vFile, text);
+ PsiJavaFile psiFile = (PsiJavaFile)myPsiManager.findFile(vFile);
+ assertNotNull(psiFile);
+ PsiClass psiClass = psiFile.getClasses()[0];
+ result.setResult(psiClass);
+
+ }
+ }.execute().throwException().getResultObject();
+ }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java
new file mode 100644
index 0000000..2cc216d
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2000-2012 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.codeInsight.daemon;
+
+import com.intellij.codeHighlighting.Pass;
+import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
+import com.intellij.codeInsight.daemon.impl.HighlightInfo;
+import com.intellij.injected.editor.EditorWindow;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.vfs.VirtualFileFilter;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
+import com.intellij.testFramework.ExpectedHighlightingData;
+import com.intellij.testFramework.FileTreeAccessFilter;
+import com.intellij.testFramework.HighlightTestInfo;
+import com.intellij.testFramework.LightCodeInsightTestCase;
+import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+
+public abstract class LightDaemonAnalyzerTestCase extends LightCodeInsightTestCase {
+ private final FileTreeAccessFilter myJavaFilesFilter = new FileTreeAccessFilter();
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ ((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).prepareForTest();
+ DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ ((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest(!isLight(getProject()));
+ super.tearDown();
+ }
+
+ @Override
+ protected void runTest() throws Throwable {
+ final Throwable[] throwable = {null};
+ CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
+ @Override
+ public void run() {
+ try {
+ doRunTest();
+ }
+ catch (Throwable t) {
+ throwable[0] = t;
+ }
+ }
+ }, "", null);
+ if (throwable[0] != null) {
+ throw throwable[0];
+ }
+ }
+
+ protected void doTest(@NonNls String filePath, boolean checkWarnings, boolean checkInfos) {
+ configureByFile(filePath);
+ doTestConfiguredFile(checkWarnings, checkInfos, filePath);
+ }
+
+ protected void doTest(@NonNls String filePath, boolean checkWarnings, boolean checkWeakWarnings, boolean checkInfos) {
+ configureByFile(filePath);
+ doTestConfiguredFile(checkWarnings, checkWeakWarnings, checkInfos, filePath);
+ }
+
+ protected void doTestConfiguredFile(boolean checkWarnings, boolean checkInfos, @Nullable String filePath) {
+ doTestConfiguredFile(checkWarnings, false, checkInfos, filePath);
+ }
+
+ protected void doTestConfiguredFile(boolean checkWarnings, boolean checkWeakWarnings, boolean checkInfos, @Nullable String filePath) {
+ getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
+
+ ExpectedHighlightingData data = new ExpectedHighlightingData(getEditor().getDocument(), checkWarnings, checkWeakWarnings, checkInfos);
+ checkHighlighting(data, composeLocalPath(filePath));
+ }
+
+ @Nullable
+ private String composeLocalPath(@Nullable String filePath) {
+ return filePath != null ? getTestDataPath() + "/" + filePath : null;
+ }
+
+ private void checkHighlighting(ExpectedHighlightingData data, String filePath) {
+ data.init();
+
+ PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+ getFile().getText(); //to load text
+ myJavaFilesFilter.allowTreeAccessForFile(getVFile());
+ getJavaFacade().setAssertOnFileLoadingFilter(myJavaFilesFilter); // check repository work
+
+ Collection<HighlightInfo> infos = doHighlighting();
+
+ getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
+
+ data.checkResult(infos, getEditor().getDocument().getText(), filePath);
+ }
+
+ protected HighlightTestInfo doTestFile(@NonNls @NotNull String filePath) {
+ return new HighlightTestInfo(getTestRootDisposable(), filePath){
+ @Override
+ public HighlightTestInfo doTest() throws Exception {
+ String path = assertOneElement(filePaths);
+ configureByFile(path);
+ ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
+ if (checkSymbolNames) data.checkSymbolNames();
+
+ checkHighlighting(data, composeLocalPath(path));
+ return this;
+ }
+ };
+ }
+
+ @NotNull
+ protected List<HighlightInfo> highlightErrors() {
+ return doHighlighting(HighlightSeverity.ERROR);
+ }
+
+ @NotNull
+ protected List<HighlightInfo> doHighlighting() {
+ PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+
+ int[] toIgnore = doFolding() ? ArrayUtil.EMPTY_INT_ARRAY : new int[]{Pass.UPDATE_FOLDING};
+ Editor editor = getEditor();
+ PsiFile file = getFile();
+ if (editor instanceof EditorWindow) {
+ editor = ((EditorWindow)editor).getDelegate();
+ file = InjectedLanguageUtil.getTopLevelFile(file);
+ }
+
+ return CodeInsightTestFixtureImpl.instantiateAndRun(file, editor, toIgnore, false);
+ }
+
+ protected List<HighlightInfo> doHighlighting(HighlightSeverity minSeverity) {
+ return DaemonAnalyzerTestCase.filter(doHighlighting(), minSeverity);
+ }
+
+ protected boolean doFolding() {
+ return false;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/LightIntentionActionTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/LightIntentionActionTestCase.java
new file mode 100644
index 0000000..9268189
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/LightIntentionActionTestCase.java
@@ -0,0 +1,6 @@
+package com.intellij.codeInsight.daemon;
+
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
+
+public abstract class LightIntentionActionTestCase extends LightQuickFixTestCase {
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java
new file mode 100644
index 0000000..9cf1c20
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2000-2011 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.codeInsight.daemon.quickFix;
+
+import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
+import com.intellij.codeInsight.daemon.impl.HighlightInfo;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
+import com.intellij.lang.Commenter;
+import com.intellij.lang.LanguageCommenters;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
+import com.intellij.rt.execution.junit.FileComparisonFailure;
+import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
+import com.intellij.testFramework.LightPlatformTestCase;
+import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ui.UIUtil;
+import org.intellij.lang.annotations.RegExp;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase {
+ @NonNls private static final String BEFORE_PREFIX = "before";
+ private static QuickFixTestCase myWrapper;
+
+ protected boolean shouldBeAvailableAfterExecution() {
+ return false;
+ }
+
+ protected Pair<String, Boolean> parseActionHintImpl(final PsiFile file, String contents) {
+ return parseActionHint(file, contents);
+ }
+
+ private static void doTestFor(final String testName, final QuickFixTestCase quickFixTestCase) {
+ final String relativePath = quickFixTestCase.getBasePath() + "/" + BEFORE_PREFIX + testName;
+ final String testFullPath = quickFixTestCase.getTestDataPath().replace(File.separatorChar, '/') + relativePath;
+ final File testFile = new File(testFullPath);
+ CommandProcessor.getInstance().executeCommand(quickFixTestCase.getProject(), new Runnable() {
+ @Override
+ public void run() {
+ try {
+ String contents = StringUtil.convertLineSeparators(FileUtil.loadFile(testFile, CharsetToolkit.UTF8));
+ quickFixTestCase.configureFromFileText(testFile.getName(), contents);
+ quickFixTestCase.bringRealEditorBack();
+ final Pair<String, Boolean> pair = quickFixTestCase.parseActionHintImpl(quickFixTestCase.getFile(), contents);
+ final String text = pair.getFirst();
+ final boolean actionShouldBeAvailable = pair.getSecond().booleanValue();
+
+ quickFixTestCase.beforeActionStarted(testName, contents);
+
+ try {
+ myWrapper = quickFixTestCase;
+ quickFixTestCase.doAction(text, actionShouldBeAvailable, testFullPath, testName);
+ }
+ finally {
+ myWrapper = null;
+ quickFixTestCase.afterActionCompleted(testName, contents);
+ }
+ }
+ catch (FileComparisonFailure e){
+ throw e;
+ }
+ catch (Throwable e) {
+ e.printStackTrace();
+ fail(testName);
+ }
+ }
+ }, "", "");
+ }
+
+ protected void afterActionCompleted(final String testName, final String contents) {
+ }
+
+ protected void beforeActionStarted(final String testName, final String contents) {
+ }
+
+ public static Pair<String, Boolean> parseActionHint(final PsiFile file, String contents) {
+ return parseActionHint(file, contents, " \"(.*)\" \"(true|false)\".*");
+ }
+
+ public static Pair<String, Boolean> parseActionHint(final PsiFile file, String contents, @NonNls @RegExp String actionPattern) {
+ PsiFile hostFile = InjectedLanguageUtil.getTopLevelFile(file);
+
+ final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(hostFile.getLanguage());
+ String comment = commenter.getLineCommentPrefix();
+ if (comment == null) {
+ comment = commenter.getBlockCommentPrefix();
+ }
+
+ // "quick fix action text to perform" "should be available"
+ Pattern pattern = Pattern.compile("^" + comment.replace("*", "\\*") + actionPattern, Pattern.DOTALL);
+ Matcher matcher = pattern.matcher(contents);
+ assertTrue("No comment found in "+file.getVirtualFile(), matcher.matches());
+ final String text = matcher.group(1);
+ final Boolean actionShouldBeAvailable = Boolean.valueOf(matcher.group(2));
+ return Pair.create(text, actionShouldBeAvailable);
+ }
+
+ @SuppressWarnings({"HardCodedStringLiteral"})
+ public static void doAction(final String text, final boolean actionShouldBeAvailable, final String testFullPath, final String testName,
+ QuickFixTestCase quickFix)
+ throws Exception {
+ IntentionAction action = quickFix.findActionWithText(text);
+ if (action == null) {
+ if (actionShouldBeAvailable) {
+ List<IntentionAction> actions = quickFix.getAvailableActions();
+ List<String> texts = new ArrayList<String>();
+ for (IntentionAction intentionAction : actions) {
+ texts.add(intentionAction.getText());
+ }
+ Collection<HighlightInfo> infos = quickFix.doHighlighting();
+ fail("Action with text '" + text + "' is not available in test " + testFullPath+"\nAvailable actions ("+texts.size()+"): "+texts+"\n"+actions+"\nInfos:"+infos);
+ }
+ }
+ else {
+ if (!actionShouldBeAvailable) {
+ fail("Action '" + text + "' is available (but must not) in test " + testFullPath);
+ }
+ quickFix.invoke(action);
+ UIUtil.dispatchAllInvocationEvents();
+ UIUtil.dispatchAllInvocationEvents();
+ if (!quickFix.shouldBeAvailableAfterExecution()) {
+ final IntentionAction afterAction = quickFix.findActionWithText(text);
+ if (afterAction != null) {
+ fail("Action '" + text + "' is still available after its invocation in test " + testFullPath);
+ }
+ }
+ final String expectedFilePath = quickFix.getBasePath() + "/after" + testName;
+ quickFix.checkResultByFile("In file :" + expectedFilePath, expectedFilePath, false);
+ }
+ }
+
+ protected void doAction(final String text, final boolean actionShouldBeAvailable, final String testFullPath, final String testName)
+ throws Exception {
+ doAction(text, actionShouldBeAvailable, testFullPath, testName, myWrapper);
+ }
+
+ protected void doAction(final String actionName) {
+ final List<IntentionAction> available = getAvailableActions();
+ final IntentionAction action = findActionWithText(available, actionName);
+ assertNotNull("Action '" + actionName + "' not found among " + available.toString(), action);
+ invoke(action);
+ }
+
+ protected static void invoke(IntentionAction action) throws IncorrectOperationException {
+ ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText());
+ }
+
+ protected IntentionAction findActionWithText(final String text) {
+ return findActionWithText(getAvailableActions(), text);
+ }
+
+ public static IntentionAction findActionWithText(final List<IntentionAction> actions, final String text) {
+ for (IntentionAction action : actions) {
+ if (text.equals(action.getText())) {
+ return action;
+ }
+ }
+ return null;
+ }
+
+ public static void doAllTests(QuickFixTestCase testCase) throws Exception {
+ assertNotNull("getBasePath() should not return null!", testCase.getBasePath());
+
+ final String testDirPath = testCase.getTestDataPath().replace(File.separatorChar, '/') + testCase.getBasePath();
+ File testDir = new File(testDirPath);
+ final File[] files = testDir.listFiles(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, @NonNls String name) {
+ return name.startsWith(BEFORE_PREFIX);
+ }
+ });
+
+ if (files == null) {
+ fail("Test files not found in " + testDirPath);
+ }
+
+ for (File file : files) {
+ final String testName = file.getName().substring(BEFORE_PREFIX.length());
+ doTestFor(testName, testCase);
+ System.out.println(file.getPath());
+ }
+ assertTrue("Test files not found in "+testDirPath,files.length != 0);
+ }
+
+ protected void doSingleTest(String fileSuffix) {
+ doTestFor(fileSuffix, createWrapper());
+ }
+
+ protected void doAllTests() throws Exception {
+ doAllTests(createWrapper());
+ }
+
+ private QuickFixTestCase createWrapper() {
+ return new QuickFixTestCase() {
+ @Override
+ public String getBasePath() {
+ return LightQuickFixTestCase.this.getBasePath();
+ }
+
+ @Override
+ public String getTestDataPath() {
+ return LightQuickFixTestCase.this.getTestDataPath();
+ }
+
+ @Override
+ public Pair<String, Boolean> parseActionHintImpl(PsiFile file, String contents) {
+ return LightQuickFixTestCase.this.parseActionHintImpl(file, contents);
+ }
+
+ @Override
+ public void beforeActionStarted(String testName, String contents) {
+ LightQuickFixTestCase.this.beforeActionStarted(testName, contents);
+ }
+
+ @Override
+ public void afterActionCompleted(String testName, String contents) {
+ LightQuickFixTestCase.this.afterActionCompleted(testName, contents);
+ }
+
+ @Override
+ public void doAction(String text, boolean actionShouldBeAvailable, String testFullPath, String testName) throws Exception {
+ LightQuickFixTestCase.this.doAction(text, actionShouldBeAvailable, testFullPath, testName);
+ }
+
+ @Override
+ public void checkResultByFile(String s, String expectedFilePath, boolean b) throws Exception {
+ LightQuickFixTestCase.this.checkResultByFile(s, expectedFilePath, b);
+ }
+
+ @Override
+ public IntentionAction findActionWithText(String text) {
+ return LightQuickFixTestCase.this.findActionWithText(text);
+ }
+
+ @Override
+ public boolean shouldBeAvailableAfterExecution() {
+ return LightQuickFixTestCase.this.shouldBeAvailableAfterExecution();
+ }
+
+ @Override
+ public void invoke(IntentionAction action) {
+ LightQuickFixTestCase.invoke(action);
+ }
+
+ @Override
+ public List<HighlightInfo> doHighlighting() {
+ return LightQuickFixTestCase.this.doHighlighting();
+ }
+
+ @Override
+ public List<IntentionAction> getAvailableActions() {
+ return LightQuickFixTestCase.this.getAvailableActions();
+ }
+
+ @Override
+ public void configureFromFileText(String name, String contents) throws IOException {
+ LightPlatformCodeInsightTestCase.configureFromFileText(name, contents);
+ }
+
+ @Override
+ public PsiFile getFile() {
+ return LightPlatformCodeInsightTestCase.getFile();
+ }
+
+ @Override
+ public Project getProject() {
+ return LightPlatformTestCase.getProject();
+ }
+
+ @Override
+ public void bringRealEditorBack() {
+ LightPlatformCodeInsightTestCase.bringRealEditorBack();
+ }
+ };
+ }
+
+ protected List<IntentionAction> getAvailableActions() {
+ doHighlighting();
+ return getAvailableActions(getEditor(), getFile());
+ }
+
+ public static List<IntentionAction> getAvailableActions(@NotNull Editor editor, @NotNull PsiFile file) {
+ return CodeInsightTestFixtureImpl.getAvailableIntentions(editor, file);
+ }
+
+ @NonNls protected String getBasePath() {return null;}
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/QuickFixTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/QuickFixTestCase.java
new file mode 100644
index 0000000..6134887
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/QuickFixTestCase.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2000-2009 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.codeInsight.daemon.quickFix;
+
+import com.intellij.codeInsight.daemon.impl.HighlightInfo;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiFile;
+
+import java.util.List;
+
+/**
+ * @author Maxim.Mossienko
+* Date: 22.01.2009
+* Time: 0:28:45
+*/
+public interface QuickFixTestCase {
+ String getBasePath();
+
+ String getTestDataPath();
+
+ Pair<String, Boolean> parseActionHintImpl(PsiFile file, String contents);
+
+ void beforeActionStarted(String testName, String contents);
+
+ void afterActionCompleted(String testName, String contents);
+
+ void doAction(String text, boolean actionShouldBeAvailable, String testFullPath, String testName) throws Exception;
+
+ void checkResultByFile(String s, String expectedFilePath, boolean b) throws Exception;
+
+ IntentionAction findActionWithText(String text);
+
+ boolean shouldBeAvailableAfterExecution();
+
+ void invoke(IntentionAction action);
+
+ List<HighlightInfo> doHighlighting();
+
+ List<IntentionAction> getAvailableActions();
+
+ void bringRealEditorBack();
+
+ void configureFromFileText(String name, String contents) throws Throwable;
+
+ PsiFile getFile();
+
+ Project getProject();
+}
diff --git a/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
new file mode 100644
index 0000000..6dcf778
--- /dev/null
+++ b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
@@ -0,0 +1,190 @@
+package com.intellij.ide.projectWizard;
+
+import com.intellij.ide.actions.ImportModuleAction;
+import com.intellij.ide.impl.NewProjectUtil;
+import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
+import com.intellij.ide.util.newProjectWizard.SelectTemplateStep;
+import com.intellij.ide.util.projectWizard.ModuleWizardStep;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkTypeId;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
+import com.intellij.openapi.roots.ui.configuration.actions.NewModuleAction;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.platform.ProjectTemplate;
+import com.intellij.projectImport.ProjectImportProvider;
+import com.intellij.testFramework.PlatformTestCase;
+import com.intellij.util.Consumer;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Dmitry Avdeev
+ * Date: 10/29/12
+ */
+public abstract class ProjectWizardTestCase extends PlatformTestCase {
+
+ protected final List<Sdk> mySdks = new ArrayList<Sdk>();
+ protected AddModuleWizard myWizard;
+ @Nullable
+ private Project myCreatedProject;
+
+ protected Project createProjectFromTemplate(String group, String name, @Nullable Consumer<ModuleWizardStep> adjuster) throws IOException {
+ runWizard(group, name, null, adjuster);
+ try {
+ myCreatedProject = NewProjectUtil.createFromWizard(myWizard, null);
+ }
+ catch (Throwable e) {
+ myCreatedProject = ContainerUtil.find(myProjectManager.getOpenProjects(), new Condition<Project>() {
+ @Override
+ public boolean value(Project project) {
+ return myWizard.getProjectName().equals(project.getName());
+ }
+ });
+ throw new RuntimeException(e);
+ }
+ assertNotNull(myCreatedProject);
+ UIUtil.dispatchAllInvocationEvents();
+
+ Project[] projects = myProjectManager.getOpenProjects();
+ assertEquals(2, projects.length);
+ return myCreatedProject;
+ }
+
+ @Nullable
+ protected Module createModuleFromTemplate(String group, String name, @Nullable Consumer<ModuleWizardStep> adjuster) throws IOException {
+ runWizard(group, name, getProject(), adjuster);
+ return createModuleFromWizard();
+ }
+
+ protected Module createModuleFromWizard() {
+ return new NewModuleAction().createModuleFromWizard(myProject, null, myWizard);
+ }
+
+ protected void runWizard(String group, String name, Project project, @Nullable Consumer<ModuleWizardStep> adjuster) throws IOException {
+
+ createWizard(project);
+ SelectTemplateStep step = (SelectTemplateStep)myWizard.getCurrentStepObject();
+ boolean condition = step.setSelectedTemplate(group, name);
+ if (!condition) {
+ throw new IllegalArgumentException(group + "/" + name + " template not found");
+ }
+ ProjectTemplate template = step.getSelectedTemplate();
+ assertNotNull(template);
+
+ if (adjuster != null) {
+ adjuster.consume(step);
+ }
+
+ runWizard(adjuster);
+ }
+
+ protected void createWizard(Project project) throws IOException {
+ File directory = FileUtil.createTempDirectory(getName(), "new", false);
+ myFilesToDelete.add(directory);
+ myWizard = new AddModuleWizard(project, DefaultModulesProvider.createForProject(project), directory.getPath());
+ UIUtil.dispatchAllInvocationEvents(); // to make default selection applied
+ }
+
+ protected void runWizard(Consumer<ModuleWizardStep> adjuster) {
+ while (!myWizard.isLast()) {
+ myWizard.doNextAction();
+ if (adjuster != null) {
+ adjuster.consume(myWizard.getCurrentStepObject());
+ }
+ }
+ myWizard.doOk();
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ Sdk projectSdk = ProjectRootManager.getInstance(getProject()).getProjectSdk();
+ Sdk[] jdks = ProjectJdkTable.getInstance().getAllJdks();
+ for (final Sdk jdk : jdks) {
+ if (projectSdk != jdk) {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ public void run() {
+ ProjectJdkTable.getInstance().removeJdk(jdk);
+ }
+ });
+ }
+ }
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ if (myWizard != null) {
+ Disposer.dispose(myWizard.getDisposable());
+ }
+ if (myCreatedProject != null) {
+ myProjectManager.closeProject(myCreatedProject);
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ Disposer.dispose(myCreatedProject);
+ }
+ });
+ }
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ public void run() {
+ for (Sdk sdk : mySdks) {
+ ProjectJdkTable.getInstance().removeJdk(sdk);
+ }
+ }
+ });
+ super.tearDown();
+ }
+
+ protected Module importModuleFrom(ProjectImportProvider provider, String path) {
+ return importFrom(path, getProject(), null, provider);
+ }
+
+ protected Module importProjectFrom(String path, Consumer<ModuleWizardStep> adjuster, ProjectImportProvider... providers) {
+ Module module = importFrom(path, null, adjuster, providers);
+ if (module != null) {
+ myCreatedProject = module.getProject();
+ }
+ return module;
+ }
+
+ private Module importFrom(String path,
+ @Nullable Project project, Consumer<ModuleWizardStep> adjuster,
+ final ProjectImportProvider... providers) {
+ VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
+ assertNotNull("Can't find " + path, file);
+ assertTrue(providers[0].canImport(file, project));
+
+ myWizard = ImportModuleAction.createImportWizard(project, null, file, providers);
+ if (myWizard.getStepCount() > 0) {
+ runWizard(adjuster);
+ }
+ List<Module> modules = ImportModuleAction.createFromWizard(project, myWizard);
+ return modules == null || modules.isEmpty() ? null : modules.get(0);
+ }
+
+ protected Sdk createSdk(String name, SdkTypeId sdkType) {
+ final Sdk sdk = ProjectJdkTable.getInstance().createSdk(name, sdkType);
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ public void run() {
+ ProjectJdkTable.getInstance().addJdk(sdk);
+ }
+ });
+ mySdks.add(sdk);
+ return sdk;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/mock/MockPsiDirectory.java b/java/testFramework/src/com/intellij/mock/MockPsiDirectory.java
new file mode 100644
index 0000000..b451b29
--- /dev/null
+++ b/java/testFramework/src/com/intellij/mock/MockPsiDirectory.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
+ */
+package com.intellij.mock;
+
+import com.intellij.navigation.ItemPresentation;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.search.PsiElementProcessor;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.lang.Language;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author peter
+ */
+public class MockPsiDirectory extends MockPsiElement implements PsiDirectory {
+ private final PsiPackage myPackage;
+
+ public MockPsiDirectory(final PsiPackage aPackage, @NotNull Disposable parentDisposable) {
+ super(parentDisposable);
+ myPackage = aPackage;
+ }
+
+ @Override
+ public boolean isDirectory() {
+ return true;
+ }
+
+ @NotNull
+ @Override
+ public Language getLanguage() {
+ return Language.ANY;
+ }
+
+ @Override
+ public void checkCreateFile(@NotNull final String name) throws IncorrectOperationException {
+ throw new IncorrectOperationException("Method checkCreateFile is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ public void checkCreateSubdirectory(@NotNull final String name) throws IncorrectOperationException {
+ throw new IncorrectOperationException("Method checkCreateSubdirectory is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ public PsiDirectory getParent() {
+ return getParentDirectory();
+ }
+
+
+ @Override
+ @NotNull
+ public PsiFile createFile(@NotNull final String name) throws IncorrectOperationException {
+ throw new IncorrectOperationException("Method createFile is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ @NotNull
+ public PsiFile copyFileFrom(@NotNull final String newName, @NotNull final PsiFile originalFile) throws IncorrectOperationException {
+ throw new IncorrectOperationException("Method copyFileFrom is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ @NotNull
+ public PsiDirectory createSubdirectory(@NotNull final String name) throws IncorrectOperationException {
+ throw new IncorrectOperationException("Method createSubdirectory is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ @Nullable
+ public PsiFile findFile(@NotNull @NonNls final String name) {
+ throw new UnsupportedOperationException("Method findFile is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ @Nullable
+ public PsiDirectory findSubdirectory(@NotNull final String name) {
+ throw new UnsupportedOperationException("Method findSubdirectory is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ @NotNull
+ public PsiFile[] getFiles() {
+ throw new UnsupportedOperationException("Method getFiles is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ @NotNull
+ public String getName() {
+ throw new UnsupportedOperationException("Method getName is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ @Nullable
+ public PsiDirectory getParentDirectory() {
+ final PsiPackage psiPackage = myPackage.getParentPackage();
+ return psiPackage == null ? null : new MockPsiDirectory(psiPackage, getProject());
+ }
+
+ @Override
+ @NotNull
+ public PsiDirectory[] getSubdirectories() {
+ throw new UnsupportedOperationException("Method getSubdirectories is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ @NotNull
+ public VirtualFile getVirtualFile() {
+ throw new UnsupportedOperationException("Method getVirtualFile is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ public boolean processChildren(final PsiElementProcessor<PsiFileSystemItem> processor) {
+ throw new UnsupportedOperationException("Method processChildren is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ @NotNull
+ public PsiElement setName(@NotNull final String name) throws IncorrectOperationException {
+ throw new IncorrectOperationException("Method setName is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ public void checkSetName(final String name) throws IncorrectOperationException {
+ throw new IncorrectOperationException("Method checkSetName is not yet implemented in " + getClass().getName());
+ }
+
+ @Override
+ @Nullable
+ public ItemPresentation getPresentation() {
+ throw new UnsupportedOperationException("Method getPresentation is not yet implemented in " + getClass().getName());
+ }
+}
diff --git a/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java b/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java
new file mode 100644
index 0000000..7979272
--- /dev/null
+++ b/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2000-2012 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.projectView;
+
+import com.intellij.ide.SelectInTarget;
+import com.intellij.ide.projectView.BaseProjectTreeBuilder;
+import com.intellij.ide.projectView.ProjectView;
+import com.intellij.ide.projectView.ViewSettings;
+import com.intellij.ide.projectView.impl.*;
+import com.intellij.ide.projectView.impl.nodes.PackageElementNode;
+import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
+import com.intellij.ide.util.treeView.*;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.project.DumbAwareRunnable;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.ui.Queryable;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.testFramework.PlatformTestUtil;
+import com.intellij.testFramework.ProjectViewTestUtil;
+import com.intellij.testFramework.TestSourceBasedTestCase;
+import com.intellij.util.Function;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreePath;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+public abstract class BaseProjectViewTestCase extends TestSourceBasedTestCase {
+ protected AbstractTreeStructure myStructure;
+ protected boolean myShowMembers = false;
+ protected boolean myHideEmptyMiddlePackages;
+ protected boolean myFlattenPackages;
+
+ private List<AbstractProjectViewPSIPane> myPanes = new ArrayList<AbstractProjectViewPSIPane>();
+
+ protected Queryable.PrintInfo myPrintInfo;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ myStructure = new TestProjectTreeStructure(myProject) {
+ @Override
+ public boolean isShowMembers() {
+ return myShowMembers;
+ }
+
+ @Override
+ public boolean isHideEmptyMiddlePackages() {
+ return myHideEmptyMiddlePackages;
+ }
+
+ @Override
+ public boolean isFlattenPackages() {
+ return myFlattenPackages;
+ }
+ };
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ for (final AbstractProjectViewPSIPane myPane : myPanes) {
+ Disposer.dispose(myPane);
+ }
+ myPanes = null;
+ myStructure = null;
+ super.tearDown();
+ }
+
+ protected AbstractProjectViewPSIPane createPane() {
+ final AbstractProjectViewPSIPane pane = new MyAbstractProjectViewPSIPane();
+ pane.createComponent();
+ myPanes.add(pane);
+ return pane;
+ }
+
+ protected void assertStructureEqual(PsiDirectory packageDirectory, @NonNls String expected) {
+ assertStructureEqual(packageDirectory, expected, 17, myStructure);
+ }
+
+ protected void assertStructureEqual(PsiDirectory packageDirectory, @NonNls String expected, int maxRowCount) {
+ assertStructureEqual(packageDirectory, expected, maxRowCount, myStructure);
+ }
+
+ protected void useStandardProviders() {
+ getProjectTreeStructure().setProviders(new ClassesTreeStructureProvider(myProject));
+ }
+
+ protected AbstractProjectTreeStructure getProjectTreeStructure() {
+ return (AbstractProjectTreeStructure)myStructure;
+ }
+
+ protected void assertStructureEqual(String expected, Comparator comparator) {
+ assertStructureEqual(myStructure.getRootElement(), expected, 27, comparator);
+ }
+
+ private void assertStructureEqual(PsiDirectory root, String expected, int maxRowCount, AbstractTreeStructure structure) {
+ assertNotNull(root);
+ PsiDirectoryNode rootNode = new PsiDirectoryNode(myProject, root, (ViewSettings)structure);
+ assertStructureEqual(rootNode, expected, maxRowCount, PlatformTestUtil.createComparator(myPrintInfo));
+ }
+
+ private void assertStructureEqual(Object rootNode, String expected, int maxRowCount, Comparator comparator) {
+ checkGetParentConsistency(rootNode);
+ String actual = PlatformTestUtil.print(myStructure, rootNode, 0, comparator, maxRowCount, ' ', myPrintInfo).toString();
+ assertEquals(expected, actual);
+ }
+
+ private void checkGetParentConsistency(Object from) {
+ Object[] childElements = myStructure.getChildElements(from);
+ for (Object childElement : childElements) {
+ assertSame(from, myStructure.getParentElement(childElement));
+ checkGetParentConsistency(childElement);
+ }
+ }
+
+ protected static boolean isExpanded(DefaultMutableTreeNode nodeForElement, AbstractProjectViewPSIPane pane) {
+ TreePath path = new TreePath(nodeForElement.getPath());
+ return pane.getTree().isExpanded(path.getParentPath());
+ }
+
+ protected static DefaultMutableTreeNode getNodeForElement(PsiElement element, AbstractProjectViewPSIPane pane) {
+ JTree tree = pane.getTree();
+ TreeModel model = tree.getModel();
+ Object root = model.getRoot();
+ return getNodeForElement(root, model, element);
+ }
+
+ private static DefaultMutableTreeNode getNodeForElement(Object root, TreeModel model, PsiElement element) {
+ if (root instanceof DefaultMutableTreeNode) {
+ Object userObject = ((DefaultMutableTreeNode)root).getUserObject();
+ if (userObject instanceof AbstractTreeNode) {
+ AbstractTreeNode treeNode = (AbstractTreeNode)userObject;
+ if (element.equals(treeNode.getValue())) return (DefaultMutableTreeNode)root;
+ for (int i = 0; i < model.getChildCount(root); i++) {
+ DefaultMutableTreeNode nodeForChild = getNodeForElement(model.getChild(root, i), model, element);
+ if (nodeForChild != null) return nodeForChild;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static void checkNavigateFromSourceBehaviour(PsiElement element, VirtualFile virtualFile, AbstractProjectViewPSIPane pane) {
+ Disposer.dispose(pane);
+ pane.createComponent();
+ assertNull(getNodeForElement(element, pane));
+ pane.select(element, virtualFile, true);
+ assertTrue(isExpanded(element, pane));
+ }
+
+ public static boolean isExpanded(PsiElement element, AbstractProjectViewPSIPane pane) {
+ DefaultMutableTreeNode nodeForElement = getNodeForElement(element, pane);
+ return nodeForElement != null && isExpanded((DefaultMutableTreeNode)nodeForElement.getParent(), pane);
+ }
+
+ protected static void assertListsEqual(ListModel model, String expected) {
+ assertEquals(expected, PlatformTestUtil.print(model));
+ }
+
+ public static void checkContainsMethod(final Object rootElement, final AbstractTreeStructure structure) {
+ ProjectViewTestUtil.checkContainsMethod(rootElement, structure, new Function<AbstractTreeNode, VirtualFile[]>() {
+ @Override
+ public VirtualFile[] fun(AbstractTreeNode kid) {
+ if (kid instanceof PackageElementNode) {
+ return ((PackageElementNode)kid).getVirtualFiles();
+ }
+ return null;
+ }
+ });
+ }
+
+ @Override
+ protected String getTestPath() {
+ return "projectView";
+ }
+
+ protected static String getPackageRelativePath() {
+ return "com/package1";
+ }
+
+ protected PsiDirectory getPackageDirectory() {
+ return getPackageDirectory(getPackageRelativePath());
+ }
+
+ private class MyAbstractProjectViewPSIPane extends AbstractProjectViewPSIPane {
+ public MyAbstractProjectViewPSIPane() {
+ super(BaseProjectViewTestCase.this.myProject);
+ }
+
+ @Override
+ public SelectInTarget createSelectInTarget() {
+ return null;
+ }
+
+ @NonNls
+ public String getComponentName() {
+ return "comp name";
+ }
+
+ @Override
+ protected AbstractTreeUpdater createTreeUpdater(AbstractTreeBuilder treeBuilder) {
+ return new AbstractTreeUpdater(treeBuilder);
+ }
+
+ @Override
+ @NotNull
+ protected BaseProjectTreeBuilder createBuilder(DefaultTreeModel treeModel) {
+ return new ProjectTreeBuilder(myProject, myTree, treeModel, AlphaComparator.INSTANCE,
+ (ProjectAbstractTreeStructureBase)myTreeStructure) {
+ @Override
+ protected AbstractTreeUpdater createUpdater() {
+ return createTreeUpdater(this);
+ }
+
+ protected void addTaskToWorker(final Runnable runnable, boolean first, final Runnable postRunnable) {
+ runnable.run();
+ postRunnable.run();
+ }
+ };
+ }
+
+ @Override
+ protected ProjectAbstractTreeStructureBase createStructure() {
+ return (ProjectAbstractTreeStructureBase)myStructure;
+ }
+
+ @Override
+ protected ProjectViewTree createTree(DefaultTreeModel treeModel) {
+ return new ProjectViewTree(myProject, treeModel) {
+ @Override
+ public DefaultMutableTreeNode getSelectedNode() {
+ return null;
+ }
+ };
+ }
+
+ @Override
+ public Icon getIcon() {
+ return null;
+ }
+
+ @Override
+ @NotNull
+ public String getId() {
+ return "";
+ }
+
+ @Override
+ public String getTitle() {
+ return null;
+ }
+
+ @Override
+ public int getWeight() {
+ return 0;
+ }
+
+ public void projectOpened() {
+ final Runnable runnable = new DumbAwareRunnable() {
+ @Override
+ public void run() {
+ final ProjectView projectView = ProjectView.getInstance(myProject);
+ projectView.addProjectPane(MyAbstractProjectViewPSIPane.this);
+ }
+ };
+ StartupManager.getInstance(myProject).registerPostStartupActivity(runnable);
+ }
+
+ public void projectClosed() {
+ }
+
+ public void initComponent() { }
+
+ public void disposeComponent() {
+
+ }
+ }
+
+ @Override
+ protected String getTestDataPath() {
+ return PathManagerEx.getTestDataPath(getClass());
+ }
+
+ @Override
+ protected boolean isRunInWriteAction() {
+ return false;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java b/java/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java
new file mode 100644
index 0000000..40a42a1
--- /dev/null
+++ b/java/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2009 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.projectView;
+
+import com.intellij.ide.projectView.impl.AbstractProjectTreeStructure;
+import com.intellij.openapi.project.Project;
+
+class TestProjectTreeStructure extends AbstractProjectTreeStructure {
+ public TestProjectTreeStructure(Project project) {
+ super(project);
+ }
+
+ @Override
+ public boolean isShowMembers() {
+ return false;
+ }
+
+ @Override
+ public boolean isFlattenPackages() {
+ return false;
+ }
+
+ @Override
+ public boolean isAbbreviatePackageNames() {
+ return false;
+ }
+
+ @Override
+ public boolean isHideEmptyMiddlePackages() {
+ return false;
+ }
+
+ @Override
+ public boolean isShowLibraryContents() {
+ return true;
+ }
+
+ @Override
+ public boolean isShowModules() {
+ return true;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/psi/AbstractReparseTestCase.java b/java/testFramework/src/com/intellij/psi/AbstractReparseTestCase.java
new file mode 100644
index 0000000..43bf6cc
--- /dev/null
+++ b/java/testFramework/src/com/intellij/psi/AbstractReparseTestCase.java
@@ -0,0 +1,105 @@
+package com.intellij.psi;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.psi.impl.DebugUtil;
+import com.intellij.psi.impl.source.SourceTreeToPsiMap;
+import com.intellij.psi.text.BlockSupport;
+import com.intellij.testFramework.PsiTestCase;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author maxim
+ */
+public abstract class AbstractReparseTestCase extends PsiTestCase {
+ protected FileType myFileType;
+ protected PsiFile myDummyFile;
+ private int myInsertOffset;
+
+ protected void setFileType(final FileType fileType) {
+ myFileType = fileType;
+ }
+
+ protected void insert(@NonNls final String s) throws IncorrectOperationException {
+ CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
+ @Override
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ String oldText = myDummyFile.getText();
+ String expectedNewText = oldText.substring(0, myInsertOffset) + s + oldText.substring(myInsertOffset);
+
+ try {
+ doReparse(s, expectedNewText, 0);
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ myInsertOffset += s.length();
+ }
+ });
+ }
+ }, "asd", null);
+ }
+
+ protected void moveEditPointLeft(int count) {
+ myInsertOffset -= count;
+ }
+
+ protected void moveEditPointRight(int count) {
+ myInsertOffset += count;
+ }
+
+ protected void setEditPoint(int pos) {
+ myInsertOffset = pos;
+ }
+
+ protected void remove(int count) throws IncorrectOperationException {
+ String oldText = myDummyFile.getText();
+ String expectedNewText = oldText.substring(0, myInsertOffset-count) + oldText.substring(myInsertOffset);
+
+ doReparse("", expectedNewText, count);
+ myInsertOffset -= count;
+ }
+
+ protected void doReparse(final String s, final String expectedNewText, final int length) throws IncorrectOperationException {
+ CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
+ @Override
+ public void run() {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ BlockSupport blockSupport = ServiceManager.getService(myProject, BlockSupport.class);
+ try {
+ blockSupport.reparseRange(myDummyFile, myInsertOffset - length, myInsertOffset, s);
+ String foundStructure = DebugUtil.treeToString(SourceTreeToPsiMap.psiElementToTree(myDummyFile), false);
+ final PsiFile psiFile = createDummyFile(getName() + "." + myFileType.getDefaultExtension(), expectedNewText);
+ String expectedStructure = DebugUtil.treeToString(SourceTreeToPsiMap.psiElementToTree(psiFile), false);
+ if (!expectedStructure.equals(foundStructure)) {
+ System.out.println("expected: ");
+ System.out.println(expectedStructure);
+ System.out.println("found: ");
+ System.out.println(foundStructure);
+ assertEquals(expectedStructure, foundStructure);
+ }
+
+ assertEquals("Reparse tree should be equal to the document",expectedNewText,myDummyFile.getText());
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+ });
+ }
+ }, "asd", null);
+ }
+
+ protected void prepareFile(@NonNls String prefix, @NonNls String suffix) throws IncorrectOperationException {
+ myDummyFile = createDummyFile(getName() + "." + myFileType.getDefaultExtension(), prefix + suffix);
+ myInsertOffset = prefix.length();
+ }
+}
diff --git a/java/testFramework/src/com/intellij/refactoring/MockInlineMethodOptions.java b/java/testFramework/src/com/intellij/refactoring/MockInlineMethodOptions.java
new file mode 100644
index 0000000..3d070ef
--- /dev/null
+++ b/java/testFramework/src/com/intellij/refactoring/MockInlineMethodOptions.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 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.refactoring;
+
+import com.intellij.refactoring.inline.InlineOptions;
+
+/**
+ * @author dyoma
+ */
+public class MockInlineMethodOptions implements InlineOptions {
+ @Override
+ public boolean isInlineThisOnly() {
+ return false;
+ }
+
+ @Override
+ public void close(int exitCode) {
+ }
+
+ @Override
+ public boolean isPreviewUsages() {
+ return false;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/refactoring/MultiFileTestCase.java b/java/testFramework/src/com/intellij/refactoring/MultiFileTestCase.java
new file mode 100644
index 0000000..b21347b
--- /dev/null
+++ b/java/testFramework/src/com/intellij/refactoring/MultiFileTestCase.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2011 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.refactoring;
+
+import com.intellij.codeInsight.CodeInsightTestCase;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.impl.source.PostprocessReformattingAspect;
+import com.intellij.testFramework.PlatformTestUtil;
+import com.intellij.testFramework.PsiTestUtil;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+
+/**
+ * @author dsl
+ */
+public abstract class MultiFileTestCase extends CodeInsightTestCase {
+ protected boolean myDoCompare = true;
+
+ protected void doTest(final PerformAction performAction) throws Exception {
+ doTest(performAction, getTestName(true));
+ }
+
+ protected void doTest(final PerformAction performAction, final boolean lowercaseFirstLetter) throws Exception {
+ doTest(performAction, getTestName(lowercaseFirstLetter));
+ }
+
+ protected void doTest(final PerformAction performAction, final String testName) throws Exception {
+ String path = getTestDataPath() + getTestRoot() + testName;
+
+ String pathBefore = path + "/before";
+ final VirtualFile rootDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, pathBefore, myFilesToDelete, false);
+ prepareProject(rootDir);
+ PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+ String pathAfter = path + "/after";
+ final VirtualFile rootAfter = LocalFileSystem.getInstance().findFileByPath(pathAfter.replace(File.separatorChar, '/'));
+
+ performAction.performAction(rootDir, rootAfter);
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ public void run() {
+ myProject.getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
+ }
+ });
+
+ FileDocumentManager.getInstance().saveAllDocuments();
+
+ if (myDoCompare) {
+ PlatformTestUtil.assertDirectoriesEqual(rootAfter, rootDir, PlatformTestUtil.CVS_FILE_FILTER);
+ }
+ }
+
+ protected void prepareProject(VirtualFile rootDir) {
+ PsiTestUtil.addSourceContentToRoots(myModule, rootDir);
+ }
+
+ @Override
+ @NonNls
+ protected abstract String getTestRoot();
+
+ protected interface PerformAction {
+ void performAction(VirtualFile rootDir, VirtualFile rootAfter) throws Exception;
+ }
+
+ @Override
+ protected boolean isRunInWriteAction() {
+ return false;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/refactoring/move/moveMembers/MockMoveMembersOptions.java b/java/testFramework/src/com/intellij/refactoring/move/moveMembers/MockMoveMembersOptions.java
new file mode 100644
index 0000000..bc6b747
--- /dev/null
+++ b/java/testFramework/src/com/intellij/refactoring/move/moveMembers/MockMoveMembersOptions.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2000-2009 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.refactoring.move.moveMembers;
+
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.PsiModifier;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * @author dyoma
+ */
+public class MockMoveMembersOptions implements MoveMembersOptions {
+ private final PsiMember[] mySelectedMembers;
+ private final String myTargetClassName;
+ private String myMemberVisibility = PsiModifier.PUBLIC;
+
+ public MockMoveMembersOptions(String targetClassName, PsiMember[] selectedMembers) {
+ mySelectedMembers = selectedMembers;
+ myTargetClassName = targetClassName;
+ }
+
+ public MockMoveMembersOptions(String targetClassName, Collection<PsiMember> memberSet) {
+ this(targetClassName, memberSet.toArray(new PsiMember[memberSet.size()]));
+ }
+
+ @Override
+ public String getMemberVisibility() {
+ return myMemberVisibility;
+ }
+
+ @Override
+ public boolean makeEnumConstant() {
+ return true;
+ }
+
+ public void setMemberVisibility(@Nullable String visibility) {
+ myMemberVisibility = visibility;
+ }
+
+ @Override
+ public PsiMember[] getSelectedMembers() {
+ return mySelectedMembers;
+ }
+
+ @Override
+ public String getTargetClassName() {
+ return myTargetClassName;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/EditorActionTestCase.java b/java/testFramework/src/com/intellij/testFramework/EditorActionTestCase.java
new file mode 100644
index 0000000..a50e044
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/EditorActionTestCase.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2000-2009 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;
+
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.psi.PsiDocumentManager;
+
+import java.io.IOException;
+
+/**
+ * A TestCase for testing some action in editor
+ */
+public abstract class EditorActionTestCase extends LightCodeInsightTestCase {
+ /**
+ * @return id of the action to be tested.
+ */
+ protected abstract String getActionId();
+
+ /**
+ * Perform action test using text before and after action perform. Useas <caret> marker where caret should be
+ * placed when file is loaded in editor and <selection></selection> denoting selection bounds.
+ * @param fileName name of the file. Mostly used to create proper instance of the PsiFile
+ * @param textBefore text with markers before action
+ * @param textAfter expected text with markers after action
+ * @throws IOException
+ */
+ protected void doTextTest(String fileName, String textBefore, String textAfter) throws IOException {
+ doTextTest(fileName, textBefore, textAfter, false);
+ }
+
+ /**
+ * Perform action test using text before and after action perform. Uses <caret> marker where caret should be
+ * placed when file is loaded in editor and <selection></selection> denoting selection bounds.
+ * @param fileName name of the file. Mostly used to create proper instance of the PsiFile
+ * @param textBefore text with markers before action
+ * @param textAfter expected text with markers after action
+ * @param ignoreTrailingSpaces true if trailing spaces should be ignored.
+ * @throws IOException
+ */
+ protected void doTextTest(String fileName, String textBefore, String textAfter, boolean ignoreTrailingSpaces) throws IOException {
+ configureFromFileText(fileName, textBefore);
+ invokeAction();
+ PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+ assertEquals("Reparse error!", myEditor.getDocument().getText(), myFile.getText());
+ checkResultByText(null, textAfter, ignoreTrailingSpaces);
+ }
+
+ /**
+ * Same as doTextTest but texts are retrieved from the data files.
+ * @param filePathBefore source file's relative path from %IDEA_INSTALLATION_HOME%/testData/
+ * @param filePathAfter expected file's relative path from %IDEA_INSTALLATION_HOME%/testData/
+ * @throws Exception
+ */
+ protected void doFileTest(String filePathBefore, String filePathAfter) throws Exception {
+ doFileTest(filePathBefore, filePathAfter, false);
+ }
+
+ /**
+ * Same as doTextTest but texts are retrieved from the data files.
+ * @param filePathBefore source file's relative path from %IDEA_INSTALLATION_HOME%/testData/
+ * @param filePathAfter expected file's relative path from %IDEA_INSTALLATION_HOME%/testData/
+ * @param ignoreTrailingSpaces true if trailing spaces should be ignored.
+ * @throws Exception
+ */
+ protected void doFileTest(String filePathBefore, String filePathAfter, boolean ignoreTrailingSpaces) throws Exception {
+ configureByFile(filePathBefore);
+ invokeAction();
+ checkResultByFile(null, filePathAfter, ignoreTrailingSpaces);
+ }
+
+ private void invokeAction() {
+ final String actionId = getActionId();
+ final AnAction action = ActionManager.getInstance().getAction(actionId);
+ //noinspection HardCodedStringLiteral
+ assertNotNull("Can find registered action with id=" + actionId, action);
+ action.actionPerformed(
+ new AnActionEvent(
+ null,
+ DataManager.getInstance().getDataContext(),
+ "",
+ action.getTemplatePresentation(),
+ ActionManager.getInstance(),
+ 0
+ )
+ );
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/IdeaTestCase.java b/java/testFramework/src/com/intellij/testFramework/IdeaTestCase.java
new file mode 100644
index 0000000..93e357c
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/IdeaTestCase.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2012 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;
+
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl;
+import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.impl.JavaPsiFacadeEx;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * @author mike
+ */
+public abstract class IdeaTestCase extends PlatformTestCase {
+ protected JavaPsiFacadeEx myJavaFacade;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ myJavaFacade = JavaPsiFacadeEx.getInstanceEx(myProject);
+ VirtualFilePointerManagerImpl filePointerManager = (VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance();
+ filePointerManager.storePointers();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ myJavaFacade = null;
+ super.tearDown();
+ VirtualFilePointerManagerImpl filePointerManager = (VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance();
+ filePointerManager.assertPointersAreDisposed();
+ }
+
+ public final JavaPsiFacadeEx getJavaFacade() {
+ return myJavaFacade;
+ }
+
+ @Override
+ protected Sdk getTestProjectJdk() {
+ return IdeaTestUtil.getMockJdk17();
+ }
+
+ @Override
+ protected ModuleType getModuleType() {
+ return StdModuleTypes.JAVA;
+ }
+
+ public static void initPlatformPrefix() {
+ initPlatformPrefix("com.intellij.idea.IdeaUltimateApplication", "Idea");
+ }
+
+ protected static void sortClassesByName(final PsiClass[] classes) {
+ Arrays.sort(classes, new Comparator<PsiClass>() {
+ @Override
+ public int compare(PsiClass o1, PsiClass o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ });
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java b/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java
new file mode 100644
index 0000000..0f94f6a
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2000-2012 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;
+
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkModificator;
+import com.intellij.openapi.roots.LanguageLevelModuleExtension;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.java.LanguageLevel;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+public class IdeaTestUtil extends PlatformTestUtil {
+ public static void main(String[] args) {
+ printDetectedPerformanceTimings();
+ }
+
+ @SuppressWarnings({"UseOfSystemOutOrSystemErr"})
+ public static void printDetectedPerformanceTimings() {
+ System.out.println(Timings.getStatistics());
+ }
+
+ public static void withLevel(final Module module, final LanguageLevel level, final Runnable r) {
+ final LanguageLevelProjectExtension projectExt = LanguageLevelProjectExtension.getInstance(module.getProject());
+
+ final LanguageLevel projectLevel = projectExt.getLanguageLevel();
+ final LanguageLevel moduleLevel = LanguageLevelModuleExtension.getInstance(module).getLanguageLevel();
+ try {
+ projectExt.setLanguageLevel(level);
+ setModuleLanguageLevel(module, level);
+ r.run();
+ }
+ finally {
+ setModuleLanguageLevel(module, moduleLevel);
+ projectExt.setLanguageLevel(projectLevel);
+ }
+ }
+
+ public static void setModuleLanguageLevel(Module module, final LanguageLevel level) {
+ final LanguageLevelModuleExtension modifiable = (LanguageLevelModuleExtension)LanguageLevelModuleExtension.getInstance(module).getModifiableModel(true);
+ modifiable.setLanguageLevel(level);
+ modifiable.commit();
+ }
+
+ public static Sdk getMockJdk17() {
+ return getMockJdk17("java 1.7");
+ }
+
+ public static Sdk getMockJdk17(@NotNull String name) {
+ return JavaSdk.getInstance().createJdk(name, getMockJdk17Path().getPath(), false);
+ }
+
+ public static Sdk getMockJdk14() {
+ return JavaSdk.getInstance().createJdk("java 1.4", getMockJdk14Path().getPath(), false);
+ }
+
+ public static File getMockJdk14Path() {
+ return getPathForJdkNamed("mockJDK-1.4");
+ }
+
+ public static File getMockJdk17Path() {
+ return getPathForJdkNamed("mockJDK-1.7");
+ }
+
+ private static File getPathForJdkNamed(String name) {
+ File mockJdkCEPath = new File(PathManager.getHomePath(), "java/" + name);
+ return mockJdkCEPath.exists() ? mockJdkCEPath : new File(PathManager.getHomePath(), "community/java/" + name);
+ }
+
+ public static Sdk getWebMockJdk17() {
+ Sdk jdk = getMockJdk17();
+ addWebJarsTo(jdk);
+ return jdk;
+ }
+
+ public static void addWebJarsTo(@NotNull Sdk jdk) {
+ SdkModificator sdkModificator = jdk.getSdkModificator();
+ sdkModificator.addRoot(findJar("lib/jsp-api.jar"), OrderRootType.CLASSES);
+ sdkModificator.addRoot(findJar("lib/servlet-api.jar"), OrderRootType.CLASSES);
+ sdkModificator.commitChanges();
+ }
+
+ private static VirtualFile findJar(String name) {
+ String path = PathManager.getHomePath() + '/' + name;
+ VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path);
+ assert file != null : "not found: " + path;
+ VirtualFile jar = JarFileSystem.getInstance().getJarRootForLocalFile(file);
+ assert jar != null : "no .jar for: " + path;
+ return jar;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java b/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java
new file mode 100644
index 0000000..a93ea6b
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2000-2012 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;
+
+import com.intellij.ExtensionPoints;
+import com.intellij.analysis.AnalysisScope;
+import com.intellij.codeInspection.GlobalInspectionTool;
+import com.intellij.codeInspection.InspectionManager;
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
+import com.intellij.codeInspection.ex.*;
+import com.intellij.codeInspection.reference.EntryPoint;
+import com.intellij.codeInspection.reference.RefElement;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.ExtensionPoint;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
+import com.intellij.util.ArrayUtil;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+/**
+ * @author max
+ * @since Apr 11, 2002
+ */
+@SuppressWarnings({"HardCodedStringLiteral"})
+public abstract class InspectionTestCase extends PsiTestCase {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.testFramework.InspectionTestCase");
+ private EntryPoint myUnusedCodeExtension;
+ private VirtualFile ext_src;
+
+ public InspectionManagerEx getManager() {
+ return (InspectionManagerEx)InspectionManager.getInstance(myProject);
+ }
+
+ public void doTest(@NonNls String folderName, LocalInspectionTool tool) {
+ doTest(folderName, new LocalInspectionToolWrapper(tool));
+ }
+
+ public void doTest(@NonNls String folderName, GlobalInspectionTool tool) {
+ doTest(folderName, new GlobalInspectionToolWrapper(tool));
+ }
+
+ public void doTest(@NonNls String folderName, GlobalInspectionTool tool, boolean checkRange) {
+ doTest(folderName, new GlobalInspectionToolWrapper(tool), checkRange);
+ }
+
+ public void doTest(@NonNls String folderName, GlobalInspectionTool tool, boolean checkRange, boolean runDeadCodeFirst) {
+ doTest(folderName, new GlobalInspectionToolWrapper(tool), "java 1.4", checkRange, runDeadCodeFirst);
+ }
+
+ public void doTest(@NonNls String folderName, InspectionTool tool) {
+ doTest(folderName, tool, "java 1.4");
+ }
+
+ public void doTest(@NonNls String folderName, InspectionTool tool, final boolean checkRange) {
+ doTest(folderName, tool, "java 1.4", checkRange);
+ }
+
+ public void doTest(@NonNls String folderName, LocalInspectionTool tool, @NonNls final String jdkName) {
+ doTest(folderName, new LocalInspectionToolWrapper(tool), jdkName);
+ }
+
+ public void doTest(@NonNls String folderName, InspectionTool tool, @NonNls final String jdkName) {
+ doTest(folderName, tool, jdkName, false);
+ }
+
+ public void doTest(@NonNls String folderName, InspectionTool tool, @NonNls final String jdkName, boolean checkRange) {
+ doTest(folderName, tool, jdkName, checkRange, false);
+ }
+
+ public void doTest(@NonNls String folderName,
+ InspectionTool tool,
+ @NonNls final String jdkName,
+ boolean checkRange,
+ boolean runDeadCodeFirst,
+ InspectionTool... additional) {
+ final String testDir = getTestDataPath() + "/" + folderName;
+ runTool(testDir, jdkName, runDeadCodeFirst, tool, additional);
+
+ InspectionTestUtil.compareToolResults(tool, checkRange, testDir);
+ }
+
+ protected void runTool(@NonNls final String testDir, @NonNls final String jdkName, final InspectionTool tool) {
+ runTool(testDir, jdkName, false, tool);
+ }
+
+ protected void runTool(final String testDir,
+ final String jdkName,
+ boolean runDeadCodeFirst,
+ final InspectionTool tool,
+ InspectionTool... additional) {
+ final VirtualFile[] sourceDir = new VirtualFile[1];
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ setupRootModel(testDir, sourceDir, jdkName);
+ }
+ catch (Exception e) {
+ LOG.error(e);
+ }
+ }
+ });
+ AnalysisScope scope = createAnalysisScope(sourceDir[0].getParent());
+
+ InspectionManagerEx inspectionManager = (InspectionManagerEx)InspectionManager.getInstance(getProject());
+ InspectionTool[] tools = runDeadCodeFirst ? new InspectionTool[]{new UnusedDeclarationInspection(), tool} : new InspectionTool[]{tool};
+ tools = ArrayUtil.mergeArrays(tools, additional);
+ final GlobalInspectionContextImpl globalContext =
+ CodeInsightTestFixtureImpl.createGlobalContextForTool(scope, getProject(), inspectionManager, tools);
+
+ InspectionTestUtil.runTool(tool, scope, globalContext, inspectionManager);
+ }
+
+ protected AnalysisScope createAnalysisScope(VirtualFile sourceDir) {
+ PsiManager psiManager = PsiManager.getInstance(myProject);
+ return new AnalysisScope(psiManager.findDirectory(sourceDir));
+ }
+
+ protected void setupRootModel(final String testDir, final VirtualFile[] sourceDir, final String sdkName) {
+ VirtualFile projectDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(testDir));
+ assertNotNull("could not find project dir " + testDir, projectDir);
+ sourceDir[0] = projectDir.findChild("src");
+ if (sourceDir[0] == null) {
+ sourceDir[0] = projectDir;
+ }
+ // IMPORTANT! The jdk must be obtained in a way it is obtained in the normal program!
+ //ProjectJdkEx jdk = ProjectJdkTable.getInstance().getInternalJdk();
+ PsiTestUtil.removeAllRoots(myModule, getTestProjectSdk());
+ PsiTestUtil.addContentRoot(myModule, projectDir);
+ PsiTestUtil.addSourceRoot(myModule, sourceDir[0]);
+ ext_src = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(testDir + "/ext_src"));
+ if (ext_src != null) {
+ PsiTestUtil.addSourceRoot(myModule, ext_src);
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ ExtensionPoint<EntryPoint> point = Extensions.getRootArea().getExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL);
+ myUnusedCodeExtension = new EntryPoint() {
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return "duh";
+ }
+
+ @Override
+ public boolean isEntryPoint(RefElement refElement, PsiElement psiElement) {
+ return isEntryPoint(psiElement);
+ }
+
+ @Override
+ public boolean isEntryPoint(PsiElement psiElement) {
+ return ext_src != null && VfsUtilCore.isAncestor(ext_src, PsiUtilCore.getVirtualFile(psiElement), false);
+ }
+
+ @Override
+ public boolean isSelected() {
+ return false;
+ }
+
+ @Override
+ public void setSelected(boolean selected) {
+
+ }
+
+ @Override
+ public void readExternal(Element element) {
+
+ }
+
+ @Override
+ public void writeExternal(Element element) {
+
+ }
+ };
+
+ point.registerExtension(myUnusedCodeExtension);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ ExtensionPoint<EntryPoint> point = Extensions.getRootArea().getExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL);
+ point.unregisterExtension(myUnusedCodeExtension);
+ myUnusedCodeExtension = null;
+ ext_src = null;
+ super.tearDown();
+ }
+
+ @Override
+ protected void setUpJdk() {
+ }
+
+ protected Sdk getTestProjectSdk() {
+ Sdk sdk = IdeaTestUtil.getMockJdk17();
+ LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_5);
+ return sdk;
+ }
+
+ @Override
+ @NonNls
+ protected String getTestDataPath() {
+ return PathManagerEx.getTestDataPath() + "/inspection/";
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/LightCodeInsightTestCase.java b/java/testFramework/src/com/intellij/testFramework/LightCodeInsightTestCase.java
new file mode 100644
index 0000000..0ecf5ff
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/LightCodeInsightTestCase.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2012 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;
+
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.impl.JavaPsiFacadeEx;
+
+/**
+ * A TestCase for single PsiFile being opened in Editor conversion. See configureXXX and checkResultXXX method docs.
+ */
+public abstract class LightCodeInsightTestCase extends LightPlatformCodeInsightTestCase {
+ private LanguageLevel myOldLanguageLevel;
+
+ @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
+ protected LightCodeInsightTestCase() {
+ IdeaTestCase.initPlatformPrefix();
+ }
+
+ public static JavaPsiFacadeEx getJavaFacade() {
+ return JavaPsiFacadeEx.getInstanceEx(ourProject);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ myOldLanguageLevel = LanguageLevelProjectExtension.getInstance(getProject()).getLanguageLevel();
+ setLanguageLevel(getLanguageLevel());
+ }
+
+ protected LanguageLevel getLanguageLevel() {
+ return LanguageLevel.HIGHEST;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ setLanguageLevel(myOldLanguageLevel);
+ super.tearDown();
+ }
+
+ protected static void setLanguageLevel(final LanguageLevel level) {
+ LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(level);
+ }
+
+ @Override
+ protected Sdk getProjectJDK() {
+ return IdeaTestUtil.getMockJdk17();
+ }
+
+ @Override
+ protected ModuleType getModuleType() {
+ return StdModuleTypes.JAVA;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/LightIdeaTestCase.java b/java/testFramework/src/com/intellij/testFramework/LightIdeaTestCase.java
new file mode 100644
index 0000000..8da3a59
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/LightIdeaTestCase.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2012 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;
+
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
+import com.intellij.psi.impl.JavaPsiFacadeEx;
+
+/**
+ * A test case that provides IDEA application and project. Note both are reused for each test run in the session so
+ * be careful to return all the modification made to application and project components (such as settings) after
+ * test is finished so other test aren't affected. The project is initialized with single module that have single
+ * content and source entry. For your convenience the project may be equipped with some mock JDK so your tests may
+ * refer to external classes. In order to enable this feature you have to have a folder named "mockJDK" under
+ * idea installation home that is used for test running. Place src.zip under that folder. We'd suggest this is real mock
+ * so it contains classes that is really needed in order to speed up tests startup.
+ */
+public abstract class LightIdeaTestCase extends LightPlatformTestCase {
+ @SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors"})
+ public LightIdeaTestCase() {
+ IdeaTestCase.initPlatformPrefix();
+ }
+
+ public static JavaPsiFacadeEx getJavaFacade() {
+ return JavaPsiFacadeEx.getInstanceEx(ourProject);
+ }
+
+ @Override
+ protected Sdk getProjectJDK() {
+ return IdeaTestUtil.getMockJdk17();
+ }
+
+ @Override
+ protected ModuleType getModuleType() {
+ return StdModuleTypes.JAVA;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java
new file mode 100644
index 0000000..e91b5ff
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2000-2012 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;
+
+import com.intellij.ide.highlighter.ModuleFileType;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.module.impl.ModuleImpl;
+import com.intellij.openapi.project.impl.ProjectImpl;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.impl.ModuleRootManagerImpl;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileVisitor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+public abstract class ModuleTestCase extends IdeaTestCase {
+ protected final Collection<Module> myModulesToDispose = new ArrayList<Module>();
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ myModulesToDispose.clear();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ try {
+ final ModuleManager moduleManager = ModuleManager.getInstance(myProject);
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ for (Module module : myModulesToDispose) {
+ String moduleName = module.getName();
+ if (moduleManager.findModuleByName(moduleName) != null) {
+ moduleManager.disposeModule(module);
+ }
+ }
+ }
+ });
+ }
+ finally {
+ myModulesToDispose.clear();
+ super.tearDown();
+ }
+ }
+
+ protected Module createModule(final File moduleFile) {
+ return createModule(moduleFile, StdModuleTypes.JAVA);
+ }
+
+ protected Module createModule(final File moduleFile, final ModuleType moduleType) {
+ final String path = moduleFile.getAbsolutePath();
+ return createModule(path, moduleType);
+ }
+
+ protected Module createModule(final String path, final ModuleType moduleType) {
+ Module module = ApplicationManager.getApplication().runWriteAction(
+ new Computable<Module>() {
+ @Override
+ public Module compute() {
+ return ModuleManager.getInstance(myProject).newModule(path, moduleType.getId());
+ }
+ }
+ );
+
+ myModulesToDispose.add(module);
+ return module;
+ }
+
+ protected Module loadModule(final File moduleFile) {
+ Module module = ApplicationManager.getApplication().runWriteAction(
+ new Computable<Module>() {
+ @Override
+ public Module compute() {
+ try {
+ return ModuleManager.getInstance(myProject).loadModule(moduleFile.getAbsolutePath());
+ }
+ catch (Exception e) {
+ LOG.error(e);
+ return null;
+ }
+ }
+ }
+ );
+
+ myModulesToDispose.add(module);
+ return module;
+ }
+
+ protected Module loadModule(final String modulePath) {
+ return loadModule(new File(modulePath));
+ }
+
+ @Nullable
+ protected Module loadAllModulesUnder(@NotNull VirtualFile rootDir) throws Exception {
+ final Ref<Module> result = Ref.create();
+
+ VfsUtilCore.visitChildrenRecursively(rootDir, new VirtualFileVisitor() {
+ @Override
+ public boolean visitFile(@NotNull VirtualFile file) {
+ if (!file.isDirectory() && file.getName().endsWith(ModuleFileType.DOT_DEFAULT_EXTENSION)) {
+ ModuleImpl module = (ModuleImpl)loadModule(new File(file.getPath()));
+ readJdomExternalizables(module);
+ result.setIfNull(module);
+ }
+ return true;
+ }
+ });
+
+ return result.get();
+ }
+
+ protected void readJdomExternalizables(final ModuleImpl module) {
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ final ProjectImpl project = (ProjectImpl)myProject;
+ project.setOptimiseTestLoadSpeed(false);
+ final ModuleRootManagerImpl moduleRootManager = (ModuleRootManagerImpl)ModuleRootManager.getInstance(module);
+ module.getStateStore().initComponent(moduleRootManager, false);
+ project.setOptimiseTestLoadSpeed(true);
+ }
+ });
+ }
+
+ protected Module createModuleFromTestData(final String dirInTestData, final String newModuleFileName, final ModuleType moduleType,
+ final boolean addSourceRoot)
+ throws IOException {
+ final File dirInTestDataFile = new File(dirInTestData);
+ assertTrue(dirInTestDataFile.isDirectory());
+ final File moduleDir = createTempDirectory();
+ FileUtil.copyDir(dirInTestDataFile, moduleDir);
+ final Module module = createModule(moduleDir + "/" + newModuleFileName, moduleType);
+ final VirtualFile root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(moduleDir);
+ new WriteCommandAction.Simple(module.getProject()) {
+ @Override
+ protected void run() throws Throwable {
+ root.refresh(false, true);
+ }
+ }.execute().throwException();
+ if (addSourceRoot) {
+ PsiTestUtil.addSourceContentToRoots(module, root);
+ }
+ else {
+ PsiTestUtil.addContentRoot(module, root);
+ }
+ return module;
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java b/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java
new file mode 100644
index 0000000..63bbdb2
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2000-2012 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;
+
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeRegistry;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ModuleRootModificationUtil;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.util.DefaultJDOMExternalizer;
+import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiManagerImpl;
+import com.intellij.util.IncorrectOperationException;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * @author Mike
+ */
+public abstract class PsiTestCase extends ModuleTestCase {
+ protected PsiManagerImpl myPsiManager;
+ protected PsiFile myFile;
+ protected PsiTestData myTestDataBefore;
+ protected PsiTestData myTestDataAfter;
+ private String myDataRoot;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ myPsiManager = (PsiManagerImpl) PsiManager.getInstance(myProject);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ myPsiManager = null;
+ myFile = null;
+ myTestDataBefore = null;
+ myTestDataAfter = null;
+ super.tearDown();
+ }
+
+ protected PsiFile createDummyFile(String fileName, String text) throws IncorrectOperationException {
+ FileType type = FileTypeRegistry.getInstance().getFileTypeByFileName(fileName);
+ return PsiFileFactory.getInstance(myProject).createFileFromText(fileName, type, text);
+ }
+
+ protected PsiFile createFile(@NonNls String fileName, String text) throws Exception {
+ return createFile(myModule, fileName, text);
+ }
+ protected PsiFile createFile(Module module, String fileName, String text) throws Exception {
+ File dir = createTempDirectory();
+ VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/'));
+
+ return createFile(module, vDir, fileName, text);
+ }
+
+ protected PsiFile createFile(final Module module, final VirtualFile vDir, final String fileName, final String text) throws IOException {
+ return new WriteAction<PsiFile>() {
+ @Override
+ protected void run(Result<PsiFile> result) throws Throwable {
+ if (!ModuleRootManager.getInstance(module).getFileIndex().isInSourceContent(vDir)) {
+ addSourceContentToRoots(module, vDir);
+ }
+
+ final VirtualFile vFile = vDir.createChildData(vDir, fileName);
+ VfsUtil.saveText(vFile, text);
+ assertNotNull(vFile);
+ final PsiFile file = myPsiManager.findFile(vFile);
+ assertNotNull(file);
+ result.setResult(file);
+ }
+ }.execute().getResultObject();
+ }
+
+ protected void addSourceContentToRoots(final Module module, final VirtualFile vDir) {
+ PsiTestUtil.addSourceContentToRoots(module, vDir);
+ }
+
+ protected PsiElement configureByFileWithMarker(String filePath, String marker) throws Exception{
+ final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(filePath.replace(File.separatorChar, '/'));
+ assertNotNull("file " + filePath + " not found", vFile);
+
+ String fileText = VfsUtil.loadText(vFile);
+ fileText = StringUtil.convertLineSeparators(fileText);
+
+ int offset = fileText.indexOf(marker);
+ assertTrue(offset >= 0);
+ fileText = fileText.substring(0, offset) + fileText.substring(offset + marker.length());
+
+ myFile = createFile(vFile.getName(), fileText);
+
+ return myFile.findElementAt(offset);
+ }
+
+ protected void configure(String path, String dataName) throws Exception {
+ myDataRoot = getTestDataPath() + path;
+
+ myTestDataBefore = loadData(dataName);
+
+ PsiTestUtil.removeAllRoots(myModule, IdeaTestUtil.getMockJdk17());
+ VirtualFile vDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, myDataRoot, myFilesToDelete);
+
+ final VirtualFile vFile = vDir.findChild(myTestDataBefore.getTextFile());
+ myFile = myPsiManager.findFile(vFile);
+ }
+
+ protected String getTestDataPath() {
+ return PathManagerEx.getTestDataPath();
+ }
+
+ protected String loadFile(String name) throws Exception {
+ String result = FileUtil.loadFile(new File(getTestDataPath() + File.separatorChar + name));
+ return StringUtil.convertLineSeparators(result);
+ }
+
+ private PsiTestData loadData(String dataName) throws Exception {
+ Document document = JDOMUtil.loadDocument(new File(myDataRoot + "/" + "data.xml"));
+
+ PsiTestData data = createData();
+ Element documentElement = document.getRootElement();
+
+ final List nodes = documentElement.getChildren("data");
+
+ for (Object node1 : nodes) {
+ Element node = (Element)node1;
+ String value = node.getAttributeValue("name");
+
+ if (value.equals(dataName)) {
+ DefaultJDOMExternalizer.readExternal(data, node);
+ data.loadText(myDataRoot);
+
+ return data;
+ }
+ }
+
+ throw new IllegalArgumentException("Cannot find data chunk '" + dataName + "'");
+ }
+
+ protected PsiTestData createData() {
+ return new PsiTestData();
+ }
+
+ protected void checkResult(String dataName) throws Exception {
+ myTestDataAfter = loadData(dataName);
+
+ final String textExpected = myTestDataAfter.getText();
+ final String actualText = myFile.getText();
+
+ if (!textExpected.equals(actualText)) {
+ System.out.println("Text mismatch: " + getName() + "(" + getClass().getName() + ")");
+ System.out.println("Text expected:");
+ printText(textExpected);
+ System.out.println("Text found:");
+ printText(actualText);
+
+ fail("text");
+ }
+
+// assertEquals(myTestDataAfter.getText(), myFile.getText());
+ }
+
+ protected static void printText(String text) {
+ final String q = "\"";
+ System.out.print(q);
+
+ text = StringUtil.convertLineSeparators(text);
+
+ StringTokenizer tokenizer = new StringTokenizer(text, "\n", true);
+ while (tokenizer.hasMoreTokens()) {
+ final String token = tokenizer.nextToken();
+
+ if (token.equals("\n")) {
+ System.out.print(q);
+ System.out.println();
+ System.out.print(q);
+ continue;
+ }
+
+ System.out.print(token);
+ }
+
+ System.out.print(q);
+ System.out.println();
+ }
+
+ protected void addLibraryToRoots(final VirtualFile jarFile, OrderRootType rootType) {
+ addLibraryToRoots(myModule, jarFile, rootType);
+ }
+
+ protected static void addLibraryToRoots(final Module module, final VirtualFile root, final OrderRootType rootType) {
+ assertEquals(OrderRootType.CLASSES, rootType);
+ ModuleRootModificationUtil.addModuleLibrary(module, root.getUrl());
+ }
+
+
+ public PsiFile getFile() {
+ return myFile;
+ }
+
+ public com.intellij.openapi.editor.Document getDocument(PsiFile file) {
+ return PsiDocumentManager.getInstance(getProject()).getDocument(file);
+ }
+
+ public com.intellij.openapi.editor.Document getDocument(VirtualFile file) {
+ return FileDocumentManager.getInstance().getDocument(file);
+ }
+
+ public void commitDocument(com.intellij.openapi.editor.Document document) {
+ PsiDocumentManager.getInstance(getProject()).commitDocument(document);
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/PsiTestData.java b/java/testFramework/src/com/intellij/testFramework/PsiTestData.java
new file mode 100644
index 0000000..2691de2
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/PsiTestData.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2009 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;
+
+import com.intellij.openapi.util.DefaultJDOMExternalizer;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jdom.Element;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Mike
+ */
+public class PsiTestData implements JDOMExternalizable {
+ public String TEXT_FILE = "";
+ private String myText;
+
+ public String getTextFile() {
+ return TEXT_FILE;
+ }
+
+ public String getText() {
+ return myText;
+ }
+
+ public void loadText(String root) throws IOException{
+ String fileName = root + "/" + TEXT_FILE;
+ myText = FileUtil.loadFile(new File(fileName));
+ myText = StringUtil.convertLineSeparators(myText);
+ }
+
+ @Override
+ public void readExternal(Element element) throws InvalidDataException {
+ DefaultJDOMExternalizer.readExternal(this, element);
+ }
+
+ @Override
+ public void writeExternal(Element element) throws WriteExternalException {
+ DefaultJDOMExternalizer.writeExternal(this, element);
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/ResolveTestCase.java b/java/testFramework/src/com/intellij/testFramework/ResolveTestCase.java
new file mode 100644
index 0000000..e2cebe4
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/ResolveTestCase.java
@@ -0,0 +1,70 @@
+
+/*
+ * Copyright 2000-2009 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;
+
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiReference;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+public abstract class ResolveTestCase extends PsiTestCase {
+ @NonNls protected static final String MARKER = "<ref>";
+
+ protected PsiReference configureByFile(@NonNls String filePath) throws Exception{
+ return configureByFile(filePath, null);
+ }
+
+ protected PsiReference configureByFile(@TestDataFile @NonNls String filePath, @Nullable VirtualFile parentDir) throws Exception{
+ final String fullPath = getTestDataPath() + filePath;
+ final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
+ assertNotNull("file " + filePath + " not found", vFile);
+
+ String fileText = StringUtil.convertLineSeparators(VfsUtil.loadText(vFile));
+
+ final String fileName = vFile.getName();
+
+ return configureByFileText(fileText, fileName, parentDir);
+ }
+
+ protected PsiReference configureByFileText(String fileText, String fileName) throws Exception {
+ return configureByFileText(fileText, fileName, null);
+ }
+
+ protected PsiReference configureByFileText(String fileText, String fileName, @Nullable final VirtualFile parentDir) throws Exception {
+ int offset = fileText.indexOf(MARKER);
+ assertTrue(offset >= 0);
+ fileText = fileText.substring(0, offset) + fileText.substring(offset + MARKER.length());
+
+ myFile = parentDir == null? createFile(myModule, fileName, fileText) : createFile(myModule, parentDir, fileName, fileText);
+ PsiReference ref = myFile.findReferenceAt(offset);
+
+ assertNotNull(ref);
+
+ return ref;
+ }
+
+ @Override
+ protected String getTestDataPath() {
+ return PathManagerEx.getTestDataPath() + "/psi/resolve/";
+ }
+}
\ No newline at end of file
diff --git a/java/testFramework/src/com/intellij/testFramework/TestSourceBasedTestCase.java b/java/testFramework/src/com/intellij/testFramework/TestSourceBasedTestCase.java
new file mode 100644
index 0000000..377de5d
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/TestSourceBasedTestCase.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2000-2009 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;
+
+import com.intellij.ide.highlighter.ProjectFileType;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+
+@SuppressWarnings({"HardCodedStringLiteral", "ConstantConditions", "JUnitTestCaseInProductSource"})
+@NonNls public abstract class TestSourceBasedTestCase extends IdeaTestCase {
+ private File myTempDirectory;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ myTempDirectory = FileUtil.createTempDirectory(getTestName(true), "test",false);
+ myFilesToDelete.add(myTempDirectory);
+ final File testRoot = new File(getTestDataPath(), getTestPath());
+ assertTrue(testRoot.getAbsolutePath(), testRoot.isDirectory());
+
+ final File currentTestRoot = new File(testRoot, getTestDirectoryName());
+ assertTrue(currentTestRoot.getAbsolutePath(), currentTestRoot.isDirectory());
+
+ FileUtil.copyDir(currentTestRoot, new File(myTempDirectory, getTestDirectoryName()));
+
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ setupContentRoot();
+ }
+ });
+
+ }
+
+ protected String getTestDataPath() {
+ return PathManagerEx.getTestDataPath(getClass());
+ }
+
+ protected abstract String getTestPath();
+
+ private File getTestContentFile() {
+ return new File(myTempDirectory, getTestDirectoryName());
+ }
+
+ private void setupContentRoot() {
+ PsiTestUtil.addContentRoot(myModule, getContentRoot());
+ VirtualFile src = getContentRoot().findChild("src");
+ if (src != null) {
+ PsiTestUtil.addSourceRoot(myModule, src);
+ }
+ }
+
+ protected VirtualFile getContentRoot() {
+ File file = getTestContentFile();
+ return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+ }
+
+ @Override
+ protected String getTestDirectoryName() {
+ return getTestName(true);
+ }
+
+
+ protected PsiDirectory getPackageDirectory(final String packageRelativePath) {
+ return getPsiManager().findDirectory(getContentRoot().findFileByRelativePath("src/" + packageRelativePath));
+ }
+
+ protected PsiDirectory getSrcDirectory() {
+ return getPsiManager().findDirectory(getContentRoot().findFileByRelativePath("src"));
+ }
+
+ protected PsiDirectory getContentDirectory() {
+ return getPsiManager().findDirectory(getContentRoot());
+ }
+
+ protected String getRootFiles() {
+ return " " + myModule.getModuleFile().getName() + "\n" +
+ " " + myProject.getName() + ProjectFileType.DOT_DEFAULT_EXTENSION +
+ "\n";
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/builders/JavaModuleFixtureBuilder.java b/java/testFramework/src/com/intellij/testFramework/builders/JavaModuleFixtureBuilder.java
new file mode 100644
index 0000000..df0b9f2
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/builders/JavaModuleFixtureBuilder.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2009 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.builders;
+
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.testFramework.fixtures.ModuleFixture;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.Map;
+
+/**
+ * @author mike
+ */
+public interface JavaModuleFixtureBuilder<T extends ModuleFixture> extends ModuleFixtureBuilder<T> {
+
+ enum MockJdkLevel {
+ jdk14,
+ jdk15
+ }
+
+ JavaModuleFixtureBuilder setLanguageLevel(LanguageLevel languageLevel);
+
+ JavaModuleFixtureBuilder addLibrary(@NonNls String libraryName, @NonNls String... classPath);
+
+ JavaModuleFixtureBuilder addLibrary(@NonNls String libraryName, Map<OrderRootType, String[]> roots);
+
+ JavaModuleFixtureBuilder addLibraryJars(@NonNls String libraryName, @NonNls String basePath, @NonNls String... jarNames);
+
+ JavaModuleFixtureBuilder addJdk(@NonNls String jdkPath);
+
+ void setMockJdkLevel(MockJdkLevel level);
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java b/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java
new file mode 100755
index 0000000..5e6a31f
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java
@@ -0,0 +1,155 @@
+package com.intellij.testFramework.codeInsight.hierarchy;
+
+import com.intellij.codeInsight.CodeInsightTestCase;
+import com.intellij.ide.hierarchy.HierarchyNodeDescriptor;
+import com.intellij.ide.hierarchy.HierarchyTreeStructure;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.openapi.util.io.FileUtil;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.*;
+
+/**
+ * Checks tree structure for Type Hierarchy (Ctrl+H), Call Hierarchy (Ctrl+Alt+H), Method Hierarchy (Ctrl+Shift+H).
+ */
+public abstract class HierarchyViewTestBase extends CodeInsightTestCase {
+
+ private static final String NODE_ELEMENT_NAME = "node";
+ private static final String ANY_NODES_ELEMENT_NAME = "any";
+ private static final String TEXT_ATTR_NAME = "text";
+ private static final String BASE_ATTR_NAME = "base";
+
+ protected abstract String getBasePath();
+
+ protected void doHierarchyTest(final Computable<HierarchyTreeStructure> treeStructureComputable, final String... fileNames)
+ throws Exception {
+ final String[] relFilePaths = new String[fileNames.length];
+ for (int i = 0; i < fileNames.length; i++) {
+ relFilePaths[i] = "/" + getBasePath() + "/" + fileNames[i];
+ }
+ configureByFiles(null, relFilePaths);
+
+ final String verificationFilePath = getTestDataPath() + "/" + getBasePath() + "/" + getTestName(false) + "_verification.xml";
+ HierarchyTreeStructure structure = treeStructureComputable.compute();
+ try {
+ checkHierarchyTreeStructure(structure, JDOMUtil.loadDocument(new File(verificationFilePath)));
+ } catch (Throwable e) {
+ assertEquals("XML structure comparison for your convenience, actual failure details BELOW",
+ FileUtil.loadFile(new File(verificationFilePath)), dump(structure, null, 0));
+ //noinspection CallToPrintStackTrace
+ e.printStackTrace();
+ }
+ }
+
+ private static String dump(final HierarchyTreeStructure treeStructure, @Nullable HierarchyNodeDescriptor descriptor, int level) {
+ StringBuilder s = new StringBuilder();
+ dump(treeStructure, descriptor, level, s);
+ return s.toString();
+ }
+
+ private static void dump(final HierarchyTreeStructure treeStructure,
+ @Nullable HierarchyNodeDescriptor descriptor,
+ int level,
+ StringBuilder b) {
+ if (level > 10) {
+ for(int i = 0; i<level; i++) b.append(" ");
+ b.append("<Probably infinite part skipped>\n");
+ return;
+ }
+ if(descriptor==null) descriptor = (HierarchyNodeDescriptor)treeStructure.getRootElement();
+ for(int i = 0; i<level; i++) b.append(" ");
+ descriptor.update();
+ b.append("<node text=\"").append(descriptor.getHighlightedText().getText()).append("\"")
+ .append(treeStructure.getBaseDescriptor() == descriptor ? " base=\"true\"" : "");
+
+ final Object[] children = treeStructure.getChildElements(descriptor);
+ if(children.length>0) {
+ b.append(">\n");
+ for (Object o : children) {
+ HierarchyNodeDescriptor d = (HierarchyNodeDescriptor)o;
+ dump(treeStructure, d, level + 1, b);
+ }
+ for(int i = 0; i<level; i++) b.append(" ");
+ b.append("</node>\n");
+ } else {
+ b.append("/>\n");
+ }
+ }
+
+ private static void checkHierarchyTreeStructure(final HierarchyTreeStructure treeStructure, final Document document) {
+ final HierarchyNodeDescriptor rootNodeDescriptor = (HierarchyNodeDescriptor)treeStructure.getRootElement();
+ rootNodeDescriptor.update();
+ final Element rootElement = document.getRootElement();
+ if (rootElement == null || !NODE_ELEMENT_NAME.equals(rootElement.getName())) {
+ throw new IllegalArgumentException("Incorrect root element in verification resource");
+ }
+ checkNodeDescriptorRecursively(treeStructure, rootNodeDescriptor, rootElement);
+ }
+
+ private static void checkNodeDescriptorRecursively(final HierarchyTreeStructure treeStructure,
+ final HierarchyNodeDescriptor descriptor,
+ final Element expectedElement) {
+ checkBaseNode(treeStructure, descriptor, expectedElement);
+ checkContent(descriptor, expectedElement);
+ checkChildren(treeStructure, descriptor, expectedElement);
+ }
+
+ private static void checkBaseNode(final HierarchyTreeStructure treeStructure,
+ final HierarchyNodeDescriptor descriptor,
+ final Element expectedElement) {
+ final String baseAttrValue = expectedElement.getAttributeValue(BASE_ATTR_NAME);
+ final HierarchyNodeDescriptor baseDescriptor = treeStructure.getBaseDescriptor();
+ final boolean mustBeBase = "true".equalsIgnoreCase(baseAttrValue);
+ assertTrue("Incorrect base node", mustBeBase ? baseDescriptor == descriptor : baseDescriptor != descriptor);
+ }
+
+ private static void checkContent(final HierarchyNodeDescriptor descriptor, final Element expectedElement) {
+ assertEquals(expectedElement.getAttributeValue(TEXT_ATTR_NAME), descriptor.getHighlightedText().getText());
+ }
+
+ private static void checkChildren(final HierarchyTreeStructure treeStructure,
+ final HierarchyNodeDescriptor descriptor,
+ final Element element) {
+ if (element.getChild(ANY_NODES_ELEMENT_NAME) != null) {
+ return;
+ }
+
+ final Object[] children = treeStructure.getChildElements(descriptor);
+ //noinspection unchecked
+ final List<Element> expectedChildren = new ArrayList<Element>(element.getChildren(NODE_ELEMENT_NAME));
+
+ final StringBuilder messageBuilder = new StringBuilder("Actual children of [" + descriptor.getHighlightedText().getText() + "]:\n");
+ for (Object child : children) {
+ final HierarchyNodeDescriptor nodeDescriptor = (HierarchyNodeDescriptor)child;
+ nodeDescriptor.update();
+ messageBuilder.append(" [").append(nodeDescriptor.getHighlightedText().getText()).append("]\n");
+ }
+ assertEquals(messageBuilder.toString(), expectedChildren.size(), children.length);
+
+ Arrays.sort(children, new Comparator<Object>() {
+ @Override
+ public int compare(final Object first, final Object second) {
+ return ((HierarchyNodeDescriptor)first).getHighlightedText().getText()
+ .compareTo(((HierarchyNodeDescriptor)second).getHighlightedText().getText());
+ }
+ });
+
+ Collections.sort(expectedChildren, new Comparator<Element>() {
+ @Override
+ public int compare(final Element first, final Element second) {
+ return first.getAttributeValue(TEXT_ATTR_NAME).compareTo(second.getAttributeValue(TEXT_ATTR_NAME));
+ }
+ });
+
+ //noinspection unchecked
+ final Iterator<Element> iterator = expectedChildren.iterator();
+ for (Object child : children) {
+ checkNodeDescriptorRecursively(treeStructure, ((HierarchyNodeDescriptor)child), iterator.next());
+ }
+ }
+
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/DefaultLightProjectDescriptor.java b/java/testFramework/src/com/intellij/testFramework/fixtures/DefaultLightProjectDescriptor.java
new file mode 100644
index 0000000..2a2d15c
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/DefaultLightProjectDescriptor.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2012 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.fixtures;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.LanguageLevelModuleExtension;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.testFramework.IdeaTestUtil;
+import com.intellij.testFramework.LightProjectDescriptor;
+
+/**
+* @author peter
+*/
+public class DefaultLightProjectDescriptor implements LightProjectDescriptor {
+ @Override
+ public ModuleType getModuleType() {
+ return StdModuleTypes.JAVA;
+ }
+
+ @Override
+ public Sdk getSdk() {
+ return IdeaTestUtil.getMockJdk17();
+ }
+
+ @Override
+ public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
+ LanguageLevelModuleExtension extension = model.getModuleExtension(LanguageLevelModuleExtension.class);
+ if (extension != null) {
+ extension.setLanguageLevel(LanguageLevel.HIGHEST);
+ }
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightFixtureTestCase.java b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightFixtureTestCase.java
new file mode 100644
index 0000000..d811f49
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightFixtureTestCase.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2000-2009 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.fixtures;
+
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiElementFactory;
+import com.intellij.psi.PsiManager;
+import com.intellij.testFramework.IdeaTestCase;
+import com.intellij.testFramework.UsefulTestCase;
+import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+
+/**
+ * @author peter
+ */
+public abstract class JavaCodeInsightFixtureTestCase extends UsefulTestCase{
+ protected JavaCodeInsightTestFixture myFixture;
+ protected Module myModule;
+
+ @SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors"})
+ protected JavaCodeInsightFixtureTestCase() {
+ IdeaTestCase.initPlatformPrefix();
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName());
+ myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture());
+ final JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
+ moduleFixtureBuilder.addSourceContentRoot(myFixture.getTempDirPath());
+ tuneFixture(moduleFixtureBuilder);
+
+ myFixture.setUp();
+ myFixture.setTestDataPath(getTestDataPath());
+ myModule = moduleFixtureBuilder.getFixture().getModule();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ myModule = null;
+ myFixture.tearDown();
+ myFixture = null;
+ super.tearDown();
+ }
+
+ /**
+ * Return relative path to the test data. Path is relative to the
+ * {@link com.intellij.openapi.application.PathManager#getHomePath()}
+ *
+ * @return relative path to the test data.
+ */
+ @NonNls
+ protected String getBasePath() {
+ return "";
+ }
+
+ /**
+ * Return absolute path to the test data. Not intended to be overridden.
+ *
+ * @return absolute path to the test data.
+ */
+ @NonNls
+ protected String getTestDataPath() {
+ return PathManager.getHomePath().replace(File.separatorChar, '/') + getBasePath();
+ }
+
+ protected void tuneFixture(final JavaModuleFixtureBuilder moduleBuilder) throws Exception {}
+
+
+ protected Project getProject() {
+ return myFixture.getProject();
+ }
+
+ protected PsiManager getPsiManager() {
+ return PsiManager.getInstance(getProject());
+ }
+
+ public PsiElementFactory getElementFactory() {
+ return JavaPsiFacade.getInstance(getProject()).getElementFactory();
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java
new file mode 100644
index 0000000..e5d8c43
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2012 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.fixtures;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.impl.JavaPsiFacadeEx;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public interface JavaCodeInsightTestFixture extends CodeInsightTestFixture {
+ JavaPsiFacadeEx getJavaFacade();
+
+ PsiClass addClass(@NotNull @NonNls final String classText);
+
+ @NotNull
+ PsiClass findClass(@NotNull @NonNls String name);
+
+ @NotNull
+ PsiPackage findPackage(@NotNull @NonNls String name);
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestUtil.java b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestUtil.java
new file mode 100644
index 0000000..dac9920
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestUtil.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2000-2010 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.fixtures;
+
+import com.intellij.codeInsight.TargetElementUtilBase;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.psi.*;
+import com.intellij.refactoring.inline.InlineConstantFieldProcessor;
+import com.intellij.refactoring.inline.InlineLocalHandler;
+import com.intellij.refactoring.inline.InlineMethodProcessor;
+import com.intellij.refactoring.inline.InlineParameterHandler;
+import com.intellij.refactoring.util.InlineUtil;
+import org.jetbrains.annotations.NotNull;
+
+
+public class JavaCodeInsightTestUtil {
+ private static final int TARGET_FOR_INLINE_FLAGS =
+ TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED;
+
+ private JavaCodeInsightTestUtil() { }
+
+ public static void doInlineLocalTest(@NotNull final CodeInsightTestFixture fixture,
+ @NotNull final String before, @NotNull final String after) {
+ fixture.configureByFile(before);
+ new WriteCommandAction(fixture.getProject()) {
+ @Override
+ protected void run(final Result result) throws Throwable {
+ final Editor editor = fixture.getEditor();
+ final PsiElement element = TargetElementUtilBase.findTargetElement(editor, TARGET_FOR_INLINE_FLAGS);
+ assert element instanceof PsiLocalVariable : element;
+ InlineLocalHandler.invoke(fixture.getProject(), editor, (PsiLocalVariable)element, null);
+ }
+ }.execute();
+ fixture.checkResultByFile(after, false);
+ }
+
+ public static void doInlineParameterTest(@NotNull final CodeInsightTestFixture fixture,
+ @NotNull final String before, @NotNull final String after) {
+ fixture.configureByFile(before);
+ new WriteCommandAction(fixture.getProject()) {
+ @Override
+ protected void run(final Result result) throws Throwable {
+ final Editor editor = fixture.getEditor();
+ final PsiElement element = TargetElementUtilBase.findTargetElement(editor, TARGET_FOR_INLINE_FLAGS);
+ assert element instanceof PsiParameter : element;
+ new InlineParameterHandler().inlineElement(getProject(), editor, element);
+ }
+ }.execute();
+ fixture.checkResultByFile(after, false);
+ }
+
+ public static void doInlineMethodTest(@NotNull final CodeInsightTestFixture fixture,
+ @NotNull final String before, @NotNull final String after) {
+ fixture.configureByFile(before);
+ new WriteCommandAction(fixture.getProject()) {
+ @Override
+ protected void run(final Result result) throws Throwable {
+ final Editor editor = fixture.getEditor();
+ final PsiElement element = TargetElementUtilBase.findTargetElement(editor, TARGET_FOR_INLINE_FLAGS);
+ assert element instanceof PsiMethod : element;
+
+ final PsiReference ref = fixture.getFile().findReferenceAt(editor.getCaretModel().getOffset());
+ final PsiReferenceExpression refExpr = ref instanceof PsiReferenceExpression ? (PsiReferenceExpression)ref : null;
+
+ final PsiMethod method = (PsiMethod)element;
+ assert !(InlineMethodProcessor.checkBadReturns(method) && !InlineUtil.allUsagesAreTailCalls(method)) : "Bad returns found";
+ new InlineMethodProcessor(getProject(), method, refExpr, editor, false).run();
+ }
+ }.execute();
+ fixture.checkResultByFile(after, false);
+ }
+
+ public static void doInlineConstantTest(@NotNull final CodeInsightTestFixture fixture,
+ @NotNull final String before, @NotNull final String after) {
+ fixture.configureByFile(before);
+ new WriteCommandAction(fixture.getProject()) {
+ @Override
+ protected void run(final Result result) throws Throwable {
+ final Editor editor = fixture.getEditor();
+ final PsiElement element = TargetElementUtilBase.findTargetElement(editor, TARGET_FOR_INLINE_FLAGS);
+ assert element instanceof PsiField : element;
+
+ final PsiReference ref = fixture.getFile().findReferenceAt(editor.getCaretModel().getOffset());
+ final PsiReferenceExpression refExpr = ref instanceof PsiReferenceExpression ? (PsiReferenceExpression)ref : null;
+
+ new InlineConstantFieldProcessor((PsiField)element, getProject(), refExpr, false).run();
+ }
+ }.execute();
+ fixture.checkResultByFile(after, false);
+ }
+}
\ No newline at end of file
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaTestFixtureFactory.java b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaTestFixtureFactory.java
new file mode 100644
index 0000000..5ae1917
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaTestFixtureFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2009 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.fixtures;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public abstract class JavaTestFixtureFactory {
+ private static final JavaTestFixtureFactory ourInstance;
+
+ static {
+ try {
+ final Class<?> aClass = Class.forName("com.intellij.testFramework.fixtures.impl.JavaTestFixtureFactoryImpl");
+ ourInstance = (JavaTestFixtureFactory)aClass.newInstance();
+ }
+ catch (Exception e) {
+ throw new RuntimeException("Can't instantiate factory", e);
+ }
+ }
+
+ public static JavaTestFixtureFactory getFixtureFactory() {
+ return ourInstance;
+ }
+
+ public abstract TestFixtureBuilder<IdeaProjectTestFixture> createLightFixtureBuilder();
+
+ public abstract JavaCodeInsightTestFixture createCodeInsightFixture(IdeaProjectTestFixture projectFixture);
+
+ public abstract JavaCodeInsightTestFixture createCodeInsightFixture(IdeaProjectTestFixture projectFixture, TempDirTestFixture tempDirFixture);
+
+ /**
+ *
+ * @deprecated use {@link JavaTestFixtureFactory#createFixtureBuilder(String)}
+ */
+ //also implicitly initializes ourInstance and registers java module fixture builder
+ public static TestFixtureBuilder<IdeaProjectTestFixture> createFixtureBuilder() {
+ return IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder();
+ }
+ public static TestFixtureBuilder<IdeaProjectTestFixture> createFixtureBuilder(@NotNull String name) {
+ return IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(name);
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java b/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java
new file mode 100644
index 0000000..4d284cf
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2000-2009 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.fixtures;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.LanguageLevelModuleExtension;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.testFramework.*;
+import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+/**
+ * @author peter
+ */
+public abstract class LightCodeInsightFixtureTestCase extends UsefulTestCase{
+ public static final LightProjectDescriptor JAVA_1_6 = new DefaultLightProjectDescriptor() {
+ @Override
+ public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
+ model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_6);
+ }
+ };
+ public static final LightProjectDescriptor JAVA_LATEST = new DefaultLightProjectDescriptor();
+
+
+ protected JavaCodeInsightTestFixture myFixture;
+ protected Module myModule;
+
+ @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
+ protected LightCodeInsightFixtureTestCase() {
+ IdeaTestCase.initPlatformPrefix();
+ }
+
+ @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
+ public LightCodeInsightFixtureTestCase(String classToTest, String prefix) {
+ PlatformTestCase.initPlatformPrefix(classToTest, prefix);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ IdeaTestFixtureFactory factory = IdeaTestFixtureFactory.getFixtureFactory();
+ TestFixtureBuilder<IdeaProjectTestFixture> fixtureBuilder = factory.createLightFixtureBuilder(getProjectDescriptor());
+ final IdeaProjectTestFixture fixture = fixtureBuilder.getFixture();
+ myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(fixture, new LightTempDirTestFixtureImpl(true));
+
+ myFixture.setUp();
+ myFixture.setTestDataPath(getTestDataPath());
+
+ myModule = myFixture.getModule();
+ }
+
+ /**
+ * Return relative path to the test data.
+ *
+ * @return relative path to the test data.
+ */
+ @NonNls
+ protected String getBasePath() {
+ return "";
+ }
+
+ @NotNull
+ protected LightProjectDescriptor getProjectDescriptor() {
+ return JAVA_LATEST;
+ }
+
+
+ /**
+ * Return absolute path to the test data. Not intended to be overridden.
+ *
+ * @return absolute path to the test data.
+ */
+ @NonNls
+ protected String getTestDataPath() {
+ String communityPath = PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/');
+ String path = communityPath + getBasePath();
+ if (new File(path).exists()) return path;
+ return communityPath + "/../" + getBasePath();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ myFixture.tearDown();
+ myFixture = null;
+ myModule = null;
+ super.tearDown();
+ }
+ protected final void runTestBare() throws Throwable {
+ LightCodeInsightFixtureTestCase.super.runTest();
+ }
+
+ protected Project getProject() {
+ return myFixture.getProject();
+ }
+
+ protected PsiManager getPsiManager() {
+ return PsiManager.getInstance(getProject());
+ }
+
+ public PsiElementFactory getElementFactory() {
+ return JavaPsiFacade.getInstance(getProject()).getElementFactory();
+ }
+
+ protected PsiFile createLightFile(final FileType fileType, final String text) {
+ return PsiFileFactory.getInstance(getProject()).createFileFromText("a." + fileType.getDefaultExtension(), fileType, text);
+ }
+
+ public PsiFile createLightFile(final String fileName, final Language language, final String text) {
+ return PsiFileFactory.getInstance(getProject()).createFileFromText(fileName, language, text, false, true);
+ }
+
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java
new file mode 100644
index 0000000..e4d075b
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2012 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.fixtures.impl;
+
+import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.JavaPsiFacadeEx;
+import com.intellij.psi.impl.PsiModificationTrackerImpl;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
+import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture;
+import com.intellij.testFramework.fixtures.TempDirTestFixture;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public class JavaCodeInsightTestFixtureImpl extends CodeInsightTestFixtureImpl implements JavaCodeInsightTestFixture {
+ public JavaCodeInsightTestFixtureImpl(IdeaProjectTestFixture projectFixture, TempDirTestFixture tempDirFixture) {
+ super(projectFixture, tempDirFixture);
+ }
+
+ @Override
+ public JavaPsiFacadeEx getJavaFacade() {
+ assertInitialized();
+ return JavaPsiFacadeEx.getInstanceEx(getProject());
+ }
+
+ @Override
+ public PsiClass addClass(@NotNull @NonNls final String classText) {
+ assertInitialized();
+ final PsiClass psiClass = addClass(getTempDirPath(), classText);
+ final VirtualFile file = psiClass.getContainingFile().getVirtualFile();
+ allowTreeAccessForFile(file);
+ return psiClass;
+ }
+
+ private PsiClass addClass(@NonNls final String rootPath, @NotNull @NonNls final String classText) {
+ final String qName =
+ ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+ public String compute() {
+ final PsiFileFactory factory = PsiFileFactory.getInstance(getProject());
+ final PsiJavaFile javaFile = (PsiJavaFile)factory.createFileFromText("a.java", JavaFileType.INSTANCE, classText);
+ return javaFile.getClasses()[0].getQualifiedName();
+ }
+ });
+ assert qName != null;
+ final PsiFile psiFile = addFileToProject(rootPath, qName.replace('.', '/') + ".java", classText);
+ return ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+ public PsiClass compute() {
+ return ((PsiJavaFile)psiFile).getClasses()[0];
+ }
+ });
+ }
+
+ @Override
+ @NotNull
+ public PsiClass findClass(@NotNull @NonNls final String name) {
+ final PsiClass aClass = getJavaFacade().findClass(name, ProjectScope.getProjectScope(getProject()));
+ assertNotNull("Class " + name + " not found", aClass);
+ return aClass;
+ }
+
+ @Override
+ @NotNull
+ public PsiPackage findPackage(@NotNull @NonNls final String name) {
+ final PsiPackage aPackage = getJavaFacade().findPackage(name);
+ assertNotNull("Package " + name + " not found", aPackage);
+ return aPackage;
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ ((PsiModificationTrackerImpl)getPsiManager().getModificationTracker()).incCounter();// drop all caches
+ super.tearDown();
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java
new file mode 100644
index 0000000..21f3e43
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2000-2012 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.fixtures.impl;
+
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.impl.MockJdkWrapper;
+import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTable;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.testFramework.IdeaTestUtil;
+import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
+import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
+import com.intellij.testFramework.fixtures.ModuleFixture;
+import com.intellij.testFramework.fixtures.TestFixtureBuilder;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author mike
+ */
+abstract class JavaModuleFixtureBuilderImpl<T extends ModuleFixture> extends ModuleFixtureBuilderImpl<T> implements JavaModuleFixtureBuilder<T> {
+ private final List<Lib> myLibraries = new ArrayList<Lib>();
+ private String myJdk;
+ private MockJdkLevel myMockJdkLevel = MockJdkLevel.jdk14;
+ private LanguageLevel myLanguageLevel = null;
+
+ public JavaModuleFixtureBuilderImpl(final TestFixtureBuilder<? extends IdeaProjectTestFixture> fixtureBuilder) {
+ super(StdModuleTypes.JAVA, fixtureBuilder);
+ }
+
+ public JavaModuleFixtureBuilderImpl(final ModuleType moduleType, final TestFixtureBuilder<? extends IdeaProjectTestFixture> fixtureBuilder) {
+ super(moduleType, fixtureBuilder);
+ }
+
+ @Override
+ public JavaModuleFixtureBuilder setLanguageLevel(final LanguageLevel languageLevel) {
+ myLanguageLevel = languageLevel;
+ return this;
+ }
+
+ @Override
+ public JavaModuleFixtureBuilder addLibrary(String libraryName, String... classPath) {
+ final HashMap<OrderRootType, String[]> map = new HashMap<OrderRootType, String[]>();
+ for (String path : classPath) {
+ if (!new File(path).exists()) {
+ System.out.println(path + " not exists");
+ }
+ }
+ map.put(OrderRootType.CLASSES, classPath);
+ myLibraries.add(new Lib(libraryName, map));
+ return this;
+ }
+
+ @Override
+ public JavaModuleFixtureBuilder addLibrary(@NonNls final String libraryName, final Map<OrderRootType, String[]> roots) {
+ myLibraries.add(new Lib(libraryName, roots));
+ return this;
+ }
+
+ @Override
+ public JavaModuleFixtureBuilder addLibraryJars(String libraryName, String basePath, String... jars) {
+ if (!basePath.endsWith("/")) {
+ basePath += "/";
+ }
+ String[] classPath = ArrayUtil.newStringArray(jars.length);
+ for (int i = 0; i < jars.length; i++) {
+ classPath[i] = basePath + jars[i];
+ }
+ return addLibrary(libraryName, classPath);
+ }
+
+ @Override
+ public JavaModuleFixtureBuilder addJdk(String jdkPath) {
+ myJdk = jdkPath;
+ return this;
+ }
+
+ @Override
+ public void setMockJdkLevel(final MockJdkLevel level) {
+ myMockJdkLevel = level;
+ }
+
+ @Override
+ protected void initModule(final Module module) {
+ super.initModule(module);
+
+ final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
+ final LibraryTable libraryTable = model.getModuleLibraryTable();
+
+ for (Lib lib : myLibraries) {
+ String libraryName = lib.getName();
+
+ final Library library = libraryTable.createLibrary(libraryName);
+
+ final Library.ModifiableModel libraryModel = library.getModifiableModel();
+
+ for (OrderRootType rootType : OrderRootType.getAllTypes()) {
+ final String[] roots = lib.getRoots(rootType);
+ for (String root : roots) {
+ VirtualFile vRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(root);
+ if (vRoot != null && OrderRootType.CLASSES.equals(rootType) && !vRoot.isDirectory()) {
+ final VirtualFile jar = JarFileSystem.getInstance().refreshAndFindFileByPath(root + "!/");
+ if (jar != null) vRoot = jar;
+ }
+ if (vRoot != null) {
+ libraryModel.addRoot(vRoot, rootType);
+ }
+ }
+ }
+ libraryModel.commit();
+ }
+
+ final Sdk jdk;
+ if (myJdk != null) {
+ jdk = JavaSdk.getInstance().createJdk(module.getName() + "_jdk", myJdk, false);
+ ((ProjectJdkImpl)jdk).setVersionString("java 1.5");
+ }
+ else {
+ jdk = IdeaTestUtil.getMockJdk17();
+ }
+ if (jdk != null) {
+ model.setSdk(new MockJdkWrapper(CompilerConfigurationImpl.getTestsExternalCompilerHome(), jdk));
+ }
+
+ if (myLanguageLevel != null) {
+ model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(myLanguageLevel);
+ }
+ else if (myMockJdkLevel == MockJdkLevel.jdk15) {
+ model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_5);
+ }
+
+ model.commit();
+
+ for (OrderEntry entry : ModuleRootManager.getInstance(module).getOrderEntries()) {
+ if (entry instanceof LibraryOrderEntry) {
+ Library library = ((LibraryOrderEntry)entry).getLibrary();
+ libraryCreated(library, module);
+ }
+ }
+ }
+
+ @Override
+ protected void setupRootModel(ModifiableRootModel rootModel) {
+ if (myOutputPath != null) {
+ final File pathFile = new File(myOutputPath);
+ if (!pathFile.mkdirs()) {
+ assert pathFile.exists() : "unable to create: " + myOutputPath;
+ }
+ final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(myOutputPath);
+ assert virtualFile != null : "cannot find output path: " + myOutputPath;
+ rootModel.getModuleExtension(CompilerModuleExtension.class).setCompilerOutputPath(virtualFile);
+ rootModel.getModuleExtension(CompilerModuleExtension.class).inheritCompilerOutputPath(false);
+ rootModel.getModuleExtension(CompilerModuleExtension.class).setExcludeOutput(false);
+ }
+ if (myTestOutputPath != null) {
+ assert new File(myTestOutputPath).mkdirs() : myTestOutputPath;
+ final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(myTestOutputPath);
+ assert virtualFile != null : "cannot find test output path: " + myTestOutputPath;
+ rootModel.getModuleExtension(CompilerModuleExtension.class).setCompilerOutputPathForTests(virtualFile);
+ rootModel.getModuleExtension(CompilerModuleExtension.class).inheritCompilerOutputPath(false);
+ rootModel.getModuleExtension(CompilerModuleExtension.class).setExcludeOutput(false);
+ }
+ }
+
+ protected void libraryCreated(Library library, Module module) {}
+
+ private static class Lib {
+ private final String myName;
+ private final Map<OrderRootType, String []> myRoots;
+
+ public Lib(final String name, final Map<OrderRootType, String[]> roots) {
+ myName = name;
+ myRoots = roots;
+ }
+
+ public String getName() {
+ return myName;
+ }
+
+ public String [] getRoots(OrderRootType rootType) {
+ final String[] roots = myRoots.get(rootType);
+ return roots != null ? roots : ArrayUtil.EMPTY_STRING_ARRAY;
+ }
+ }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaTestFixtureFactoryImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaTestFixtureFactoryImpl.java
new file mode 100644
index 0000000..d4e85df
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaTestFixtureFactoryImpl.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2009 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.fixtures.impl;
+
+import com.intellij.testFramework.LightProjectDescriptor;
+import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
+import com.intellij.testFramework.fixtures.*;
+
+/**
+ * @author yole
+ */
+public class JavaTestFixtureFactoryImpl extends JavaTestFixtureFactory {
+ public JavaTestFixtureFactoryImpl() {
+ IdeaTestFixtureFactory.getFixtureFactory().registerFixtureBuilder(JavaModuleFixtureBuilder.class, MyJavaModuleFixtureBuilderImpl.class);
+ }
+
+ @Override
+ public JavaCodeInsightTestFixture createCodeInsightFixture(IdeaProjectTestFixture projectFixture) {
+ return new JavaCodeInsightTestFixtureImpl(projectFixture, new TempDirTestFixtureImpl());
+ }
+
+ @Override
+ public JavaCodeInsightTestFixture createCodeInsightFixture(IdeaProjectTestFixture projectFixture, TempDirTestFixture tempDirFixture) {
+ return new JavaCodeInsightTestFixtureImpl(projectFixture, tempDirFixture);
+ }
+
+ @Override
+ public TestFixtureBuilder<IdeaProjectTestFixture> createLightFixtureBuilder() {
+ return new LightTestFixtureBuilderImpl<IdeaProjectTestFixture>(new LightIdeaTestFixtureImpl(ourJavaProjectDescriptor));
+ }
+
+ public static class MyJavaModuleFixtureBuilderImpl extends JavaModuleFixtureBuilderImpl {
+ public MyJavaModuleFixtureBuilderImpl(final TestFixtureBuilder<? extends IdeaProjectTestFixture> testFixtureBuilder) {
+ super(testFixtureBuilder);
+ }
+
+ @Override
+ protected ModuleFixture instantiateFixture() {
+ return new ModuleFixtureImpl(this);
+ }
+ }
+
+ private static final LightProjectDescriptor ourJavaProjectDescriptor = LightCodeInsightFixtureTestCase.JAVA_1_6;
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/package.html b/java/testFramework/src/com/intellij/testFramework/package.html
new file mode 100644
index 0000000..960f5c5
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/package.html
@@ -0,0 +1,4 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides a test framework for writing tests which use IDEA projects, PSI and other services.
+</body></html>
diff --git a/java/testFramework/testFramework-java.iml b/java/testFramework/testFramework-java.iml
new file mode 100644
index 0000000..408e30d
--- /dev/null
+++ b/java/testFramework/testFramework-java.iml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="openapi" exported="" />
+ <orderEntry type="module" module-name="util" exported="" />
+ <orderEntry type="library" name="JUnit4" level="project" />
+ <orderEntry type="library" name="JDOM" level="project" />
+ <orderEntry type="library" name="Log4J" level="project" />
+ <orderEntry type="module" module-name="lang-api" exported="" />
+ <orderEntry type="module" module-name="lang-impl" exported="" />
+ <orderEntry type="module" module-name="compiler-impl" />
+ <orderEntry type="module" module-name="java-impl" exported="" />
+ <orderEntry type="module" module-name="execution-impl" exported="" scope="RUNTIME" />
+ <orderEntry type="library" name="Groovy" level="project" />
+ <orderEntry type="module" module-name="testFramework" exported="" />
+ <orderEntry type="module" module-name="relaxng" exported="" scope="TEST" />
+ <orderEntry type="module" module-name="idea-ui" exported="" />
+ </component>
+ <component name="copyright">
+ <Base>
+ <setting name="state" value="1" />
+ </Base>
+ </component>
+</module>
+