lite tests rewrite
[fedora-idea.git] / source / com / intellij / testFramework / fixtures / impl / CodeInsightTestFixtureImpl.java
blob0ce211b7de576da239f181a1487d79acce3e9cac
1 /*
2 * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
3 */
5 package com.intellij.testFramework.fixtures.impl;
7 import com.intellij.codeHighlighting.HighlightDisplayLevel;
8 import com.intellij.codeInsight.CodeInsightActionHandler;
9 import com.intellij.codeInsight.TargetElementUtilBase;
10 import com.intellij.codeInsight.completion.CodeCompletionHandler;
11 import com.intellij.codeInsight.completion.LookupData;
12 import com.intellij.codeInsight.completion.actions.CodeCompletionAction;
13 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
14 import com.intellij.codeInsight.daemon.impl.GeneralHighlightingPass;
15 import com.intellij.codeInsight.daemon.impl.HighlightInfo;
16 import com.intellij.codeInsight.daemon.impl.LocalInspectionsPass;
17 import com.intellij.codeInsight.daemon.impl.PostHighlightingPass;
18 import com.intellij.codeInsight.intention.IntentionAction;
19 import com.intellij.codeInsight.intention.IntentionManager;
20 import com.intellij.codeInsight.lookup.Lookup;
21 import com.intellij.codeInsight.lookup.LookupItem;
22 import com.intellij.codeInsight.lookup.LookupManager;
23 import com.intellij.codeInspection.InspectionProfileEntry;
24 import com.intellij.codeInspection.InspectionToolProvider;
25 import com.intellij.codeInspection.LocalInspectionTool;
26 import com.intellij.codeInspection.ModifiableModel;
27 import com.intellij.codeInspection.ex.InspectionProfileImpl;
28 import com.intellij.codeInspection.ex.InspectionTool;
29 import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
30 import com.intellij.ide.DataManager;
31 import com.intellij.lang.findUsages.FindUsagesProvider;
32 import com.intellij.lang.findUsages.LanguageFindUsages;
33 import com.intellij.mock.MockProgressIndicator;
34 import com.intellij.openapi.Disposable;
35 import com.intellij.openapi.application.Result;
36 import com.intellij.openapi.application.RunResult;
37 import com.intellij.openapi.command.WriteCommandAction;
38 import com.intellij.openapi.editor.Document;
39 import com.intellij.openapi.editor.Editor;
40 import com.intellij.openapi.editor.EditorFactory;
41 import com.intellij.openapi.editor.RangeMarker;
42 import com.intellij.openapi.editor.actionSystem.EditorActionManager;
43 import com.intellij.openapi.editor.actionSystem.TypedAction;
44 import com.intellij.openapi.editor.ex.DocumentEx;
45 import com.intellij.openapi.editor.markup.GutterIconRenderer;
46 import com.intellij.openapi.extensions.ExtensionPoint;
47 import com.intellij.openapi.extensions.ExtensionPointName;
48 import com.intellij.openapi.extensions.ExtensionsArea;
49 import com.intellij.openapi.fileEditor.FileEditorManager;
50 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
51 import com.intellij.openapi.fileTypes.FileType;
52 import com.intellij.openapi.fileTypes.FileTypeManager;
53 import com.intellij.openapi.fileTypes.StdFileTypes;
54 import com.intellij.openapi.project.Project;
55 import com.intellij.openapi.roots.ModuleRootManager;
56 import com.intellij.openapi.util.Disposer;
57 import com.intellij.openapi.util.Pair;
58 import com.intellij.openapi.util.Ref;
59 import com.intellij.openapi.util.TextRange;
60 import com.intellij.openapi.util.io.FileUtil;
61 import com.intellij.openapi.util.text.StringUtil;
62 import com.intellij.openapi.vfs.*;
63 import com.intellij.profile.codeInspection.InspectionProfileManager;
64 import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
65 import com.intellij.psi.*;
66 import com.intellij.psi.impl.JavaPsiFacadeEx;
67 import com.intellij.psi.impl.PsiManagerImpl;
68 import com.intellij.psi.impl.source.PostprocessReformattingAspect;
69 import com.intellij.psi.impl.source.PsiFileImpl;
70 import com.intellij.psi.impl.source.resolve.FileContextUtil;
71 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
72 import com.intellij.psi.search.GlobalSearchScope;
73 import com.intellij.psi.search.UsageSearchContext;
74 import com.intellij.psi.search.searches.ReferencesSearch;
75 import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor;
76 import com.intellij.refactoring.rename.RenameProcessor;
77 import com.intellij.testFramework.ExpectedHighlightingData;
78 import com.intellij.testFramework.UsefulTestCase;
79 import com.intellij.testFramework.fixtures.CodeInsightTestFixture;
80 import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
81 import com.intellij.testFramework.fixtures.TempDirTestFixture;
82 import com.intellij.util.Function;
83 import com.intellij.util.SmartList;
84 import com.intellij.util.containers.ContainerUtil;
85 import gnu.trove.THashMap;
86 import gnu.trove.THashSet;
87 import junit.framework.Assert;
88 import junit.framework.TestCase;
89 import org.jetbrains.annotations.NonNls;
90 import org.jetbrains.annotations.NotNull;
91 import org.jetbrains.annotations.Nullable;
93 import java.io.File;
94 import java.io.IOException;
95 import java.io.OutputStream;
96 import java.util.*;
98 /**
99 * @author Dmitry Avdeev
101 public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsightTestFixture {
103 @NonNls private static final String PROFILE = "Configurable";
105 private PsiManagerImpl myPsiManager;
106 private PsiFile myFile;
107 private Editor myEditor;
108 private String myTestDataPath;
110 private LocalInspectionTool[] myInspections;
111 private final Map<String, LocalInspectionTool> myAvailableTools = new THashMap<String, LocalInspectionTool>();
112 private final Map<String, LocalInspectionToolWrapper> myAvailableLocalTools = new THashMap<String, LocalInspectionToolWrapper>();
114 private final TempDirTestFixture myTempDirFixture = new TempDirTextFixtureImpl();
115 private final IdeaProjectTestFixture myProjectFixture;
116 private final Set<VirtualFile> myAddedClasses = new THashSet<VirtualFile>();
117 @NonNls private static final String XXX = "XXX";
118 private PsiElement myFileContext;
120 public CodeInsightTestFixtureImpl(IdeaProjectTestFixture projectFixture) {
121 myProjectFixture = projectFixture;
124 public void setTestDataPath(String dataPath) {
125 myTestDataPath = dataPath;
128 public String getTempDirPath() {
129 return myTempDirFixture.getTempDirPath();
132 public TempDirTestFixture getTempDirFixture() {
133 return myTempDirFixture;
136 public String copyFileToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath) throws IOException {
137 final File destFile = new File(getTempDirPath() + "/" + targetPath);
138 FileUtil.copy(new File(sourceFilePath), destFile);
139 Assert.assertNotNull(LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile));
140 return targetPath;
143 public String copyFileToProject(@NonNls final String sourceFilePath) throws IOException {
144 return copyFileToProject(sourceFilePath, StringUtil.getShortName(StringUtil.getShortName(sourceFilePath, '\\'), '/'));
147 public void enableInspections(LocalInspectionTool... inspections) {
148 myInspections = inspections;
149 if (isInitialized()) {
150 configureInspections(myInspections);
154 private boolean isInitialized() {
155 return myPsiManager != null;
158 public void enableInspections(final Class<? extends LocalInspectionTool>... inspections) {
159 final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
160 for (Class clazz: inspections) {
161 try {
162 LocalInspectionTool inspection = (LocalInspectionTool)clazz.getConstructor().newInstance();
163 tools.add(inspection);
165 catch (Exception e) {
166 throw new RuntimeException("Cannot instantiate " + clazz);
169 enableInspections(tools.toArray(new LocalInspectionTool[tools.size()]));
172 public void disableInspections(LocalInspectionTool... inspections) {
173 myAvailableTools.clear();
174 myAvailableLocalTools.clear();
175 final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>(Arrays.asList(myInspections));
176 for (Iterator<LocalInspectionTool> i = tools.iterator(); i.hasNext();) {
177 final LocalInspectionTool tool = i.next();
178 for (LocalInspectionTool toRemove: inspections) {
179 if (tool.getShortName().equals(toRemove.getShortName())) {
180 i.remove();
181 break;
185 myInspections = tools.toArray(new LocalInspectionTool[tools.size()]);
186 configureInspections(myInspections);
189 public void enableInspections(InspectionToolProvider... providers) {
190 final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
191 for (InspectionToolProvider provider: providers) {
192 for (Class clazz: provider.getInspectionClasses()) {
193 try {
194 LocalInspectionTool inspection = (LocalInspectionTool)clazz.getConstructor().newInstance();
195 tools.add(inspection);
197 catch (Exception e) {
198 throw new RuntimeException("Cannot instantiate " + clazz);
202 myInspections = tools.toArray(new LocalInspectionTool[tools.size()]);
203 configureInspections(myInspections);
206 public long testHighlighting(final boolean checkWarnings,
207 final boolean checkInfos,
208 final boolean checkWeakWarnings,
209 final String... filePaths) throws Throwable {
211 final Ref<Long> duration = new Ref<Long>();
212 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
214 protected void run() throws Throwable {
215 configureByFilesInner(filePaths);
216 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
218 }.execute().throwException();
219 return duration.get().longValue();
222 public long checkHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings) throws Throwable {
223 final Ref<Long> duration = new Ref<Long>();
224 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
225 protected void run() throws Throwable {
226 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
228 }.execute().throwException();
229 return duration.get().longValue();
232 public long checkHighlighting() throws Throwable {
233 return checkHighlighting(true, true, true);
236 public long testHighlighting(final String... filePaths) throws Throwable {
237 return testHighlighting(true, true, true, filePaths);
240 public long testHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings, final VirtualFile file) throws Throwable {
241 final Ref<Long> duration = new Ref<Long>();
242 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
243 protected void run() throws Throwable {
244 myFile = myPsiManager.findFile(file);
245 myEditor = createEditor(file);
246 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
248 }.execute().throwException();
249 return duration.get().longValue();
252 @Nullable
253 public PsiReference getReferenceAtCaretPosition(final String filePath) throws Throwable {
254 final RunResult<PsiReference> runResult = new WriteCommandAction<PsiReference>(myProjectFixture.getProject()) {
255 protected void run(final Result<PsiReference> result) throws Throwable {
256 configureByFilesInner(filePath);
257 final int offset = myEditor.getCaretModel().getOffset();
258 final PsiReference psiReference = getFile().findReferenceAt(offset);
259 result.setResult(psiReference);
261 }.execute();
262 runResult.throwException();
263 return runResult.getResultObject();
266 @NotNull
267 public PsiReference getReferenceAtCaretPositionWithAssertion(final String filePath) throws Throwable {
268 final PsiReference reference = getReferenceAtCaretPosition(filePath);
269 assert reference != null: "no reference found at " + myEditor.getCaretModel().getLogicalPosition();
270 return reference;
273 @NotNull
274 public List<IntentionAction> getAvailableIntentions(final String... filePaths) throws Throwable {
276 final Project project = myProjectFixture.getProject();
277 return new WriteCommandAction<List<IntentionAction>>(project) {
278 protected void run(final Result<List<IntentionAction>> result) throws Throwable {
279 final int offset = configureByFilesInner(filePaths);
280 result.setResult(getAvailableIntentions(project, doHighlighting(), offset, myEditor, myFile));
282 }.execute().getResultObject();
285 public void launchAction(@NotNull final IntentionAction action) throws Throwable {
286 new WriteCommandAction(myProjectFixture.getProject()) {
287 protected void run(final Result result) throws Throwable {
288 action.invoke(getProject(), getEditor(), getFile());
290 }.execute().throwException();
294 public void testCompletion(final String[] filesBefore, final String fileAfter) throws Throwable {
295 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
297 protected void run() throws Throwable {
298 configureByFilesInner(filesBefore);
299 completeBasic();
300 checkResultByFile(fileAfter, myFile, false);
302 }.execute().throwException();
305 public void testCompletion(String fileBefore, String fileAfter) throws Throwable {
306 testCompletion(new String[] { fileBefore }, fileAfter);
309 public void testCompletionVariants(final String fileBefore, final String... expectedItems) throws Throwable {
310 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
312 protected void run() throws Throwable {
313 configureByFilesInner(fileBefore);
314 LookupItem[] lookupItems = completeBasic();
315 UsefulTestCase.assertNotNull("No lookup was shown, probably there was only one lookup element that was inserted automatically", lookupItems);
316 UsefulTestCase.assertSameElements(ContainerUtil.map(lookupItems, new Function<LookupItem, String>() {
317 public String fun(final LookupItem lookupItem) {
318 return lookupItem.getLookupString();
320 }), expectedItems);
322 }.execute().throwException();
325 public void testRename(final String fileBefore, final String fileAfter, final String newName) throws Throwable {
326 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
327 protected void run() throws Throwable {
328 configureByFilesInner(fileBefore);
330 }.execute().throwException();
331 testRename(fileAfter, newName);
334 public void testRename(final String fileAfter, final String newName) throws Throwable {
335 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
336 protected void run() throws Throwable {
337 PsiElement element = TargetElementUtilBase.findTargetElement(myEditor, TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
338 assert element != null: "element not found at caret position, offset " + myEditor.getCaretModel().getOffset();
339 new RenameProcessor(myProjectFixture.getProject(), element, newName, false, false).run();
340 checkResultByFile(fileAfter, myFile, false);
342 }.execute().throwException();
345 public void type(final char c) {
346 EditorActionManager actionManager = EditorActionManager.getInstance();
347 TypedAction action = actionManager.getTypedAction();
348 action.actionPerformed(getEditor(), c, DataManager.getInstance().getDataContext());
351 public JavaPsiFacade getJavaFacade() {
352 return JavaPsiFacade.getInstance(getProject());
355 public PsiReference[] testFindUsages(@NonNls final String... fileNames) throws Throwable {
356 configureByFiles(fileNames);
357 FindUsagesProvider handler = LanguageFindUsages.INSTANCE.forLanguage(getFile().getLanguage());
358 PsiElement referenceTo = TargetElementUtilBase
359 .findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
361 assert referenceTo != null && handler.canFindUsagesFor(referenceTo) : "Cannot find element in caret";
362 final Project project = getProject();
363 return ReferencesSearch.search(referenceTo, GlobalSearchScope.projectScope(project), false).toArray(new PsiReference[0]);
366 public void moveFile(@NonNls final String filePath, @NonNls final String to) throws Throwable {
367 final Project project = myProjectFixture.getProject();
368 new WriteCommandAction.Simple(project) {
369 protected void run() throws Throwable {
370 configureByFile(filePath);
371 final VirtualFile file = findFile(to);
372 assert file.isDirectory() : to + " is not a directory";
373 final PsiDirectory directory = myPsiManager.findDirectory(file);
374 new MoveFilesOrDirectoriesProcessor(project, new PsiElement[] {myFile}, directory,
375 false, false, null, null).run();
377 }.execute().throwException();
381 @Nullable
382 public GutterIconRenderer findGutter(final String filePath) throws Throwable {
383 final Project project = myProjectFixture.getProject();
384 final Ref<GutterIconRenderer> result = new Ref<GutterIconRenderer>();
385 new WriteCommandAction.Simple(project) {
387 protected void run() throws Throwable {
388 final int offset = configureByFilesInner(filePath);
390 final Collection<HighlightInfo> infos = doHighlighting();
391 for (HighlightInfo info :infos) {
392 if (info.endOffset >= offset && info.startOffset <= offset) {
393 final GutterIconRenderer renderer = info.getGutterIconRenderer();
394 if (renderer != null) {
395 result.set(renderer);
396 return;
402 }.execute().throwException();
403 return result.get();
406 @NotNull
407 public Collection<GutterIconRenderer> findAllGutters(final String filePath) throws Throwable {
408 final Project project = myProjectFixture.getProject();
409 final SortedMap<HighlightInfo, List<GutterIconRenderer>> result = new TreeMap<HighlightInfo, List<GutterIconRenderer>>(new Comparator<HighlightInfo>() {
410 public int compare(final HighlightInfo o1, final HighlightInfo o2) {
411 return o1.startOffset - o2.startOffset;
414 new WriteCommandAction.Simple(project) {
416 protected void run() throws Throwable {
417 configureByFilesInner(filePath);
419 final Collection<HighlightInfo> infos = doHighlighting();
420 for (HighlightInfo info :infos) {
421 final GutterIconRenderer renderer = info.getGutterIconRenderer();
422 if (renderer != null) {
423 List<GutterIconRenderer> renderers = result.get(info);
424 if (renderers == null) {
425 result.put(info, renderers = new SmartList<GutterIconRenderer>());
427 renderers.add(renderer);
432 }.execute().throwException();
433 return ContainerUtil.concat(result.values());
436 public PsiClass addClass(@NotNull @NonNls final String classText) throws IOException {
437 final PsiClass aClass = ((PsiJavaFile)PsiFileFactory.getInstance(getProject()).createFileFromText("a.java", classText)).getClasses()[0];
438 final String qName = aClass.getQualifiedName();
439 assert qName != null;
441 final VirtualFile root = ModuleRootManager.getInstance(myProjectFixture.getModule()).getSourceRoots()[0];
442 final VirtualFile dir = VfsUtil.createDirectories(root.getPath() + "/" + StringUtil.getPackageName(qName).replace('.', '/'));
443 final VirtualFile virtualFile = dir.createChildData(this, StringUtil.getShortName(qName) + ".java");
444 VfsUtil.saveText(virtualFile, classText);
445 myAddedClasses.add(virtualFile);
446 return ((PsiJavaFile)getPsiManager().findFile(virtualFile)).getClasses()[0];
449 public <T> void registerExtension(final ExtensionsArea area, final ExtensionPointName<T> epName, final T extension) {
450 final ExtensionPoint<T> extensionPoint = area.getExtensionPoint(epName);
451 extensionPoint.registerExtension(extension);
452 disposeOnTearDown(new Disposable() {
453 public void dispose() {
454 extensionPoint.unregisterExtension(extension);
459 public PsiManager getPsiManager() {
460 return myPsiManager;
463 @Nullable
464 protected Editor getCompletionEditor() {
465 return InjectedLanguageUtil.getEditorForInjectedLanguage(myEditor, myFile);
469 @Nullable
470 public LookupItem[] completeBasic() {
471 return new WriteCommandAction<LookupItem[]>(getProject()) {
472 protected void run(final Result<LookupItem[]> result) throws Throwable {
473 new CodeCompletionAction() {
474 public CodeInsightActionHandler getHandler() {
475 return new CodeCompletionHandler() {
476 protected PsiFile createFileCopy(final PsiFile file) {
477 final PsiFile copy = super.createFileCopy(file);
478 if (myFileContext != null) {
479 final PsiElement contextCopy = myFileContext.copy();
480 final PsiFile containingFile = contextCopy.getContainingFile();
481 if (containingFile instanceof PsiFileImpl) {
482 ((PsiFileImpl)containingFile).setOriginalFile(myFileContext.getContainingFile());
484 setContext(copy, contextCopy);
486 return copy;
489 protected Lookup showLookup(final Project project, final Editor editor, final LookupItem[] items, final String prefix, final LookupData data,
490 final PsiFile file,
491 final String bottomText) {
492 result.setResult(items);
493 return super.showLookup(project, editor, items, prefix, data, file, bottomText);
497 }.actionPerformedImpl(getProject(), InjectedLanguageUtil.getEditorForInjectedLanguage(myEditor, myFile));
500 }.execute().getResultObject();
503 public void checkResult(final String text) throws IOException {
504 PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
505 checkResult("TEXT", false, SelectionAndCaretMarkupLoader.fromText(text, getProject()), myFile.getText());
508 public void checkResultByFile(final String filePath) throws Throwable {
509 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
511 protected void run() throws Throwable {
512 checkResultByFile(filePath, myFile, false);
514 }.execute().throwException();
517 public void checkResultByFile(final String filePath, final String expectedFile, final boolean ignoreWhitespaces) throws Throwable {
519 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
521 protected void run() throws Throwable {
522 String fullPath = getTempDirPath() + "/" + filePath;
523 final VirtualFile copy = LocalFileSystem.getInstance().refreshAndFindFileByPath(fullPath.replace(File.separatorChar, '/'));
524 assert copy != null : "file not found: " + fullPath;
525 final PsiFile psiFile = myPsiManager.findFile(copy);
526 assert psiFile != null;
527 checkResultByFile(expectedFile, psiFile, ignoreWhitespaces);
529 }.execute().throwException();
532 public void setUp() throws Exception {
533 super.setUp();
535 final String testDataPath = getTestDataPath();
536 if (testDataPath != null) {
537 FileUtil.copyDir(new File(testDataPath), new File(getTempDirPath()), false);
539 myProjectFixture.setUp();
540 myTempDirFixture.setUp();
541 myPsiManager = (PsiManagerImpl)PsiManager.getInstance(getProject());
542 configureInspections(myInspections == null ? new LocalInspectionTool[0] : myInspections);
545 private void enableInspectionTool(LocalInspectionTool tool){
546 final String shortName = tool.getShortName();
547 final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
548 if (key == null){
549 HighlightDisplayKey.register(shortName, tool.getDisplayName(), tool.getID());
551 myAvailableTools.put(shortName, tool);
552 myAvailableLocalTools.put(shortName, new LocalInspectionToolWrapper(tool));
555 private void configureInspections(final LocalInspectionTool[] tools) {
556 for (LocalInspectionTool tool : tools) {
557 enableInspectionTool(tool);
560 final InspectionProfileImpl profile = new InspectionProfileImpl(PROFILE) {
561 public ModifiableModel getModifiableModel() {
562 mySource = this;
563 return this;
566 public InspectionProfileEntry[] getInspectionTools() {
567 final Collection<LocalInspectionToolWrapper> tools = myAvailableLocalTools.values();
568 return tools.toArray(new LocalInspectionToolWrapper[tools.size()]);
571 public boolean isToolEnabled(HighlightDisplayKey key) {
572 return key != null && key.toString() != null && myAvailableTools != null && myAvailableTools.containsKey(key.toString());
575 public HighlightDisplayLevel getErrorLevel(HighlightDisplayKey key) {
576 final LocalInspectionTool localInspectionTool = myAvailableTools.get(key.toString());
577 return localInspectionTool != null ? localInspectionTool.getDefaultLevel() : HighlightDisplayLevel.WARNING;
580 public InspectionTool getInspectionTool(String shortName) {
581 return myAvailableLocalTools.get(shortName);
584 final InspectionProfileManager inspectionProfileManager = InspectionProfileManager.getInstance();
585 inspectionProfileManager.addProfile(profile);
586 Disposer.register(getProject(), new Disposable() {
587 public void dispose() {
588 inspectionProfileManager.deleteProfile(PROFILE);
591 inspectionProfileManager.setRootProfile(profile.getName());
592 InspectionProjectProfileManager.getInstance(getProject()).updateProfile(profile);
595 public void tearDown() throws Exception {
596 LookupManager.getInstance(getProject()).hideActiveLookup();
598 FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
599 VirtualFile[] openFiles = editorManager.getOpenFiles();
600 for (VirtualFile openFile : openFiles) {
601 editorManager.closeFile(openFile);
604 myProjectFixture.tearDown();
605 myTempDirFixture.tearDown();
607 super.tearDown();
610 private int configureByFilesInner(@NonNls String... filePaths) throws IOException {
611 myFile = null;
612 myEditor = null;
613 int offset = -1;
614 for (int i = filePaths.length - 1; i >= 0; i--) {
615 String filePath = filePaths[i];
616 int fileOffset = configureByFileInner(filePath);
617 if (fileOffset > 0) {
618 offset = fileOffset;
621 return offset;
624 public void configureByFile(final String file) throws IOException {
625 new WriteCommandAction.Simple(getProject()) {
626 protected void run() throws Throwable {
627 configureByFileInner(file);
629 }.execute();
632 public void configureByFiles(@NonNls final String... files) throws Throwable {
633 new WriteCommandAction.Simple(getProject()) {
634 protected void run() throws Throwable {
635 configureByFilesInner(files);
637 }.execute();
640 public PsiFile configureByText(final FileType fileType, @NonNls final String text) throws Throwable {
641 final String extension = fileType.getDefaultExtension();
642 final File tempFile = File.createTempFile("aaa", "." + extension, new File(getTempDirPath()));
643 final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
644 if (fileTypeManager.getFileTypeByExtension(extension) != fileType) {
645 fileTypeManager.associateExtension(fileType, extension);
647 final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile);
648 VfsUtil.saveText(vFile, text);
649 configureInner(vFile, SelectionAndCaretMarkupLoader.fromFile(vFile, getProject()));
650 return myFile;
653 public Document getDocument(final PsiFile file) {
654 return PsiDocumentManager.getInstance(getProject()).getDocument(file);
657 public void setFileContext(@Nullable final PsiElement context) {
658 myFileContext = context;
659 setContext(myFile, context);
664 * @param filePath
665 * @return caret offset or -1 if caret marker does not present
666 * @throws IOException
668 private int configureByFileInner(@NonNls String filePath) throws IOException {
669 return configureByFileInner(findFile(filePath));
672 private int configureByFileInner(final VirtualFile copy) throws IOException {
673 return configureInner(copy, SelectionAndCaretMarkupLoader.fromFile(copy, getProject()));
676 private int configureInner(final VirtualFile copy, final SelectionAndCaretMarkupLoader loader) {
677 try {
678 final OutputStream outputStream = copy.getOutputStream(null, 0, 0);
679 outputStream.write(loader.newFileText.getBytes());
680 outputStream.close();
682 catch (IOException e) {
683 throw new RuntimeException(e);
685 myFile = myPsiManager.findFile(copy);
686 setContext(myFile, myFileContext);
687 int offset = -1;
688 myEditor = createEditor(copy);
689 assert myEditor != null;
690 if (loader.caretMarker != null) {
691 offset = loader.caretMarker.getStartOffset();
692 myEditor.getCaretModel().moveToOffset(offset);
694 if (loader.selStartMarker != null && loader.selEndMarker != null) {
695 myEditor.getSelectionModel().setSelection(loader.selStartMarker.getStartOffset(), loader.selEndMarker.getStartOffset());
697 return offset;
700 private static void setContext(final PsiFile file, final PsiElement context) {
701 if (file != null && context != null) {
702 file.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, new SmartPsiElementPointer() {
703 public PsiElement getElement() {
704 return context;
710 private VirtualFile findFile(final String filePath) {
711 String fullPath = getTempDirPath() + "/" + filePath;
713 final VirtualFile copy = LocalFileSystem.getInstance().refreshAndFindFileByPath(fullPath.replace(File.separatorChar, '/'));
714 assert copy != null: "file " + fullPath + " not found";
715 return copy;
718 @Nullable
719 private Editor createEditor(VirtualFile file) {
720 final Project project = getProject();
721 final FileEditorManager instance = FileEditorManager.getInstance(project);
722 if (file.getFileType().isBinary()) {
723 return null;
725 return instance.openTextEditor(new OpenFileDescriptor(project, file, 0), false);
728 private void collectAndCheckHighlightings(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, Ref<Long> duration)
729 throws Exception {
730 final Project project = getProject();
731 ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
733 PsiDocumentManager.getInstance(project).commitAllDocuments();
735 ((PsiFileImpl)myFile).calcTreeElement(); //to load text
737 //to initialize caches
738 myPsiManager.getCacheManager().getFilesWithWord(XXX, UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(project), true);
739 VirtualFileFilter javaFilesFilter = new VirtualFileFilter() {
740 public boolean accept(VirtualFile file) {
741 if (myAddedClasses.contains(file)) return false;
743 FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file);
744 return fileType == StdFileTypes.JAVA || fileType == StdFileTypes.CLASS;
748 JavaPsiFacadeEx.getInstanceEx(project).setAssertOnFileLoadingFilter(javaFilesFilter); // check repository work
750 final long start = System.currentTimeMillis();
751 // ProfilingUtil.startCPUProfiling();
752 Collection<HighlightInfo> infos = doHighlighting();
753 duration.set(System.currentTimeMillis() - start);
754 // ProfilingUtil.captureCPUSnapshot("testing");
756 JavaPsiFacadeEx.getInstanceEx(project).setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
758 data.checkResult(infos, myEditor.getDocument().getText());
761 @NotNull
762 private Collection<HighlightInfo> doHighlighting() {
764 final Project project = myProjectFixture.getProject();
766 PsiDocumentManager.getInstance(project).commitAllDocuments();
768 Document document = myEditor.getDocument();
769 GeneralHighlightingPass action1 = new GeneralHighlightingPass(project, myFile, document, 0, myFile.getTextLength(), true);
770 action1.doCollectInformation(new MockProgressIndicator());
771 Collection<HighlightInfo> highlights1 = action1.getHighlights();
773 PostHighlightingPass action2 = new PostHighlightingPass(project, myFile, myEditor, 0, myFile.getTextLength());
774 action2.doCollectInformation(new MockProgressIndicator());
775 Collection<HighlightInfo> highlights2 = action2.getHighlights();
777 Collection<HighlightInfo> highlights3 = null;
778 if (myAvailableTools.size() > 0) {
779 LocalInspectionsPass inspectionsPass = new LocalInspectionsPass(myFile, myEditor.getDocument(), 0, myFile.getTextLength());
780 inspectionsPass.doCollectInformation(new MockProgressIndicator());
781 highlights3 = inspectionsPass.getHighlights();
784 ArrayList<HighlightInfo> list = new ArrayList<HighlightInfo>();
785 list.addAll(highlights1);
786 list.addAll(highlights2);
787 if (highlights3 != null) {
788 list.addAll(highlights3);
790 return list;
793 private String getTestDataPath() {
794 return myTestDataPath;
797 public Project getProject() {
798 return myProjectFixture.getProject();
801 public Editor getEditor() {
802 return myEditor;
805 public PsiFile getFile() {
806 return myFile;
809 public static List<IntentionAction> getAvailableIntentions(final Project project, final Collection<HighlightInfo> infos, final int offset,
810 final Editor editor, final PsiFile file) {
811 final List<IntentionAction> availableActions = new ArrayList<IntentionAction>();
813 for (HighlightInfo info :infos) {
814 if (info.quickFixActionRanges != null) {
815 for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
816 if (offset > 0 && !pair.getSecond().contains(offset)) {
817 continue;
819 final HighlightInfo.IntentionActionDescriptor actionDescriptor = pair.first;
820 final IntentionAction action = actionDescriptor.getAction();
821 if (action.isAvailable(project, editor, file)) {
822 availableActions.add(action);
823 final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
824 assert element != null;
825 final List<IntentionAction> actions = actionDescriptor.getOptions(element);
826 if (actions != null) {
827 for (IntentionAction intentionAction : actions) {
828 if (intentionAction.isAvailable(project, editor, file)) {
829 availableActions.add(intentionAction);
838 for (IntentionAction intentionAction : IntentionManager.getInstance().getIntentionActions()) {
839 if (intentionAction.isAvailable(project, editor, file)) {
840 availableActions.add(intentionAction);
843 return availableActions;
846 static class SelectionAndCaretMarkupLoader {
847 final String newFileText;
848 final RangeMarker caretMarker;
849 final RangeMarker selStartMarker;
850 final RangeMarker selEndMarker;
852 static SelectionAndCaretMarkupLoader fromFile(String path, Project project) throws IOException {
853 return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(new String(FileUtil.loadFileText(new File(path)))), project);
855 static SelectionAndCaretMarkupLoader fromFile(VirtualFile file, Project project) throws IOException {
856 return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(new String(VfsUtil.loadText(file))), project);
859 static SelectionAndCaretMarkupLoader fromText(String text, Project project) throws IOException {
860 return new SelectionAndCaretMarkupLoader(text, project);
863 private SelectionAndCaretMarkupLoader(String fileText, Project project) throws IOException {
864 final Document document = EditorFactory.getInstance().createDocument(fileText);
866 int caretIndex = fileText.indexOf(CARET_MARKER);
867 int selStartIndex = fileText.indexOf(SELECTION_START_MARKER);
868 int selEndIndex = fileText.indexOf(SELECTION_END_MARKER);
870 caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
871 selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
872 selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
874 new WriteCommandAction(project) {
875 protected void run(Result result) throws Throwable {
876 if (caretMarker != null) {
877 document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
879 if (selStartMarker != null) {
880 document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
882 if (selEndMarker != null) {
883 document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
886 }.execute();
888 newFileText = document.getText();
892 private void checkResultByFile(@NonNls String expectedFile,
893 @NotNull PsiFile originalFile,
894 boolean stripTrailingSpaces) throws IOException {
895 PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
896 checkResult(expectedFile, stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromFile(getTestDataPath() + "/" + expectedFile, getProject()), originalFile.getText());
899 private void checkResult(final String expectedFile,
900 final boolean stripTrailingSpaces,
901 final SelectionAndCaretMarkupLoader markupLoader,
902 String actualText) {
903 Project project = myProjectFixture.getProject();
905 project.getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
906 if (stripTrailingSpaces) {
907 ((DocumentEx)myEditor.getDocument()).stripTrailingSpaces(false);
910 PsiDocumentManager.getInstance(project).commitAllDocuments();
912 SelectionAndCaretMarkupLoader loader = markupLoader;
913 String newFileText1 = loader.newFileText;
914 if (stripTrailingSpaces) {
915 Document document1 = EditorFactory.getInstance().createDocument(loader.newFileText);
916 ((DocumentEx)document1).stripTrailingSpaces(false);
917 newFileText1 = document1.getText();
920 actualText = StringUtil.convertLineSeparators(actualText, "\n");
922 //noinspection HardCodedStringLiteral
923 TestCase.assertEquals( "Text mismatch in file " + expectedFile, newFileText1, actualText );
925 if (loader.caretMarker != null) {
926 int caretLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.caretMarker.getStartOffset());
927 int caretCol = loader.caretMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, caretLine, 0);
929 TestCase.assertEquals("caretLine", caretLine + 1, myEditor.getCaretModel().getLogicalPosition().line + 1);
930 TestCase.assertEquals("caretColumn", caretCol + 1, myEditor.getCaretModel().getLogicalPosition().column + 1);
933 if (loader.selStartMarker != null && loader.selEndMarker != null) {
934 int selStartLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selStartMarker.getStartOffset());
935 int selStartCol = loader.selStartMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0);
937 int selEndLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selEndMarker.getEndOffset());
938 int selEndCol = loader.selEndMarker.getEndOffset() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0);
940 TestCase.assertEquals("selectionStartLine", selStartLine + 1,
941 StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionStart()) + 1);
943 TestCase.assertEquals("selectionStartCol", selStartCol + 1, myEditor.getSelectionModel().getSelectionStart() -
944 StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0) + 1);
946 TestCase.assertEquals("selectionEndLine", selEndLine + 1,
947 StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionEnd()) + 1);
949 TestCase.assertEquals("selectionEndCol", selEndCol + 1,
950 myEditor.getSelectionModel().getSelectionEnd() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0) + 1);
952 else {
953 TestCase.assertTrue("has no selection", !myEditor.getSelectionModel().hasSelection());