Fixed : [RUBY-2713] - Incorrect warning for image_tag argument
[fedora-idea.git] / source / com / intellij / testFramework / fixtures / impl / CodeInsightTestFixtureImpl.java
blobafa83ba16a5397c623a57c6ebb61f5d2799aaffc
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.codeHighlighting.TextEditorHighlightingPass;
9 import com.intellij.codeInsight.CodeInsightActionHandler;
10 import com.intellij.codeInsight.TargetElementUtilBase;
11 import com.intellij.codeInsight.completion.CodeCompletionHandlerBase;
12 import com.intellij.codeInsight.completion.CompletionContext;
13 import com.intellij.codeInsight.completion.CompletionProgressIndicator;
14 import com.intellij.codeInsight.completion.CompletionType;
15 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
16 import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
17 import com.intellij.codeInsight.daemon.impl.HighlightInfo;
18 import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass;
19 import com.intellij.codeInsight.daemon.impl.TextEditorHighlightingPassRegistrarEx;
20 import com.intellij.codeInsight.intention.IntentionAction;
21 import com.intellij.codeInsight.lookup.LookupElement;
22 import com.intellij.codeInsight.lookup.LookupManager;
23 import com.intellij.codeInsight.lookup.impl.LookupImpl;
24 import com.intellij.codeInspection.InspectionProfileEntry;
25 import com.intellij.codeInspection.InspectionToolProvider;
26 import com.intellij.codeInspection.LocalInspectionTool;
27 import com.intellij.codeInspection.ModifiableModel;
28 import com.intellij.codeInspection.ex.InspectionProfileImpl;
29 import com.intellij.codeInspection.ex.InspectionTool;
30 import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
31 import com.intellij.facet.Facet;
32 import com.intellij.facet.FacetManager;
33 import com.intellij.find.findUsages.FindUsagesHandler;
34 import com.intellij.find.findUsages.FindUsagesManager;
35 import com.intellij.find.findUsages.FindUsagesOptions;
36 import com.intellij.ide.DataManager;
37 import com.intellij.mock.MockProgressIndicator;
38 import com.intellij.openapi.Disposable;
39 import com.intellij.openapi.actionSystem.DataContext;
40 import com.intellij.openapi.actionSystem.IdeActions;
41 import com.intellij.openapi.application.ApplicationManager;
42 import com.intellij.openapi.application.ModalityState;
43 import com.intellij.openapi.application.Result;
44 import com.intellij.openapi.command.WriteCommandAction;
45 import com.intellij.openapi.editor.*;
46 import com.intellij.openapi.editor.actionSystem.EditorActionManager;
47 import com.intellij.openapi.editor.ex.DocumentEx;
48 import com.intellij.openapi.editor.ex.util.EditorUtil;
49 import com.intellij.openapi.editor.markup.GutterIconRenderer;
50 import com.intellij.openapi.editor.markup.RangeHighlighter;
51 import com.intellij.openapi.extensions.ExtensionPoint;
52 import com.intellij.openapi.extensions.ExtensionPointName;
53 import com.intellij.openapi.extensions.ExtensionsArea;
54 import com.intellij.openapi.fileEditor.FileEditorManager;
55 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
56 import com.intellij.openapi.fileTypes.FileType;
57 import com.intellij.openapi.fileTypes.FileTypeManager;
58 import com.intellij.openapi.fileTypes.StdFileTypes;
59 import com.intellij.openapi.module.Module;
60 import com.intellij.openapi.project.Project;
61 import com.intellij.openapi.util.*;
62 import com.intellij.openapi.util.io.FileUtil;
63 import com.intellij.openapi.util.text.StringUtil;
64 import com.intellij.openapi.vfs.LocalFileSystem;
65 import com.intellij.openapi.vfs.VfsUtil;
66 import com.intellij.openapi.vfs.VirtualFile;
67 import com.intellij.openapi.vfs.VirtualFileFilter;
68 import com.intellij.profile.codeInspection.InspectionProfileManager;
69 import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
70 import com.intellij.psi.*;
71 import com.intellij.psi.impl.JavaPsiFacadeEx;
72 import com.intellij.psi.impl.PsiManagerImpl;
73 import com.intellij.psi.impl.source.PostprocessReformattingAspect;
74 import com.intellij.psi.impl.source.PsiFileImpl;
75 import com.intellij.psi.impl.source.resolve.FileContextUtil;
76 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
77 import com.intellij.psi.search.GlobalSearchScope;
78 import com.intellij.psi.search.UsageSearchContext;
79 import com.intellij.psi.util.PsiUtilBase;
80 import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor;
81 import com.intellij.refactoring.rename.RenameProcessor;
82 import com.intellij.refactoring.rename.RenamePsiElementProcessor;
83 import com.intellij.testFramework.ExpectedHighlightingData;
84 import com.intellij.testFramework.UsefulTestCase;
85 import com.intellij.testFramework.fixtures.*;
86 import com.intellij.usageView.UsageInfo;
87 import com.intellij.util.ArrayUtil;
88 import com.intellij.util.CommonProcessors;
89 import com.intellij.util.Function;
90 import com.intellij.util.SmartList;
91 import com.intellij.util.containers.ContainerUtil;
92 import gnu.trove.THashMap;
93 import gnu.trove.THashSet;
94 import junit.framework.Assert;
95 import org.jetbrains.annotations.NonNls;
96 import org.jetbrains.annotations.NotNull;
97 import org.jetbrains.annotations.Nullable;
99 import javax.swing.*;
100 import java.io.File;
101 import java.io.IOException;
102 import java.io.OutputStream;
103 import java.util.*;
106 * @author Dmitry Avdeev
108 public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsightTestFixture {
110 @NonNls private static final String PROFILE = "Configurable";
112 private PsiManagerImpl myPsiManager;
113 private PsiFile myFile;
114 private Editor myEditor;
115 private String myTestDataPath;
116 private boolean myEmptyLookup;
118 private LocalInspectionTool[] myInspections;
119 private final Map<String, LocalInspectionTool> myAvailableTools = new THashMap<String, LocalInspectionTool>();
120 private final Map<String, LocalInspectionToolWrapper> myAvailableLocalTools = new THashMap<String, LocalInspectionToolWrapper>();
122 private final TempDirTestFixture myTempDirFixture = new TempDirTestFixtureImpl();
123 private final IdeaProjectTestFixture myProjectFixture;
124 private final Set<VirtualFile> myAddedClasses = new THashSet<VirtualFile>();
125 @NonNls private static final String XXX = "XXX";
126 private PsiElement myFileContext;
128 public CodeInsightTestFixtureImpl(IdeaProjectTestFixture projectFixture) {
129 myProjectFixture = projectFixture;
132 public void setTestDataPath(String dataPath) {
133 myTestDataPath = dataPath;
136 public String getTempDirPath() {
137 return myTempDirFixture.getTempDirPath();
140 public TempDirTestFixture getTempDirFixture() {
141 return myTempDirFixture;
144 public VirtualFile copyFileToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath) throws IOException {
145 final File destFile = new File(getTempDirPath() + "/" + targetPath);
146 if (!destFile.exists()) {
147 File fromFile = new File(getTestDataPath() + "/" + sourceFilePath);
148 if (!fromFile.exists()) {
149 fromFile = new File(sourceFilePath);
152 if (fromFile.isDirectory()) {
153 destFile.mkdirs();
154 } else {
155 FileUtil.copy(fromFile, destFile);
158 final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
159 Assert.assertNotNull(file);
160 return file;
163 public VirtualFile copyDirectoryToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath) throws IOException {
164 final File destFile = new File(getTempDirPath() + "/" + targetPath);
165 final File fromFile = new File(getTestDataPath() + "/" + sourceFilePath);
166 FileUtil.copyDir(fromFile, destFile);
167 final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
168 Assert.assertNotNull(file);
169 file.refresh(false, true);
170 return file;
173 public VirtualFile copyFileToProject(@NonNls final String sourceFilePath) throws IOException {
174 return copyFileToProject(sourceFilePath, sourceFilePath);
177 public void enableInspections(LocalInspectionTool... inspections) {
178 myInspections = inspections;
179 if (isInitialized()) {
180 configureInspections(myInspections);
184 private boolean isInitialized() {
185 return myPsiManager != null;
188 public void enableInspections(final Class<? extends LocalInspectionTool>... inspections) {
189 final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
190 for (Class clazz: inspections) {
191 try {
192 LocalInspectionTool inspection = (LocalInspectionTool)clazz.getConstructor().newInstance();
193 tools.add(inspection);
195 catch (Exception e) {
196 throw new RuntimeException("Cannot instantiate " + clazz);
199 enableInspections(tools.toArray(new LocalInspectionTool[tools.size()]));
202 public void disableInspections(LocalInspectionTool... inspections) {
203 myAvailableTools.clear();
204 myAvailableLocalTools.clear();
205 final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>(Arrays.asList(myInspections));
206 for (Iterator<LocalInspectionTool> i = tools.iterator(); i.hasNext();) {
207 final LocalInspectionTool tool = i.next();
208 for (LocalInspectionTool toRemove: inspections) {
209 if (tool.getShortName().equals(toRemove.getShortName())) {
210 i.remove();
211 break;
215 myInspections = tools.toArray(new LocalInspectionTool[tools.size()]);
216 configureInspections(myInspections);
219 public void enableInspections(InspectionToolProvider... providers) {
220 final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
221 for (InspectionToolProvider provider: providers) {
222 for (Class clazz: provider.getInspectionClasses()) {
223 try {
224 LocalInspectionTool inspection = (LocalInspectionTool)clazz.getConstructor().newInstance();
225 tools.add(inspection);
227 catch (Exception e) {
228 throw new RuntimeException("Cannot instantiate " + clazz);
232 myInspections = tools.toArray(new LocalInspectionTool[tools.size()]);
233 configureInspections(myInspections);
236 public long testHighlighting(final boolean checkWarnings,
237 final boolean checkInfos,
238 final boolean checkWeakWarnings,
239 final String... filePaths) throws Throwable {
241 final Ref<Long> duration = new Ref<Long>();
242 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
244 protected void run() throws Throwable {
245 configureByFilesInner(filePaths);
246 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
248 }.execute().throwException();
249 return duration.get().longValue();
252 public long checkHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings) throws Throwable {
253 final Ref<Long> duration = new Ref<Long>();
254 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
255 protected void run() throws Throwable {
256 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
258 }.execute().throwException();
259 return duration.get().longValue();
262 public long checkHighlighting() throws Throwable {
263 return checkHighlighting(true, true, true);
266 public long testHighlighting(final String... filePaths) throws Throwable {
267 return testHighlighting(true, true, true, filePaths);
270 public long testHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings, final VirtualFile file) throws Throwable {
271 final Ref<Long> duration = new Ref<Long>();
272 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
273 protected void run() throws Throwable {
274 myFile = myPsiManager.findFile(file);
275 myEditor = createEditor(file);
276 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
278 }.execute().throwException();
279 return duration.get().longValue();
282 @Nullable
283 public PsiReference getReferenceAtCaretPosition(final String... filePaths) throws Throwable {
284 new WriteCommandAction<PsiReference>(myProjectFixture.getProject()) {
285 protected void run(final Result<PsiReference> result) throws Throwable {
286 configureByFilesInner(filePaths);
288 }.execute().throwException();
289 return getFile().findReferenceAt(myEditor.getCaretModel().getOffset());
292 @NotNull
293 public PsiReference getReferenceAtCaretPositionWithAssertion(final String... filePaths) throws Throwable {
294 final PsiReference reference = getReferenceAtCaretPosition(filePaths);
295 assert reference != null: "no reference found at " + myEditor.getCaretModel().getLogicalPosition();
296 return reference;
299 @NotNull
300 public List<IntentionAction> getAvailableIntentions(final String... filePaths) throws Throwable {
302 final Project project = myProjectFixture.getProject();
303 return new WriteCommandAction<List<IntentionAction>>(project) {
304 protected void run(final Result<List<IntentionAction>> result) throws Throwable {
305 configureByFilesInner(filePaths);
306 result.setResult(getAvailableIntentions());
308 }.execute().getResultObject();
311 @NotNull
312 public List<IntentionAction> getAvailableIntentions() {
313 doHighlighting();
314 return getAvailableIntentions(myEditor, myFile);
317 public List<IntentionAction> filterAvailableIntentions(@NotNull final String hint) throws Throwable {
318 return ContainerUtil.findAll(getAvailableIntentions(),new Condition<IntentionAction>() {
319 public boolean value(final IntentionAction intentionAction) {
320 return intentionAction.getText().startsWith(hint);
325 public IntentionAction findSingleIntention(@NotNull final String hint) throws Throwable {
326 final List<IntentionAction> list = filterAvailableIntentions(hint);
327 if (list.size() != 1) {
328 Assert.fail(StringUtil.join(getAvailableIntentions(), new Function<IntentionAction, String>() {
329 public String fun(final IntentionAction intentionAction) {
330 return intentionAction.getText();
332 }, ", "));
334 return UsefulTestCase.assertOneElement(list);
337 public IntentionAction getAvailableIntention(final String intentionName, final String... filePaths) throws Throwable {
338 List<IntentionAction> intentions = getAvailableIntentions(filePaths);
339 return CodeInsightTestUtil.findIntentionByText(intentions, intentionName);
342 public void launchAction(@NotNull final IntentionAction action) throws Throwable {
343 new WriteCommandAction(myProjectFixture.getProject()) {
344 protected void run(final Result result) throws Throwable {
345 action.invoke(getProject(), getEditor(), getFile());
347 }.execute().throwException();
351 public void testCompletion(final String[] filesBefore, final String fileAfter) throws Throwable {
352 assertInitialized();
353 configureByFiles(filesBefore);
354 final LookupElement[] items = complete(CompletionType.BASIC);
355 if (items != null) {
356 System.out.println("items = " + Arrays.toString(items));
358 checkResultByFile(fileAfter);
361 private void assertInitialized() {
362 Assert.assertNotNull("setUp() hasn't been called", myPsiManager);
365 public void testCompletion(String fileBefore, String fileAfter, final String... additionalFiles) throws Throwable {
366 testCompletion(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)), fileAfter);
369 public void testCompletionVariants(final String fileBefore, final String... expectedItems) throws Throwable {
370 assertInitialized();
371 final List<String> result = getCompletionVariants(fileBefore);
372 UsefulTestCase.assertSameElements(result, expectedItems);
375 public List<String> getCompletionVariants(final String fileBefore) throws Throwable {
376 assertInitialized();
377 configureByFiles(fileBefore);
378 final LookupElement[] items = complete(CompletionType.BASIC);
379 Assert.assertNotNull("No lookup was shown, probably there was only one lookup element that was inserted automatically", items);
380 return getLookupElementStrings();
383 @Nullable
384 public List<String> getLookupElementStrings() {
385 assertInitialized();
386 final LookupElement[] elements = getLookupElements();
387 if (elements == null) return null;
389 return ContainerUtil.map(elements, new Function<LookupElement, String>() {
390 public String fun(final LookupElement lookupItem) {
391 return lookupItem.getLookupString();
396 public void testRename(final String fileBefore, final String fileAfter, final String newName, final String... additionalFiles) throws Throwable {
397 assertInitialized();
398 configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)));
399 testRename(fileAfter, newName);
402 public void testRename(final String fileAfter, final String newName) throws Throwable {
403 assertInitialized();
404 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
405 protected void run() throws Throwable {
406 PsiElement element = TargetElementUtilBase.findTargetElement(getCompletionEditor(), TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED | TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
407 assert element != null: "element not found in file " + myFile.getName() + " at caret position, offset " + myEditor.getCaretModel().getOffset();
408 final PsiElement substitution = RenamePsiElementProcessor.forElement(element).substituteElementToRename(element, myEditor);
409 new RenameProcessor(myProjectFixture.getProject(), substitution, newName, false, false).run();
410 checkResultByFile(fileAfter, myFile, false);
412 }.execute().throwException();
415 public void type(final char c) {
416 assertInitialized();
417 new WriteCommandAction(getProject()) {
418 protected void run(Result result) throws Throwable {
419 EditorActionManager actionManager = EditorActionManager.getInstance();
420 final DataContext dataContext = DataManager.getInstance().getDataContext();
421 if (c == '\b') {
422 performEditorAction(IdeActions.ACTION_EDITOR_BACKSPACE);
423 return;
425 if (c == '\n') {
426 performEditorAction(IdeActions.ACTION_EDITOR_ENTER);
427 return;
429 if (c == '\t') {
430 if (LookupManager.getInstance(getProject()).getActiveLookup() != null) {
431 actionManager.getActionHandler(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE).execute(getEditor(), dataContext);
432 return;
436 actionManager.getTypedAction().actionPerformed(getEditor(), c, dataContext);
438 }.execute();
441 public void performEditorAction(final String actionId) {
442 assertInitialized();
443 final DataContext dataContext = DataManager.getInstance().getDataContext();
444 EditorActionManager actionManager = EditorActionManager.getInstance();
445 actionManager.getActionHandler(actionId).execute(getEditor(), dataContext);
448 public JavaPsiFacade getJavaFacade() {
449 assertInitialized();
450 return JavaPsiFacade.getInstance(getProject());
453 public Collection<UsageInfo> testFindUsages(@NonNls final String... fileNames) throws Throwable {
454 assertInitialized();
455 configureByFiles(fileNames);
456 PsiElement referenceTo = TargetElementUtilBase
457 .findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
459 assert referenceTo != null : "Cannot find referenced element";
460 final Project project = getProject();
461 final FindUsagesHandler handler = new FindUsagesManager(project, null).getFindUsagesHandler(referenceTo, false);
463 final CommonProcessors.CollectProcessor<UsageInfo> processor = new CommonProcessors.CollectProcessor<UsageInfo>();
464 final FindUsagesOptions options = new FindUsagesOptions(project);
465 options.isUsages = true;
466 assert handler != null : "Cannot find handler for: " + referenceTo;
467 final PsiElement[] psiElements = ArrayUtil.mergeArrays(handler.getPrimaryElements(), handler.getSecondaryElements(), PsiElement.class);
468 for (PsiElement psiElement : psiElements) {
469 handler.processElementUsages(psiElement, processor, options);
471 return processor.getResults();
474 public void moveFile(@NonNls final String filePath, @NonNls final String to, final String... additionalFiles) throws Throwable {
475 assertInitialized();
476 final Project project = myProjectFixture.getProject();
477 new WriteCommandAction.Simple(project) {
478 protected void run() throws Throwable {
479 configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, filePath)));
480 final VirtualFile file = findFileInTempDir(to);
481 assert file.isDirectory() : to + " is not a directory";
482 final PsiDirectory directory = myPsiManager.findDirectory(file);
483 new MoveFilesOrDirectoriesProcessor(project, new PsiElement[] {myFile}, directory,
484 false, false, null, null).run();
486 }.execute().throwException();
490 @Nullable
491 public GutterIconRenderer findGutter(final String filePath) throws Throwable {
492 assertInitialized();
493 final Project project = myProjectFixture.getProject();
494 final Ref<GutterIconRenderer> result = new Ref<GutterIconRenderer>();
495 new WriteCommandAction.Simple(project) {
497 protected void run() throws Throwable {
498 final int offset = configureByFilesInner(filePath);
500 final Collection<HighlightInfo> infos = doHighlighting();
501 for (HighlightInfo info :infos) {
502 if (info.endOffset >= offset && info.startOffset <= offset) {
503 final GutterIconRenderer renderer = info.getGutterIconRenderer();
504 if (renderer != null) {
505 result.set(renderer);
506 return;
512 }.execute().throwException();
513 return result.get();
516 @NotNull
517 public Collection<GutterIconRenderer> findAllGutters(final String filePath) throws Throwable {
518 assertInitialized();
519 final Project project = myProjectFixture.getProject();
520 final SortedMap<Integer, List<GutterIconRenderer>> result = new TreeMap<Integer, List<GutterIconRenderer>>();
521 new WriteCommandAction.Simple(project) {
523 protected void run() throws Throwable {
524 configureByFilesInner(filePath);
526 for (HighlightInfo info : doHighlighting()) {
527 addGutterIconRenderer(info.getGutterIconRenderer(), info.startOffset);
530 doHighlighting();
532 for (final RangeHighlighter highlighter : myEditor.getDocument().getMarkupModel(project).getAllHighlighters()) {
533 addGutterIconRenderer(highlighter.getGutterIconRenderer(), highlighter.getStartOffset());
537 private void addGutterIconRenderer(final GutterIconRenderer renderer, final int offset) {
538 if (renderer == null) return;
540 List<GutterIconRenderer> renderers = result.get(offset);
541 if (renderers == null) {
542 result.put(offset, renderers = new SmartList<GutterIconRenderer>());
544 renderers.add(renderer);
547 }.execute().throwException();
548 return ContainerUtil.concat(result.values());
552 public PsiClass addClass(@NotNull @NonNls final String classText) throws IOException {
553 assertInitialized();
554 final PsiClass psiClass = ((HeavyIdeaTestFixture)myProjectFixture).addClass(getTempDirPath(), classText);
555 myAddedClasses.add(psiClass.getContainingFile().getVirtualFile());
556 return psiClass;
559 public PsiFile addFileToProject(@NonNls final String relativePath, @NonNls final String fileText) throws IOException {
560 assertInitialized();
561 return ((HeavyIdeaTestFixture)myProjectFixture).addFileToProject(getTempDirPath(), relativePath, fileText);
564 public <T> void registerExtension(final ExtensionsArea area, final ExtensionPointName<T> epName, final T extension) {
565 assertInitialized();
566 final ExtensionPoint<T> extensionPoint = area.getExtensionPoint(epName);
567 extensionPoint.registerExtension(extension);
568 disposeOnTearDown(new Disposable() {
569 public void dispose() {
570 extensionPoint.unregisterExtension(extension);
575 public PsiManager getPsiManager() {
576 return myPsiManager;
579 public LookupElement[] complete(final CompletionType type) {
580 assertInitialized();
581 myEmptyLookup = false;
582 new WriteCommandAction(getProject()) {
583 protected void run(Result result) throws Throwable {
584 final CodeInsightActionHandler handler = new CodeCompletionHandlerBase(type) {
585 protected PsiFile createFileCopy(final PsiFile file) {
586 final PsiFile copy = super.createFileCopy(file);
587 if (myFileContext != null) {
588 final PsiElement contextCopy = myFileContext.copy();
589 final PsiFile containingFile = contextCopy.getContainingFile();
590 if (containingFile instanceof PsiFileImpl) {
591 ((PsiFileImpl)containingFile).setOriginalFile(myFileContext.getContainingFile());
593 setContext(copy, contextCopy);
595 return copy;
598 @Override
599 protected void completionFinished(final int offset1, final int offset2, final CompletionContext context, final CompletionProgressIndicator indicator,
600 final LookupElement[] items) {
601 myEmptyLookup = items.length == 0;
602 super.completionFinished(offset1, offset2, context, indicator, items);
605 Editor editor = getCompletionEditor();
606 handler.invoke(getProject(), editor, PsiUtilBase.getPsiFileInEditor(editor, getProject()));
608 }.execute();
609 return getLookupElements();
612 @Nullable
613 protected Editor getCompletionEditor() {
614 return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
617 @Nullable
618 public LookupElement[] completeBasic() {
619 return complete(CompletionType.BASIC);
622 @Nullable
623 public LookupElement[] getLookupElements() {
624 LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
625 if (lookup == null) {
626 return myEmptyLookup ? LookupElement.EMPTY_ARRAY : null;
628 else {
629 return lookup.getSortedItems();
633 public void checkResult(final String text) throws IOException {
634 PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
635 checkResult("TEXT", false, SelectionAndCaretMarkupLoader.fromText(text, getProject()), myFile.getText());
638 public void checkResultByFile(final String expectedFile) throws Throwable {
639 checkResultByFile(expectedFile, false);
642 public void checkResultByFile(final String expectedFile, final boolean ignoreWhitespaces) throws Throwable {
643 assertInitialized();
644 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
646 protected void run() throws Throwable {
647 checkResultByFile(expectedFile, myFile, ignoreWhitespaces);
649 }.execute().throwException();
652 public void checkResultByFile(final String filePath, final String expectedFile, final boolean ignoreWhitespaces) throws Throwable {
653 assertInitialized();
655 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
657 protected void run() throws Throwable {
658 String fullPath = getTempDirPath() + "/" + filePath;
659 final VirtualFile copy = LocalFileSystem.getInstance().refreshAndFindFileByPath(fullPath.replace(File.separatorChar, '/'));
660 assert copy != null : "file not found: " + fullPath;
661 final PsiFile psiFile = myPsiManager.findFile(copy);
662 assert psiFile != null;
663 checkResultByFile(expectedFile, psiFile, ignoreWhitespaces);
665 }.execute().throwException();
668 public void setUp() throws Exception {
669 super.setUp();
671 myProjectFixture.setUp();
672 myTempDirFixture.setUp();
673 myPsiManager = (PsiManagerImpl)PsiManager.getInstance(getProject());
674 configureInspections(myInspections == null ? new LocalInspectionTool[0] : myInspections);
677 private void enableInspectionTool(LocalInspectionTool tool){
678 final String shortName = tool.getShortName();
679 final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
680 if (key == null){
681 HighlightDisplayKey.register(shortName, tool.getDisplayName(), tool.getID());
683 myAvailableTools.put(shortName, tool);
684 myAvailableLocalTools.put(shortName, new LocalInspectionToolWrapper(tool));
687 private void configureInspections(final LocalInspectionTool[] tools) {
688 for (LocalInspectionTool tool : tools) {
689 enableInspectionTool(tool);
692 final InspectionProfileImpl profile = new InspectionProfileImpl(PROFILE) {
693 @NotNull
694 public ModifiableModel getModifiableModel() {
695 mySource = this;
696 return this;
699 @NotNull
700 public InspectionProfileEntry[] getInspectionTools() {
701 final Collection<LocalInspectionToolWrapper> tools = myAvailableLocalTools.values();
702 return tools.toArray(new LocalInspectionToolWrapper[tools.size()]);
705 public boolean isToolEnabled(HighlightDisplayKey key) {
706 return key != null && key.toString() != null && myAvailableTools != null && myAvailableTools.containsKey(key.toString());
709 public HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey key) {
710 final LocalInspectionTool localInspectionTool = key == null ? null : myAvailableTools.get(key.toString());
711 return localInspectionTool != null ? localInspectionTool.getDefaultLevel() : HighlightDisplayLevel.WARNING;
714 public InspectionTool getInspectionTool(@NotNull String shortName) {
715 return myAvailableLocalTools.get(shortName);
718 final InspectionProfileManager inspectionProfileManager = InspectionProfileManager.getInstance();
719 inspectionProfileManager.addProfile(profile);
720 Disposer.register(getProject(), new Disposable() {
721 public void dispose() {
722 inspectionProfileManager.deleteProfile(PROFILE);
725 inspectionProfileManager.setRootProfile(profile.getName());
726 InspectionProjectProfileManager.getInstance(getProject()).updateProfile(profile);
729 public void tearDown() throws Exception {
730 if (SwingUtilities.isEventDispatchThread()) {
731 LookupManager.getInstance(getProject()).hideActiveLookup();
733 else {
734 ApplicationManager.getApplication().invokeAndWait(new Runnable() {
735 public void run() {
736 LookupManager.getInstance(getProject()).hideActiveLookup();
738 }, ModalityState.NON_MODAL);
741 FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
742 VirtualFile[] openFiles = editorManager.getOpenFiles();
743 for (VirtualFile openFile : openFiles) {
744 editorManager.closeFile(openFile);
747 myProjectFixture.tearDown();
748 myTempDirFixture.tearDown();
750 super.tearDown();
753 private int configureByFilesInner(@NonNls String... filePaths) throws IOException {
754 assertInitialized();
755 myFile = null;
756 myEditor = null;
757 for (int i = filePaths.length - 1; i > 0; i--) {
758 configureByFileInner(filePaths[i]);
760 return configureByFileInner(filePaths[0]);
763 public void configureByFile(final String file) throws IOException {
764 assertInitialized();
765 new WriteCommandAction.Simple(getProject()) {
766 protected void run() throws Throwable {
767 configureByFilesInner(file);
769 }.execute();
772 public void configureByFiles(@NonNls final String... files) throws Throwable {
773 new WriteCommandAction.Simple(getProject()) {
774 protected void run() throws Throwable {
775 configureByFilesInner(files);
777 }.execute();
780 public void configureByDirectory(final String dir) {
781 //To change body of implemented methods use File | Settings | File Templates.
784 public PsiFile configureByText(final FileType fileType, @NonNls final String text) throws Throwable {
785 assertInitialized();
786 final String extension = fileType.getDefaultExtension();
787 final File tempFile = File.createTempFile("aaa", "." + extension, new File(getTempDirPath()));
788 final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
789 if (fileTypeManager.getFileTypeByExtension(extension) != fileType) {
790 new WriteCommandAction(getProject()) {
791 protected void run(Result result) throws Throwable {
792 fileTypeManager.associateExtension(fileType, extension);
794 }.execute();
796 final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile);
797 VfsUtil.saveText(vFile, text);
798 assert vFile != null;
799 configureInner(vFile, SelectionAndCaretMarkupLoader.fromFile(vFile, getProject()));
800 return myFile;
803 public Document getDocument(final PsiFile file) {
804 assertInitialized();
805 return PsiDocumentManager.getInstance(getProject()).getDocument(file);
808 public void setFileContext(@Nullable final PsiElement context) {
809 myFileContext = context;
810 setContext(myFile, context);
815 * @param filePath
816 * @return caret offset or -1 if caret marker does not present
817 * @throws IOException
819 private int configureByFileInner(@NonNls String filePath) throws IOException {
820 assertInitialized();
821 copyFileToProject(filePath);
822 return configureFromTempProjectFile(filePath);
825 public int configureFromTempProjectFile(final String filePath) throws IOException {
826 return configureByFileInner(findFileInTempDir(filePath));
829 public void configureFromExistingVirtualFile(VirtualFile f) throws IOException {
830 configureByFileInner(f);
833 private int configureByFileInner(final VirtualFile copy) throws IOException {
834 return configureInner(copy, SelectionAndCaretMarkupLoader.fromFile(copy, getProject()));
837 private int configureInner(@NotNull final VirtualFile copy, final SelectionAndCaretMarkupLoader loader) {
838 assertInitialized();
839 try {
840 final OutputStream outputStream = copy.getOutputStream(null, 0, 0);
841 outputStream.write(loader.newFileText.getBytes());
842 outputStream.close();
844 catch (IOException e) {
845 throw new RuntimeException(e);
847 myFile = myPsiManager.findFile(copy);
848 setContext(myFile, myFileContext);
849 myEditor = createEditor(copy);
850 assert myEditor != null : "Editor couldn't be created for file: " + copy.getPath() + ", use copyFileToProject(..) method for this file instead of configureByFile(..)" ;
851 int offset = -1;
852 if (loader.caretMarker != null) {
853 offset = loader.caretMarker.getStartOffset();
854 myEditor.getCaretModel().moveToOffset(offset);
856 if (loader.selStartMarker != null && loader.selEndMarker != null) {
857 myEditor.getSelectionModel().setSelection(loader.selStartMarker.getStartOffset(), loader.selEndMarker.getStartOffset());
860 Module module = getModule();
861 if (module != null) {
862 for (Facet facet : FacetManager.getInstance(module).getAllFacets()) {
863 module.getMessageBus().syncPublisher(FacetManager.FACETS_TOPIC).facetConfigurationChanged(facet);
867 return offset;
870 private static void setContext(final PsiFile file, final PsiElement context) {
871 if (file != null && context != null) {
872 file.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, new SmartPsiElementPointer() {
873 public PsiElement getElement() {
874 return context;
877 public PsiFile getContainingFile() {
878 return context.getContainingFile();
884 public VirtualFile findFileInTempDir(final String filePath) {
885 String fullPath = getTempDirPath() + "/" + filePath;
887 final VirtualFile copy = LocalFileSystem.getInstance().refreshAndFindFileByPath(fullPath.replace(File.separatorChar, '/'));
888 assert copy != null: "file " + fullPath + " not found";
889 return copy;
892 @Nullable
893 private Editor createEditor(VirtualFile file) {
894 final Project project = getProject();
895 final FileEditorManager instance = FileEditorManager.getInstance(project);
896 if (file.getFileType().isBinary()) {
897 return null;
899 return instance.openTextEditor(new OpenFileDescriptor(project, file, 0), false);
902 private void collectAndCheckHighlightings(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, Ref<Long> duration)
903 throws Exception {
904 final Project project = getProject();
905 ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
907 PsiDocumentManager.getInstance(project).commitAllDocuments();
909 ((PsiFileImpl)myFile).calcTreeElement(); //to load text
911 //to initialize caches
912 myPsiManager.getCacheManager().getFilesWithWord(XXX, UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(project), true);
913 VirtualFileFilter javaFilesFilter = new VirtualFileFilter() {
914 public boolean accept(VirtualFile file) {
915 if (myAddedClasses.contains(file)) return false;
917 FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file);
918 return fileType == StdFileTypes.JAVA || fileType == StdFileTypes.CLASS;
922 JavaPsiFacadeEx.getInstanceEx(project).setAssertOnFileLoadingFilter(javaFilesFilter); // check repository work
924 final long start = System.currentTimeMillis();
925 // ProfilingUtil.startCPUProfiling();
926 Collection<HighlightInfo> infos = doHighlighting();
927 duration.set(System.currentTimeMillis() - start);
928 // ProfilingUtil.captureCPUSnapshot("testing");
930 JavaPsiFacadeEx.getInstanceEx(project).setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
932 data.checkResult(infos, myEditor.getDocument().getText());
935 @NotNull
936 private Collection<HighlightInfo> doHighlighting() {
937 final Project project = myProjectFixture.getProject();
938 PsiDocumentManager.getInstance(project).commitAllDocuments();
940 return
941 ApplicationManager.getApplication().runReadAction(new Computable<Collection<HighlightInfo>>() {
942 public Collection<HighlightInfo> compute() {
943 List<TextEditorHighlightingPass > passes =
944 TextEditorHighlightingPassRegistrarEx.getInstanceEx(getProject()).instantiatePasses(getFile(), getEditor(), ArrayUtil.EMPTY_INT_ARRAY);
945 MockProgressIndicator progress = new MockProgressIndicator();
946 for (TextEditorHighlightingPass pass : passes) {
947 pass.collectInformation(progress);
949 for (TextEditorHighlightingPass pass : passes) {
950 pass.applyInformationToEditor();
952 List<HighlightInfo> infos = DaemonCodeAnalyzerImpl.getHighlights(getEditor().getDocument(), getProject());
953 return infos == null ? Collections.<HighlightInfo>emptyList() : new ArrayList<HighlightInfo>(infos);
958 public String getTestDataPath() {
959 return myTestDataPath;
962 public Project getProject() {
963 return myProjectFixture.getProject();
966 public Module getModule() {
967 return myProjectFixture.getModule();
970 public Editor getEditor() {
971 return myEditor;
974 public PsiFile getFile() {
975 return myFile;
978 public static List<IntentionAction> getAvailableIntentions(final Editor editor, final PsiFile file) {
979 return ApplicationManager.getApplication().runReadAction(new Computable<List<IntentionAction>>() {
980 public List<IntentionAction> compute() {
981 return doGetAvailableIntentions(editor, file);
986 private static List<IntentionAction> doGetAvailableIntentions(Editor editor, PsiFile file) {
987 List<HighlightInfo.IntentionActionDescriptor> descriptors = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
988 ShowIntentionsPass.getActionsToShow(editor, file, descriptors, descriptors, descriptors, descriptors, -1);
991 final List<IntentionAction> availableActions = new ArrayList<IntentionAction>();
992 for (HighlightInfo info :infos) {
993 if (info.quickFixActionRanges != null) {
994 for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
995 IntentionAction action = pair.first.getAction();
996 if (action.isAvailable(file.getProject(), editor, file)) availableActions.add(action);
1001 intentionAction = LightQuickFixTestCase.findActionWithText(
1002 availableActions,
1003 intentionActionName
1007 PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
1008 List<IntentionAction> result = new ArrayList<IntentionAction>();
1010 List<HighlightInfo> infos = DaemonCodeAnalyzerImpl.getFileLeveleHighlights(file.getProject(), file);
1011 for (HighlightInfo info : infos) {
1012 for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
1013 HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first;
1014 if (actionInGroup.getAction().isAvailable(file.getProject(), editor, file)) {
1015 descriptors.add(actionInGroup);
1020 for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) {
1021 result.add(descriptor.getAction());
1022 List<IntentionAction> options = descriptor.getOptions(element);
1023 if (options != null) {
1024 for (IntentionAction option : options) {
1025 if (option.isAvailable(file.getProject(), editor, file)) {
1026 result.add(option);
1031 return result;
1034 static class SelectionAndCaretMarkupLoader {
1035 final String newFileText;
1036 final RangeMarker caretMarker;
1037 final RangeMarker selStartMarker;
1038 final RangeMarker selEndMarker;
1040 static SelectionAndCaretMarkupLoader fromFile(String path, Project project) throws IOException {
1041 return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(new String(FileUtil.loadFileText(new File(path)))), project);
1043 static SelectionAndCaretMarkupLoader fromFile(VirtualFile file, Project project) throws IOException {
1044 return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(VfsUtil.loadText(file)), project);
1047 static SelectionAndCaretMarkupLoader fromText(String text, Project project) {
1048 return new SelectionAndCaretMarkupLoader(text, project);
1051 private SelectionAndCaretMarkupLoader(String fileText, Project project) {
1052 final Document document = EditorFactory.getInstance().createDocument(fileText);
1054 int caretIndex = fileText.indexOf(CARET_MARKER);
1055 int selStartIndex = fileText.indexOf(SELECTION_START_MARKER);
1056 int selEndIndex = fileText.indexOf(SELECTION_END_MARKER);
1058 caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
1059 selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
1060 selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
1062 new WriteCommandAction(project) {
1063 protected void run(Result result) throws Throwable {
1064 if (caretMarker != null) {
1065 document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
1067 if (selStartMarker != null) {
1068 document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
1070 if (selEndMarker != null) {
1071 document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
1074 }.execute();
1076 newFileText = document.getText();
1080 private void checkResultByFile(@NonNls String expectedFile,
1081 @NotNull PsiFile originalFile,
1082 boolean stripTrailingSpaces) throws IOException {
1083 if (!stripTrailingSpaces) {
1084 final LogicalPosition position = myEditor.getCaretModel().getLogicalPosition();
1085 EditorUtil.fillVirtualSpaceUntil(myEditor, position.column, position.line);
1087 PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
1088 checkResult(expectedFile, stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromFile(getTestDataPath() + "/" + expectedFile, getProject()), originalFile.getText());
1091 private void checkResult(final String expectedFile,
1092 final boolean stripTrailingSpaces,
1093 final SelectionAndCaretMarkupLoader loader,
1094 String actualText) {
1095 assertInitialized();
1096 Project project = myProjectFixture.getProject();
1098 project.getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
1099 if (stripTrailingSpaces) {
1100 actualText = stripTrailingSpaces(actualText);
1103 PsiDocumentManager.getInstance(project).commitAllDocuments();
1105 String newFileText1 = loader.newFileText;
1106 if (stripTrailingSpaces) {
1107 newFileText1 = stripTrailingSpaces(newFileText1);
1110 actualText = StringUtil.convertLineSeparators(actualText, "\n");
1112 //noinspection HardCodedStringLiteral
1113 Assert.assertEquals("Text mismatch in file " + expectedFile, newFileText1, actualText);
1115 if (loader.caretMarker != null) {
1116 int caretLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.caretMarker.getStartOffset());
1117 int caretCol = loader.caretMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, caretLine, 0);
1119 Assert.assertEquals("caretLine", caretLine + 1, myEditor.getCaretModel().getLogicalPosition().line + 1);
1120 Assert.assertEquals("caretColumn", caretCol + 1, myEditor.getCaretModel().getLogicalPosition().column + 1);
1123 if (loader.selStartMarker != null && loader.selEndMarker != null) {
1124 int selStartLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selStartMarker.getStartOffset());
1125 int selStartCol = loader.selStartMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0);
1127 int selEndLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selEndMarker.getEndOffset());
1128 int selEndCol = loader.selEndMarker.getEndOffset() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0);
1130 Assert.assertEquals("selectionStartLine", selStartLine + 1,
1131 StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionStart()) + 1);
1133 Assert.assertEquals("selectionStartCol", selStartCol + 1, myEditor.getSelectionModel().getSelectionStart() -
1134 StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0) + 1);
1136 Assert.assertEquals("selectionEndLine", selEndLine + 1,
1137 StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionEnd()) + 1);
1139 Assert.assertEquals("selectionEndCol", selEndCol + 1,
1140 myEditor.getSelectionModel().getSelectionEnd() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0) +
1143 else {
1144 Assert.assertTrue("has no selection", !myEditor.getSelectionModel().hasSelection());
1148 private static String stripTrailingSpaces(String actualText) {
1149 final Document document = EditorFactory.getInstance().createDocument(actualText);
1150 ((DocumentEx)document).stripTrailingSpaces(false);
1151 actualText = document.getText();
1152 return actualText;