2 * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
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
;
101 import java
.io
.IOException
;
102 import java
.io
.OutputStream
;
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()) {
155 FileUtil
.copy(fromFile
, destFile
);
158 final VirtualFile file
= LocalFileSystem
.getInstance().refreshAndFindFileByIoFile(destFile
);
159 Assert
.assertNotNull(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);
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
) {
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())) {
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()) {
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();
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());
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();
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();
312 public List
<IntentionAction
> getAvailableIntentions() {
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();
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
{
353 configureByFiles(filesBefore
);
354 final LookupElement
[] items
= complete(CompletionType
.BASIC
);
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
{
371 final List
<String
> result
= getCompletionVariants(fileBefore
);
372 UsefulTestCase
.assertSameElements(result
, expectedItems
);
375 public List
<String
> getCompletionVariants(final String fileBefore
) throws Throwable
{
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();
384 public List
<String
> getLookupElementStrings() {
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
{
398 configureByFiles(ArrayUtil
.reverseArray(ArrayUtil
.append(additionalFiles
, fileBefore
)));
399 testRename(fileAfter
, newName
);
402 public void testRename(final String fileAfter
, final String newName
) throws Throwable
{
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
) {
417 new WriteCommandAction(getProject()) {
418 protected void run(Result result
) throws Throwable
{
419 EditorActionManager actionManager
= EditorActionManager
.getInstance();
420 final DataContext dataContext
= DataManager
.getInstance().getDataContext();
422 performEditorAction(IdeActions
.ACTION_EDITOR_BACKSPACE
);
426 performEditorAction(IdeActions
.ACTION_EDITOR_ENTER
);
430 if (LookupManager
.getInstance(getProject()).getActiveLookup() != null) {
431 actionManager
.getActionHandler(IdeActions
.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE
).execute(getEditor(), dataContext
);
436 actionManager
.getTypedAction().actionPerformed(getEditor(), c
, dataContext
);
441 public void performEditorAction(final String actionId
) {
443 final DataContext dataContext
= DataManager
.getInstance().getDataContext();
444 EditorActionManager actionManager
= EditorActionManager
.getInstance();
445 actionManager
.getActionHandler(actionId
).execute(getEditor(), dataContext
);
448 public JavaPsiFacade
getJavaFacade() {
450 return JavaPsiFacade
.getInstance(getProject());
453 public Collection
<UsageInfo
> testFindUsages(@NonNls final String
... fileNames
) throws Throwable
{
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
{
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();
491 public GutterIconRenderer
findGutter(final String filePath
) throws Throwable
{
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
);
512 }.execute().throwException();
517 public Collection
<GutterIconRenderer
> findAllGutters(final String filePath
) throws Throwable
{
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
);
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
{
554 final PsiClass psiClass
= ((HeavyIdeaTestFixture
)myProjectFixture
).addClass(getTempDirPath(), classText
);
555 myAddedClasses
.add(psiClass
.getContainingFile().getVirtualFile());
559 public PsiFile
addFileToProject(@NonNls final String relativePath
, @NonNls final String fileText
) throws IOException
{
561 return ((HeavyIdeaTestFixture
)myProjectFixture
).addFileToProject(getTempDirPath(), relativePath
, fileText
);
564 public <T
> void registerExtension(final ExtensionsArea area
, final ExtensionPointName
<T
> epName
, final T extension
) {
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() {
579 public LookupElement
[] complete(final CompletionType type
) {
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
);
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()));
609 return getLookupElements();
613 protected Editor
getCompletionEditor() {
614 return InjectedLanguageUtil
.getEditorForInjectedLanguageNoCommit(myEditor
, myFile
);
618 public LookupElement
[] completeBasic() {
619 return complete(CompletionType
.BASIC
);
623 public LookupElement
[] getLookupElements() {
624 LookupImpl lookup
= (LookupImpl
)LookupManager
.getActiveLookup(myEditor
);
625 if (lookup
== null) {
626 return myEmptyLookup ? LookupElement
.EMPTY_ARRAY
: null;
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
{
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
{
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
{
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
);
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
) {
694 public ModifiableModel
getModifiableModel() {
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();
734 ApplicationManager
.getApplication().invokeAndWait(new Runnable() {
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();
753 private int configureByFilesInner(@NonNls String
... filePaths
) throws IOException
{
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
{
765 new WriteCommandAction
.Simple(getProject()) {
766 protected void run() throws Throwable
{
767 configureByFilesInner(file
);
772 public void configureByFiles(@NonNls final String
... files
) throws Throwable
{
773 new WriteCommandAction
.Simple(getProject()) {
774 protected void run() throws Throwable
{
775 configureByFilesInner(files
);
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
{
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
);
796 final VirtualFile vFile
= LocalFileSystem
.getInstance().refreshAndFindFileByIoFile(tempFile
);
797 VfsUtil
.saveText(vFile
, text
);
798 assert vFile
!= null;
799 configureInner(vFile
, SelectionAndCaretMarkupLoader
.fromFile(vFile
, getProject()));
803 public Document
getDocument(final PsiFile file
) {
805 return PsiDocumentManager
.getInstance(getProject()).getDocument(file
);
808 public void setFileContext(@Nullable final PsiElement context
) {
809 myFileContext
= context
;
810 setContext(myFile
, context
);
816 * @return caret offset or -1 if caret marker does not present
817 * @throws IOException
819 private int configureByFileInner(@NonNls String filePath
) throws IOException
{
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
) {
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(..)" ;
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
);
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() {
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";
893 private Editor
createEditor(VirtualFile file
) {
894 final Project project
= getProject();
895 final FileEditorManager instance
= FileEditorManager
.getInstance(project
);
896 if (file
.getFileType().isBinary()) {
899 return instance
.openTextEditor(new OpenFileDescriptor(project
, file
, 0), false);
902 private void collectAndCheckHighlightings(boolean checkWarnings
, boolean checkInfos
, boolean checkWeakWarnings
, Ref
<Long
> duration
)
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());
936 private Collection
<HighlightInfo
> doHighlighting() {
937 final Project project
= myProjectFixture
.getProject();
938 PsiDocumentManager
.getInstance(project
).commitAllDocuments();
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() {
974 public PsiFile
getFile() {
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(
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
)) {
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());
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) +
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();