cleanup
[idea/community.git] / platform / testFramework / src / com / intellij / testFramework / fixtures / impl / CodeInsightTestFixtureImpl.java
1 /*
2  * Copyright 2000-2011 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.intellij.testFramework.fixtures.impl;
18
19 import com.intellij.analysis.AnalysisScope;
20 import com.intellij.codeHighlighting.HighlightDisplayLevel;
21 import com.intellij.codeInsight.TargetElementUtilBase;
22 import com.intellij.codeInsight.completion.CodeCompletionHandlerBase;
23 import com.intellij.codeInsight.completion.CompletionProgressIndicator;
24 import com.intellij.codeInsight.completion.CompletionType;
25 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
26 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
27 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
28 import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
29 import com.intellij.codeInsight.daemon.impl.HighlightInfo;
30 import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
31 import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass;
32 import com.intellij.codeInsight.folding.CodeFoldingManager;
33 import com.intellij.codeInsight.highlighting.actions.HighlightUsagesAction;
34 import com.intellij.codeInsight.intention.IntentionAction;
35 import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
36 import com.intellij.codeInsight.lookup.LookupElement;
37 import com.intellij.codeInsight.lookup.LookupManager;
38 import com.intellij.codeInsight.lookup.impl.LookupImpl;
39 import com.intellij.codeInspection.*;
40 import com.intellij.codeInspection.ex.*;
41 import com.intellij.facet.Facet;
42 import com.intellij.facet.FacetManager;
43 import com.intellij.find.FindManager;
44 import com.intellij.find.findUsages.FindUsagesHandler;
45 import com.intellij.find.findUsages.FindUsagesOptions;
46 import com.intellij.find.impl.FindManagerImpl;
47 import com.intellij.ide.DataManager;
48 import com.intellij.ide.startup.StartupManagerEx;
49 import com.intellij.ide.startup.impl.StartupManagerImpl;
50 import com.intellij.ide.structureView.StructureViewBuilder;
51 import com.intellij.ide.structureView.newStructureView.StructureViewComponent;
52 import com.intellij.lang.LanguageStructureViewBuilder;
53 import com.intellij.openapi.Disposable;
54 import com.intellij.openapi.actionSystem.*;
55 import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
56 import com.intellij.openapi.application.ApplicationManager;
57 import com.intellij.openapi.application.Result;
58 import com.intellij.openapi.command.CommandProcessor;
59 import com.intellij.openapi.command.WriteCommandAction;
60 import com.intellij.openapi.editor.*;
61 import com.intellij.openapi.editor.actionSystem.DocCommandGroupId;
62 import com.intellij.openapi.editor.actionSystem.EditorActionManager;
63 import com.intellij.openapi.editor.ex.EditorEx;
64 import com.intellij.openapi.editor.ex.util.EditorUtil;
65 import com.intellij.openapi.editor.impl.DocumentImpl;
66 import com.intellij.openapi.editor.impl.DocumentMarkupModel;
67 import com.intellij.openapi.editor.markup.GutterIconRenderer;
68 import com.intellij.openapi.editor.markup.RangeHighlighter;
69 import com.intellij.openapi.extensions.ExtensionPoint;
70 import com.intellij.openapi.extensions.ExtensionPointName;
71 import com.intellij.openapi.extensions.Extensions;
72 import com.intellij.openapi.extensions.ExtensionsArea;
73 import com.intellij.openapi.fileEditor.*;
74 import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
75 import com.intellij.openapi.fileTypes.FileType;
76 import com.intellij.openapi.fileTypes.FileTypeManager;
77 import com.intellij.openapi.fileTypes.StdFileTypes;
78 import com.intellij.openapi.module.Module;
79 import com.intellij.openapi.project.DumbService;
80 import com.intellij.openapi.project.Project;
81 import com.intellij.openapi.util.*;
82 import com.intellij.openapi.util.io.FileUtil;
83 import com.intellij.openapi.util.text.StringUtil;
84 import com.intellij.openapi.vfs.LocalFileSystem;
85 import com.intellij.openapi.vfs.VfsUtil;
86 import com.intellij.openapi.vfs.VirtualFile;
87 import com.intellij.openapi.vfs.VirtualFileFilter;
88 import com.intellij.profile.codeInspection.InspectionProfileManager;
89 import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
90 import com.intellij.psi.*;
91 import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
92 import com.intellij.psi.impl.PsiManagerImpl;
93 import com.intellij.psi.impl.PsiModificationTrackerImpl;
94 import com.intellij.psi.impl.cache.CacheManager;
95 import com.intellij.psi.impl.cache.impl.todo.TodoIndex;
96 import com.intellij.psi.impl.source.PostprocessReformattingAspect;
97 import com.intellij.psi.impl.source.PsiFileImpl;
98 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
99 import com.intellij.psi.search.GlobalSearchScope;
100 import com.intellij.psi.search.UsageSearchContext;
101 import com.intellij.psi.statistics.StatisticsManager;
102 import com.intellij.psi.statistics.impl.StatisticsManagerImpl;
103 import com.intellij.psi.stubs.StubUpdatingIndex;
104 import com.intellij.psi.util.PsiTreeUtil;
105 import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor;
106 import com.intellij.refactoring.rename.RenameProcessor;
107 import com.intellij.refactoring.rename.RenamePsiElementProcessor;
108 import com.intellij.testFramework.*;
109 import com.intellij.testFramework.fixtures.*;
110 import com.intellij.usageView.UsageInfo;
111 import com.intellij.util.*;
112 import com.intellij.util.containers.ContainerUtil;
113 import com.intellij.util.indexing.FileBasedIndex;
114 import com.intellij.util.ui.UIUtil;
115 import gnu.trove.THashMap;
116 import junit.framework.Assert;
117 import org.jetbrains.annotations.NonNls;
118 import org.jetbrains.annotations.NotNull;
119 import org.jetbrains.annotations.Nullable;
120
121 import javax.swing.*;
122 import java.io.File;
123 import java.io.IOException;
124 import java.util.*;
125
126 /**
127  * @author Dmitry Avdeev
128  */
129 @SuppressWarnings({"TestMethodWithIncorrectSignature", "JUnitTestCaseWithNoTests", "JUnitTestClassNamingConvention"})
130 public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsightTestFixture {
131
132   @NonNls private static final String PROFILE = "Configurable";
133
134   private static final Function<IntentionAction,String> INTENTION_NAME_FUN = new Function<IntentionAction, String>() {
135     @Override
136     public String fun(final IntentionAction intentionAction) {
137       return "\"" + intentionAction.getText() + "\"";
138     }
139   };
140
141   private PsiManagerImpl myPsiManager;
142   private PsiFile myFile;
143   private Editor myEditor;
144   private String myTestDataPath;
145   private boolean myEmptyLookup;
146
147   private InspectionProfileEntry[] myInspections;
148   private final Map<String, InspectionProfileEntry> myAvailableTools = new THashMap<String, InspectionProfileEntry>();
149   private final Map<String, InspectionTool> myAvailableLocalTools = new THashMap<String, InspectionTool>();
150
151   private final TempDirTestFixture myTempDirFixture;
152   protected final IdeaProjectTestFixture myProjectFixture;
153   @NonNls private static final String XXX = "XXX";
154   private final FileTreeAccessFilter myJavaFilesFilter = new FileTreeAccessFilter();
155   private boolean myAllowDirt;
156   private final Map<String, LocalInspectionEP> myExtensions = new HashMap<String, LocalInspectionEP>();
157
158   public CodeInsightTestFixtureImpl(IdeaProjectTestFixture projectFixture, TempDirTestFixture tempDirTestFixture) {
159     myProjectFixture = projectFixture;
160     myTempDirFixture = tempDirTestFixture;
161   }
162
163   @Override
164   public void setTestDataPath(String dataPath) {
165     myTestDataPath = dataPath;
166   }
167
168   @Override
169   public String getTempDirPath() {
170     return myTempDirFixture.getTempDirPath();
171   }
172
173   @Override
174   public TempDirTestFixture getTempDirFixture() {
175     return myTempDirFixture;
176   }
177
178   @Override
179   public VirtualFile copyFileToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath) {
180     File fromFile = new File(getTestDataPath() + "/" + sourceFilePath);
181     if (!fromFile.exists()) {
182       fromFile = new File(sourceFilePath);
183     }
184
185     if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
186       VirtualFile fromVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(fromFile);
187       if (fromVFile == null) {
188         fromVFile = myTempDirFixture.getFile(sourceFilePath);
189       }
190       assert fromVFile != null : "can't find test data file " + sourceFilePath + " (" + getTestDataPath() + ")";
191       return myTempDirFixture.copyFile(fromVFile, targetPath);
192     }
193
194     final File destFile = new File(getTempDirPath() + "/" + targetPath);
195     if (!destFile.exists()) {
196       if (fromFile.isDirectory()) {
197         assert destFile.mkdirs() : destFile;
198       }
199       else {
200         if (!fromFile.exists()) {
201           fail("Cannot find source file: '"+sourceFilePath+"'. getTestDataPath()='"+getTestDataPath()+"'. getHomePath()='"+getHomePath()+"'.");
202         }
203         try {
204           FileUtil.copy(fromFile, destFile);
205         }
206         catch (IOException e) {
207           throw new RuntimeException("Cannot copy " + fromFile + " to " + destFile, e);
208         }
209       }
210     }
211
212     final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
213     assert file != null : destFile;
214     return file;
215   }
216
217   @Override
218   public VirtualFile copyDirectoryToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath) {
219     assert getTestDataPath() != null : "test data path not specified";
220     final File fromFile = new File(getTestDataPath() + "/" + sourceFilePath);
221     if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
222       return myTempDirFixture.copyAll(fromFile.getPath(), targetPath);
223     }
224     else {
225       final File destFile = new File(getTempDirPath() + "/" + targetPath);
226       try {
227         FileUtil.copyDir(fromFile, destFile);
228       }
229       catch (IOException e) {
230         throw new RuntimeException(e);
231       }
232       final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
233       Assert.assertNotNull(file);
234       file.refresh(false, true);
235       return file;
236     }
237   }
238
239   @Override
240   public VirtualFile copyFileToProject(@NonNls final String sourceFilePath) {
241     return copyFileToProject(sourceFilePath, sourceFilePath);
242   }
243
244   @Override
245   public void enableInspections(InspectionProfileEntry... inspections) {
246     myInspections = inspections;
247     if (isInitialized()) {
248       configureInspections(myInspections);
249     }
250   }
251
252   private boolean isInitialized() {
253     return myPsiManager != null;
254   }
255
256   @Override
257   public void enableInspections(final Class<? extends LocalInspectionTool>... inspections) {
258     final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
259     for (Class clazz : inspections) {
260       try {
261         LocalInspectionTool inspection = (LocalInspectionTool)clazz.getConstructor().newInstance();
262         tools.add(inspection);
263       }
264       catch (Exception e) {
265         throw new RuntimeException("Cannot instantiate " + clazz);
266       }
267     }
268     enableInspections(tools.toArray(new LocalInspectionTool[tools.size()]));
269   }
270
271   @Override
272   public void disableInspections(InspectionProfileEntry... inspections) {
273     myAvailableTools.clear();
274     myAvailableLocalTools.clear();
275     final ArrayList<InspectionProfileEntry> tools = new ArrayList<InspectionProfileEntry>(Arrays.asList(myInspections));
276     for (Iterator<InspectionProfileEntry> i = tools.iterator(); i.hasNext();) {
277       final InspectionProfileEntry tool = i.next();
278       for (InspectionProfileEntry toRemove : inspections) {
279         if (tool.getShortName().equals(toRemove.getShortName())) {
280           i.remove();
281           break;
282         }
283       }
284     }
285     myInspections = tools.toArray(new InspectionProfileEntry[tools.size()]);
286     configureInspections(myInspections);
287   }
288
289   @Override
290   public void enableInspections(InspectionToolProvider... providers) {
291     final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
292     for (InspectionToolProvider provider : providers) {
293       for (Class clazz : provider.getInspectionClasses()) {
294         try {
295           Object o = clazz.getConstructor().newInstance();
296           if (o instanceof LocalInspectionTool) {
297             LocalInspectionTool inspection = (LocalInspectionTool)o;
298             tools.add(inspection);
299           }
300         }
301         catch (Exception e) {
302           throw new RuntimeException("Cannot instantiate " + clazz, e);
303         }
304       }
305     }
306     myInspections = tools.toArray(new LocalInspectionTool[tools.size()]);
307     configureInspections(myInspections);
308   }
309
310   @Override
311   public long testHighlighting(final boolean checkWarnings,
312                                final boolean checkInfos,
313                                final boolean checkWeakWarnings,
314                                final String... filePaths) {
315     final Ref<Long> duration = new Ref<Long>();
316     if (filePaths.length > 0) {
317       configureByFilesInner(filePaths);
318     }
319     try {
320       collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
321     }
322     catch (Exception e) {
323       throw new RuntimeException(e);
324     }
325     return duration.get().longValue();
326   }
327
328   @Override
329   public long testHighlightingAllFiles(final boolean checkWarnings,
330                                        final boolean checkInfos,
331                                        final boolean checkWeakWarnings,
332                                        @NonNls final String... filePaths) {
333     final ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
334     for (String path : filePaths) {
335       files.add(copyFileToProject(path));
336     }
337     return testHighlightingAllFiles(checkWarnings, checkInfos, checkWeakWarnings, VfsUtil.toVirtualFileArray(files));
338   }
339
340   @Override
341   public long testHighlightingAllFiles(final boolean checkWarnings,
342                                        final boolean checkInfos,
343                                        final boolean checkWeakWarnings,
344                                        @NonNls final VirtualFile... files) {
345     final Ref<Long> duration = new Ref<Long>();
346     collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration, files);
347     return duration.get().longValue();
348   }
349
350   private void collectAndCheckHighlightings(final boolean checkWarnings,
351                                             final boolean checkInfos,
352                                             final boolean checkWeakWarnings,
353                                             final Ref<Long> duration,
354                                             final VirtualFile[] files) {
355     final List<Trinity<PsiFile, Editor, ExpectedHighlightingData>> datas =
356       ContainerUtil.map2List(files, new Function<VirtualFile, Trinity<PsiFile, Editor, ExpectedHighlightingData>>() {
357         @Override
358         public Trinity<PsiFile, Editor, ExpectedHighlightingData> fun(final VirtualFile file) {
359           final PsiFile psiFile = myPsiManager.findFile(file);
360           assertNotNull(psiFile);
361           final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(psiFile);
362           assertNotNull(document);
363           ExpectedHighlightingData data = new ExpectedHighlightingData(document, checkWarnings, checkWeakWarnings, checkInfos, psiFile);
364           data.init();
365           return Trinity.create(psiFile, createEditor(file), data);
366         }
367       });
368     for (Trinity<PsiFile, Editor, ExpectedHighlightingData> trinity : datas) {
369       myEditor = trinity.second;
370       myFile = trinity.first;
371       collectAndCheckHighlightings(trinity.third, duration);
372     }
373   }
374
375   @Override
376   public long checkHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings) {
377     final Ref<Long> duration = new Ref<Long>();
378     try {
379       collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
380     }
381     catch (Exception e) {
382       throw new RuntimeException(e);
383     }
384     return duration.get().longValue();
385   }
386
387   @Override
388   public long checkHighlighting() {
389     return checkHighlighting(true, true, true);
390   }
391
392   @Override
393   public long testHighlighting(final String... filePaths) {
394     return testHighlighting(true, true, true, filePaths);
395   }
396
397   @Override
398   public long testHighlighting(final boolean checkWarnings,
399                                final boolean checkInfos,
400                                final boolean checkWeakWarnings,
401                                final VirtualFile file) {
402     final Ref<Long> duration = new Ref<Long>();
403     openFileInEditor(file);
404     try {
405       collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
406     }
407     catch (Exception e) {
408       throw new RuntimeException(e);
409     }
410     return duration.get().longValue();
411   }
412
413   @Override
414   public HighlightTestInfo testFile(@NonNls @NotNull String... filePath) {
415     return new HighlightTestInfo(getTestRootDisposable(), filePath){
416       @Override
417       public HighlightTestInfo doTest() throws Exception {
418         configureByFiles(filePaths);
419         ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
420         if (checkSymbolNames) data.checkSymbolNames();
421         data.init();
422         collectAndCheckHighlightings(data, Ref.create(0L));
423         return this;
424       }
425     };
426   }
427
428   public void openFileInEditor(@NotNull final VirtualFile file) {
429     myFile = myPsiManager.findFile(file);
430     myEditor = createEditor(file);
431   }
432
433   @Override
434   public void testInspection(String testDir, InspectionTool tool) {
435     VirtualFile sourceDir = copyDirectoryToProject(new File(testDir, "src").getPath(), "src");
436     AnalysisScope scope = new AnalysisScope(getPsiManager().findDirectory(sourceDir));
437
438     scope.invalidate();
439
440     InspectionManagerEx inspectionManager = (InspectionManagerEx)InspectionManager.getInstance(getProject());
441     GlobalInspectionContextImpl globalContext = createGlobalContextForTool(scope, getProject(), inspectionManager, tool);
442
443     InspectionTestUtil.runTool(tool, scope, globalContext, inspectionManager);
444     InspectionTestUtil.compareToolResults(tool, false, new File(getTestDataPath(), testDir).getPath());
445   }
446
447   public static GlobalInspectionContextImpl createGlobalContextForTool(AnalysisScope scope,
448                                                                        final Project project,
449                                                                        final InspectionManagerEx inspectionManager,
450                                                                        final InspectionTool... tools) {
451     final GlobalInspectionContextImpl globalContext = new GlobalInspectionContextImpl(project, inspectionManager.getContentManager()){
452       @Override
453       protected List<ToolsImpl> getUsedTools() {
454         List<ToolsImpl> result = new ArrayList<ToolsImpl>();
455         for (InspectionTool tool : tools) {
456           result.add(new ToolsImpl(tool, tool.getDefaultLevel(), true));
457         }
458         return result;
459       }
460
461       @Override
462       public boolean isToCheckMember(PsiElement element, InspectionProfileEntry tool) {
463         return true;
464       }
465     };
466     globalContext.setCurrentScope(scope);
467     return globalContext;
468   }
469
470   @Override
471   @Nullable
472   public PsiReference getReferenceAtCaretPosition(final String... filePaths) {
473     if (filePaths.length > 0) {
474       configureByFilesInner(filePaths);
475     }
476     return getFile().findReferenceAt(myEditor.getCaretModel().getOffset());
477   }
478
479   @Override
480   @NotNull
481   public PsiReference getReferenceAtCaretPositionWithAssertion(final String... filePaths) {
482     final PsiReference reference = getReferenceAtCaretPosition(filePaths);
483     assert reference != null : "no reference found at " + myEditor.getCaretModel().getLogicalPosition();
484     return reference;
485   }
486
487   @Override
488   @NotNull
489   public List<IntentionAction> getAvailableIntentions(final String... filePaths) {
490     if (filePaths.length > 0) {
491       configureByFilesInner(filePaths);
492     }
493     return getAvailableIntentions();
494   }
495
496   @Override
497   @NotNull
498   public List<IntentionAction> getAllQuickFixes(@NonNls final String... filePaths) {
499     if (filePaths.length != 0) {
500       configureByFilesInner(filePaths);
501     }
502     List<HighlightInfo> infos = doHighlighting();
503     ArrayList<IntentionAction> actions = new ArrayList<IntentionAction>();
504     for (HighlightInfo info : infos) {
505       for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
506         actions.add(pair.getFirst().getAction());
507       }
508     }
509     return actions;
510   }
511
512   @Override
513   @NotNull
514   public List<IntentionAction> getAvailableIntentions() {
515     doHighlighting();
516     return getAvailableIntentions(myEditor, myFile);
517   }
518
519   @Override
520   public List<IntentionAction> filterAvailableIntentions(@NotNull final String hint) {
521     final List<IntentionAction> availableIntentions = getAvailableIntentions();
522     return ContainerUtil.findAll(availableIntentions, new Condition<IntentionAction>() {
523       @Override
524       public boolean value(final IntentionAction intentionAction) {
525         return intentionAction.getText().startsWith(hint);
526       }
527     });
528   }
529
530   @Override
531   public IntentionAction findSingleIntention(@NotNull final String hint) {
532     final List<IntentionAction> list = filterAvailableIntentions(hint);
533     if (list.isEmpty()) {
534       Assert.fail("\"" + hint + "\" not in [" + StringUtil.join(getAvailableIntentions(), INTENTION_NAME_FUN, ", ") + "]");
535     }
536     else if (list.size() > 1) {
537       Assert.fail("Too many intention found for \"" + hint + "\": [" + StringUtil.join(list, INTENTION_NAME_FUN, ", ") + "]");
538     }
539     return UsefulTestCase.assertOneElement(list);
540   }
541
542   @Override
543   public IntentionAction getAvailableIntention(final String intentionName, final String... filePaths) {
544     List<IntentionAction> intentions = getAvailableIntentions(filePaths);
545     return CodeInsightTestUtil.findIntentionByText(intentions, intentionName);
546   }
547
548   @Override
549   public void launchAction(@NotNull final IntentionAction action) {
550     ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText());
551   }
552
553   @Override
554   public void testCompletion(final String[] filesBefore, final String fileAfter) {
555     assertInitialized();
556     configureByFiles(filesBefore);
557     complete(CompletionType.BASIC);
558     checkResultByFile(fileAfter);
559   }
560
561   protected void assertInitialized() {
562     Assert.assertNotNull("setUp() hasn't been called", myPsiManager);
563   }
564
565   @Override
566   public void testCompletion(String fileBefore, String fileAfter, final String... additionalFiles) {
567     testCompletion(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)), fileAfter);
568   }
569
570   @Override
571   public void testCompletionVariants(final String fileBefore, final String... expectedItems) {
572     assertInitialized();
573     final List<String> result = getCompletionVariants(fileBefore);
574     Assert.assertNotNull(result);
575     UsefulTestCase.assertSameElements(result, expectedItems);
576   }
577
578   @Override
579   public List<String> getCompletionVariants(final String... filesBefore) {
580     assertInitialized();
581     configureByFiles(filesBefore);
582     final LookupElement[] items = complete(CompletionType.BASIC);
583     Assert.assertNotNull("No lookup was shown, probably there was only one lookup element that was inserted automatically", items);
584     return getLookupElementStrings();
585   }
586
587   @Override
588   @Nullable
589   public List<String> getLookupElementStrings() {
590     assertInitialized();
591     final LookupElement[] elements = getLookupElements();
592     if (elements == null) return null;
593
594     return ContainerUtil.map(elements, new Function<LookupElement, String>() {
595       @Override
596       public String fun(final LookupElement lookupItem) {
597         return lookupItem.getLookupString();
598       }
599     });
600   }
601
602   @Override
603   public void testRename(final String fileBefore, final String fileAfter, final String newName, final String... additionalFiles) {
604     assertInitialized();
605     configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)));
606     testRename(fileAfter, newName);
607   }
608
609   @Override
610   public void testRename(final String fileAfter, final String newName) {
611     renameElementAtCaret(newName);
612     checkResultByFile(fileAfter);
613   }
614
615   @Override
616   @NotNull
617   public PsiElement getElementAtCaret() {
618     assertInitialized();
619     final PsiElement element = TargetElementUtilBase.findTargetElement(getCompletionEditor(),
620                                                                        TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED |
621                                                                        TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
622     assert element != null : "element not found in file " +
623                              myFile.getName() +
624                              " at caret position, offset " +
625                              myEditor.getCaretModel().getOffset();
626     return element;
627   }
628
629   @Override
630   public void renameElementAtCaret(final String newName) {
631     renameElement(getElementAtCaret(), newName);
632   }
633
634   @Override
635   public void renameElement(final PsiElement element, final String newName) {
636     final boolean searchInComments = false;
637     final boolean searchTextOccurrences = false;
638     renameElement(element, newName, searchInComments, searchTextOccurrences);
639   }
640
641   @Override
642   public void renameElement(final PsiElement element,
643                             final String newName,
644                             final boolean searchInComments,
645                             final boolean searchTextOccurrences) {
646     final PsiElement substitution = RenamePsiElementProcessor.forElement(element).substituteElementToRename(element, myEditor);
647     if (substitution == null) return;
648     new RenameProcessor(getProject(), substitution, newName, searchInComments, searchTextOccurrences).run();
649   }
650
651   @Override
652   public <T extends PsiElement> T findElementByText(String text, Class<T> elementClass) {
653     int pos = PsiDocumentManager.getInstance(getProject()).getDocument(getFile()).getText().indexOf(text);
654     assert pos >= 0 : "text not found in file";
655     return PsiTreeUtil.getParentOfType(getFile().findElementAt(pos), elementClass);
656   }
657
658   @Override
659   public void type(final char c) {
660     assertInitialized();
661     UIUtil.invokeAndWaitIfNeeded(new Runnable() {
662       @Override
663       public void run() {
664         final EditorActionManager actionManager = EditorActionManager.getInstance();
665         if (c == '\b') {
666           performEditorAction(IdeActions.ACTION_EDITOR_BACKSPACE);
667           return;
668         }
669         if (c == '\n') {
670           if (_performEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM)) {
671             return;
672           }
673
674           performEditorAction(IdeActions.ACTION_EDITOR_ENTER);
675           return;
676         }
677         if (c == '\t') {
678           if (_performEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE)) {
679             return;
680           }
681           if (_performEditorAction(IdeActions.ACTION_EXPAND_LIVE_TEMPLATE_BY_TAB)) {
682             return;
683           }
684           if (_performEditorAction(IdeActions.ACTION_EDITOR_TAB)) {
685             return;
686           }
687         }
688
689         CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
690           @Override
691           public void run() {
692             CommandProcessor.getInstance().setCurrentCommandGroupId(myEditor.getDocument());
693             ActionManagerEx.getInstanceEx().fireBeforeEditorTyping(c, getEditorDataContext());
694             actionManager.getTypedAction().actionPerformed(getEditor(), c, getEditorDataContext());
695           }
696         }, null, DocCommandGroupId.noneGroupId(myEditor.getDocument()));
697       }
698     });
699   }
700
701   private DataContext getEditorDataContext() {
702     return ((EditorEx)myEditor).getDataContext();
703   }
704
705   @Override
706   public void type(String s) {
707     for (int i = 0; i < s.length(); i++) {
708       type(s.charAt(i));
709     }
710   }
711
712   @Override
713   public void performEditorAction(final String actionId) {
714     assertInitialized();
715     _performEditorAction(actionId);
716   }
717
718   private boolean _performEditorAction(String actionId) {
719     final DataContext dataContext = getEditorDataContext();
720
721     ActionManagerEx managerEx = ActionManagerEx.getInstanceEx();
722     AnAction action = managerEx.getAction(actionId);
723     AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, new Presentation(), managerEx, 0);
724
725     action.update(event);
726
727     if (!event.getPresentation().isEnabled()) {
728       return false;
729     }
730
731     managerEx.fireBeforeActionPerformed(action, dataContext, event);
732
733     action.actionPerformed(event);
734
735     managerEx.fireAfterActionPerformed(action, dataContext, event);
736     return true;
737   }
738
739   @Override
740   public Presentation testAction(AnAction action) {
741     DataContext context = DataManager.getInstance().getDataContext();
742     TestActionEvent e = new TestActionEvent(context, action);
743     action.beforeActionPerformedUpdate(e);
744     if (e.getPresentation().isEnabled() && e.getPresentation().isVisible()) {
745       action.actionPerformed(e);
746     }
747     return e.getPresentation();
748   }
749
750   @Override
751   public Collection<UsageInfo> testFindUsages(@NonNls final String... fileNames) {
752     assertInitialized();
753     configureByFiles(fileNames);
754     final PsiElement targetElement = TargetElementUtilBase
755       .findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
756     assert targetElement != null : "Cannot find referenced element";
757     return findUsages(targetElement);
758   }
759
760   @Override
761   public Collection<UsageInfo> findUsages(@NotNull final PsiElement targetElement) {
762     final Project project = getProject();
763     final FindUsagesHandler handler =
764       ((FindManagerImpl)FindManager.getInstance(project)).getFindUsagesManager().getFindUsagesHandler(targetElement, false);
765
766     final CommonProcessors.CollectProcessor<UsageInfo> processor = new CommonProcessors.CollectProcessor<UsageInfo>();
767     assert handler != null : "Cannot find handler for: " + targetElement;
768     final PsiElement[] psiElements = ArrayUtil.mergeArrays(handler.getPrimaryElements(), handler.getSecondaryElements());
769     final FindUsagesOptions options = handler.getFindUsagesOptions(null);
770     for (PsiElement psiElement : psiElements) {
771       handler.processElementUsages(psiElement, processor, options);
772     }
773     return processor.getResults();
774   }
775
776   @Override
777   public RangeHighlighter[] testHighlightUsages(final String... files) {
778     configureByFiles(files);
779     testAction(new HighlightUsagesAction());
780     final Editor editor = getEditor();
781     //final Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext());
782     //assert editor != null;
783     //HighlightUsagesHandler.invoke(getProject(), editor, getFile());
784     return editor.getMarkupModel().getAllHighlighters();
785   }
786
787   @Override
788   public void moveFile(@NonNls final String filePath, @NonNls final String to, final String... additionalFiles) {
789     assertInitialized();
790     final Project project = getProject();
791     new WriteCommandAction.Simple(project) {
792       @Override
793       protected void run() throws Exception {
794         configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, filePath)));
795         final VirtualFile file = findFileInTempDir(to);
796         assert file != null : "Directory " + to + " not found";
797         assert file.isDirectory() : to + " is not a directory";
798         final PsiDirectory directory = myPsiManager.findDirectory(file);
799         new MoveFilesOrDirectoriesProcessor(project, new PsiElement[]{myFile}, directory,
800                                             false, false, null, null).run();
801       }
802     }.execute().throwException();
803   }
804
805   @Override
806   @Nullable
807   public GutterIconRenderer findGutter(final String filePath) {
808     configureByFilesInner(filePath);
809     int offset = myEditor.getCaretModel().getOffset();
810
811     final Collection<HighlightInfo> infos = doHighlighting();
812     for (HighlightInfo info : infos) {
813       if (info.endOffset >= offset && info.startOffset <= offset) {
814         final GutterIconRenderer renderer = info.getGutterIconRenderer();
815         if (renderer != null) {
816           return renderer;
817         }
818       }
819     }
820     RangeHighlighter[] highlighters = DocumentMarkupModel.forDocument(myEditor.getDocument(), getProject(), true).getAllHighlighters();
821     for (RangeHighlighter highlighter : highlighters) {
822       if (highlighter.getEndOffset() >= offset && highlighter.getStartOffset() <= offset) {
823         GutterIconRenderer renderer = highlighter.getGutterIconRenderer();
824         if (renderer != null) {
825           return renderer;
826         }
827       }
828     }
829     return null;
830   }
831
832   @Override
833   @NotNull
834   public Collection<GutterIconRenderer> findAllGutters(final String filePath) {
835     final Project project = getProject();
836     final SortedMap<Integer, List<GutterIconRenderer>> result = new TreeMap<Integer, List<GutterIconRenderer>>();
837     configureByFilesInner(filePath);
838
839     List<HighlightInfo> infos = doHighlighting();
840     for (HighlightInfo info : infos) {
841       addGutterIconRenderer(info.getGutterIconRenderer(), info.startOffset, result);
842     }
843
844     RangeHighlighter[] highlighters = DocumentMarkupModel.forDocument(myEditor.getDocument(), project, true).getAllHighlighters();
845     for (final RangeHighlighter highlighter : highlighters) {
846       if (!highlighter.isValid()) continue;
847       addGutterIconRenderer(highlighter.getGutterIconRenderer(), highlighter.getStartOffset(), result);
848     }
849     return ContainerUtil.concat(result.values());
850   }
851
852   private static void addGutterIconRenderer(final GutterIconRenderer renderer,
853                                             final int offset,
854                                             SortedMap<Integer, List<GutterIconRenderer>> result) {
855     if (renderer == null) return;
856
857     List<GutterIconRenderer> renderers = result.get(offset);
858     if (renderers == null) {
859       result.put(offset, renderers = new SmartList<GutterIconRenderer>());
860     }
861     renderers.add(renderer);
862   }
863
864
865   @Override
866   public PsiFile addFileToProject(@NonNls final String relativePath, @NonNls final String fileText) {
867     assertInitialized();
868     return addFileToProject(getTempDirPath(), relativePath, fileText);
869   }
870
871   protected PsiFile addFileToProject(String rootPath, String relativePath, String fileText) {
872     try {
873       if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
874         final VirtualFile file = myTempDirFixture.createFile(relativePath, fileText);
875         return PsiManager.getInstance(getProject()).findFile(file);
876       }
877
878       return ((HeavyIdeaTestFixture)myProjectFixture).addFileToProject(rootPath, relativePath, fileText);
879     }
880     catch (IOException e) {
881       throw new RuntimeException(e);
882     }
883     finally {
884       ((PsiModificationTrackerImpl)PsiManager.getInstance(getProject()).getModificationTracker()).incCounter();
885     }
886   }
887
888   public <T> void registerExtension(final ExtensionsArea area, final ExtensionPointName<T> epName, final T extension) {
889     assertInitialized();
890     final ExtensionPoint<T> extensionPoint = area.getExtensionPoint(epName);
891     extensionPoint.registerExtension(extension);
892     disposeOnTearDown(new Disposable() {
893       @Override
894       public void dispose() {
895         extensionPoint.unregisterExtension(extension);
896       }
897     });
898   }
899
900   @Override
901   public PsiManager getPsiManager() {
902     return myPsiManager;
903   }
904
905   @Override
906   public LookupElement[] complete(CompletionType type) {
907     return complete(type, 1);
908   }
909
910   @Override
911   public LookupElement[] complete(final CompletionType type, final int invocationCount) {
912     assertInitialized();
913     myEmptyLookup = false;
914     UIUtil.invokeAndWaitIfNeeded(new Runnable() {
915       @Override
916       public void run() {
917         CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
918           @Override
919           public void run() {
920             final CodeCompletionHandlerBase handler = new CodeCompletionHandlerBase(type) {
921
922               @Override
923               protected void completionFinished(int offset1,
924                                                 int offset2,
925                                                 CompletionProgressIndicator indicator,
926                                                 LookupElement[] items,
927                                                 boolean hasModifiers) {
928                 myEmptyLookup = items.length == 0;
929                 super.completionFinished(offset1, offset2, indicator, items, hasModifiers);
930               }
931             };
932             Editor editor = getCompletionEditor();
933             handler.invokeCompletion(getProject(), editor, invocationCount, false);
934             PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); // to compare with file text
935           }
936         }, null, null);
937       }
938     });
939
940     return getLookupElements();
941   }
942
943   @Nullable
944   protected Editor getCompletionEditor() {
945     return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
946   }
947
948   @Override
949   @Nullable
950   public LookupElement[] completeBasic() {
951     return complete(CompletionType.BASIC);
952   }
953
954   @Override
955   @Nullable
956   public LookupElement[] getLookupElements() {
957     LookupImpl lookup = getLookup();
958     if (lookup == null) {
959       return myEmptyLookup ? LookupElement.EMPTY_ARRAY : null;
960     }
961     else {
962       final List<LookupElement> list = lookup.getItems();
963       return list.toArray(new LookupElement[list.size()]);
964     }
965   }
966
967   @Override
968   public void checkResult(final String text) {
969     checkResult(text, false);
970   }
971
972   @Override
973   public void checkResult(final String text, final boolean stripTrailingSpaces) {
974     new WriteCommandAction(getProject()) {
975       @Override
976       protected void run(Result result) throws Throwable {
977         PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
978         EditorUtil.fillVirtualSpaceUntilCaret(myEditor);
979         checkResult("TEXT", stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromText(text, getProject()), myFile.getText());
980       }
981     }.execute();
982   }
983
984   @Override
985   public void checkResultByFile(final String expectedFile) {
986     checkResultByFile(expectedFile, false);
987   }
988
989   @Override
990   public void checkResultByFile(final String expectedFile, final boolean ignoreTrailingWhitespaces) {
991     assertInitialized();
992     new WriteCommandAction.Simple(getProject()) {
993
994       @Override
995       protected void run() throws Exception {
996         checkResultByFile(expectedFile, myFile, ignoreTrailingWhitespaces);
997       }
998     }.execute().throwException();
999   }
1000
1001   @Override
1002   public void checkResultByFile(final String filePath, final String expectedFile, final boolean ignoreTrailingWhitespaces) {
1003     assertInitialized();
1004
1005     new WriteCommandAction.Simple(getProject()) {
1006
1007       @Override
1008       protected void run() throws Exception {
1009         final String path = filePath.replace(File.separatorChar, '/');
1010         final VirtualFile copy = findFileInTempDir(path);
1011         if (copy == null) {
1012           throw new IllegalArgumentException("could not find results file " + path);
1013         }
1014         final PsiFile psiFile = myPsiManager.findFile(copy);
1015         assert psiFile != null;
1016         checkResultByFile(expectedFile, psiFile, ignoreTrailingWhitespaces);
1017       }
1018     }.execute().throwException();
1019   }
1020
1021   @Override
1022   public void setUp() throws Exception {
1023     super.setUp();
1024
1025     myProjectFixture.setUp();
1026     myTempDirFixture.setUp();
1027     myPsiManager = (PsiManagerImpl)PsiManager.getInstance(getProject());
1028     configureInspections(myInspections == null ? LocalInspectionTool.EMPTY_ARRAY : myInspections);
1029
1030     DaemonCodeAnalyzerImpl daemonCodeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject());
1031     daemonCodeAnalyzer.prepareForTest();
1032
1033     DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
1034     ensureIndexesUpToDate(getProject());
1035     ((StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject())).runPostStartupActivities();
1036     LocalInspectionEP[] extensions = Extensions.getExtensions(LocalInspectionEP.LOCAL_INSPECTION);
1037     for (LocalInspectionEP extension : extensions) {
1038       myExtensions.put(extension.shortName, extension);
1039     }
1040   }
1041
1042   @Override
1043   public void tearDown() throws Exception {
1044     ((StatisticsManagerImpl)StatisticsManager.getInstance()).clearStatistics();
1045
1046     FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
1047     VirtualFile[] openFiles = editorManager.getOpenFiles();
1048     for (VirtualFile openFile : openFiles) {
1049       editorManager.closeFile(openFile);
1050     }
1051
1052     myEditor = null;
1053     myFile = null;
1054     myPsiManager = null;
1055     myInspections = null;
1056     myAvailableLocalTools.clear();
1057     myAvailableTools.clear();
1058
1059     myProjectFixture.tearDown();
1060     myTempDirFixture.tearDown();
1061
1062     super.tearDown();
1063   }
1064
1065   private void enableInspectionTool(InspectionProfileEntry tool) {
1066     final String shortName = tool.getShortName();
1067     final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
1068     if (key == null) {
1069       String id = tool instanceof LocalInspectionTool ? ((LocalInspectionTool)tool).getID() : shortName;
1070       HighlightDisplayKey.register(shortName, tool.getDisplayName(), id);
1071     }
1072     myAvailableTools.put(shortName, tool);
1073     InspectionTool inspectionTool;
1074     if (tool instanceof LocalInspectionTool) {
1075       LocalInspectionEP ep = myExtensions.get(tool.getShortName());
1076       inspectionTool = new LocalInspectionToolWrapper((LocalInspectionTool)tool, ep);
1077     }
1078     else {
1079       inspectionTool = (InspectionTool)tool;
1080     }
1081     myAvailableLocalTools.put(shortName, inspectionTool);
1082   }
1083
1084   private void configureInspections(final InspectionProfileEntry[] tools) {
1085     for (InspectionProfileEntry tool : tools) {
1086       enableInspectionTool(tool);
1087     }
1088
1089     final InspectionProfileImpl profile = new InspectionProfileImpl(PROFILE) {
1090       @Override
1091       @NotNull
1092       public ModifiableModel getModifiableModel() {
1093         mySource = this;
1094         return this;
1095       }
1096
1097       @Override
1098       @NotNull
1099       public InspectionProfileEntry[] getInspectionTools(PsiElement element) {
1100         final Collection<InspectionTool> tools = myAvailableLocalTools.values();
1101         return tools.toArray(new InspectionTool[tools.size()]);
1102       }
1103
1104       @Override
1105       public List<ToolsImpl> getAllEnabledInspectionTools(Project project) {
1106         List<ToolsImpl> result = new ArrayList<ToolsImpl>();
1107         for (InspectionProfileEntry entry : getInspectionTools(null)) {
1108           result.add(new ToolsImpl(entry, entry.getDefaultLevel(), true));
1109         }
1110         return result;
1111       }
1112
1113       @Override
1114       public boolean isToolEnabled(HighlightDisplayKey key, PsiElement element) {
1115         return key != null && key.toString() != null && myAvailableTools.containsKey(key.toString());
1116       }
1117
1118       @Override
1119       public InspectionProfileEntry getInspectionTool(@NotNull String shortName) {
1120         return myAvailableTools.get(shortName);
1121       }
1122
1123       @Override
1124       public HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey key, PsiElement element) {
1125         final InspectionProfileEntry entry = myAvailableTools.get(key.toString());
1126         return entry != null ? entry.getDefaultLevel() : HighlightDisplayLevel.WARNING;
1127       }
1128
1129       @Override
1130       public InspectionTool getInspectionTool(@NotNull String shortName, @NotNull PsiElement element) {
1131         return myAvailableLocalTools.get(shortName);
1132       }
1133     };
1134     final InspectionProfileManager inspectionProfileManager = InspectionProfileManager.getInstance();
1135     inspectionProfileManager.addProfile(profile);
1136     Disposer.register(getTestRootDisposable(), new Disposable() {
1137       @Override
1138       public void dispose() {
1139         inspectionProfileManager.deleteProfile(PROFILE);
1140       }
1141     });
1142     inspectionProfileManager.setRootProfile(profile.getName());
1143     InspectionProjectProfileManager.getInstance(getProject()).updateProfile(profile);
1144     InspectionProjectProfileManager.getInstance(getProject()).setProjectProfile(profile.getName());
1145   }
1146
1147   private PsiFile[] configureByFilesInner(@NonNls String... filePaths) {
1148     assertInitialized();
1149     myFile = null;
1150     myEditor = null;
1151     PsiFile[] psiFiles = new PsiFile[filePaths.length];
1152     for (int i = filePaths.length - 1; i >= 0; i--) {
1153       psiFiles[i] = configureByFileInner(filePaths[i]);
1154     }
1155     return psiFiles;
1156   }
1157
1158   @Override
1159   public PsiFile configureByFile(final String file) {
1160     configureByFilesInner(file);
1161     return myFile;
1162   }
1163
1164   @Override
1165   public PsiFile[] configureByFiles(@NonNls final String... files) {
1166     return configureByFilesInner(files);
1167   }
1168
1169   @Override
1170   public PsiFile configureByText(final FileType fileType, @NonNls final String text) {
1171     assertInitialized();
1172     final String extension = fileType.getDefaultExtension();
1173     final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
1174     if (fileTypeManager.getFileTypeByExtension(extension) != fileType) {
1175       new WriteCommandAction(getProject()) {
1176         @Override
1177         protected void run(Result result) throws Exception {
1178           fileTypeManager.associateExtension(fileType, extension);
1179         }
1180       }.execute();
1181     }
1182     final String fileName = "aaa." + extension;
1183     return configureByText(fileName, text);
1184   }
1185
1186   @Override
1187   public PsiFile configureByText(final String fileName, @NonNls final String text) {
1188     assertInitialized();
1189     new WriteCommandAction(getProject()) {
1190       @Override
1191       protected void run(Result result) throws Throwable {
1192         final VirtualFile vFile;
1193         if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
1194           final VirtualFile root = LightPlatformTestCase.getSourceRoot();
1195           root.refresh(false, false);
1196           vFile = root.findOrCreateChildData(this, fileName);
1197         }
1198         else {
1199           String prefix = StringUtil.getPackageName(fileName);
1200           if (prefix.length() < 3) {
1201             prefix += "___";
1202           }
1203           final File tempFile = FileUtil.createTempFile(new File(getTempDirPath()), prefix, "." + StringUtil.getShortName(fileName), true);
1204           vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile);
1205         }
1206         final Document document = FileDocumentManager.getInstance().getCachedDocument(vFile);
1207         if (document != null) {
1208           FileDocumentManager.getInstance().saveDocument(document);
1209         }
1210
1211         VfsUtil.saveText(vFile, text);
1212         configureInner(vFile, SelectionAndCaretMarkupLoader.fromFile(vFile, getProject()));
1213       }
1214     }.execute();
1215     return myFile;
1216   }
1217
1218   @Override
1219   public Document getDocument(final PsiFile file) {
1220     assertInitialized();
1221     return PsiDocumentManager.getInstance(getProject()).getDocument(file);
1222   }
1223
1224   /**
1225    * @param filePath
1226    * @throws IOException
1227    */
1228   private PsiFile configureByFileInner(@NonNls String filePath) {
1229     assertInitialized();
1230     final VirtualFile file = copyFileToProject(filePath);
1231     return configureByFileInner(file);
1232   }
1233
1234   @Override
1235   public PsiFile configureFromTempProjectFile(final String filePath) {
1236     final VirtualFile fileInTempDir = findFileInTempDir(filePath);
1237     if (fileInTempDir == null) {
1238       throw new IllegalArgumentException("Could not find file in temp dir: " + filePath);
1239     }
1240     return configureByFileInner(fileInTempDir);
1241   }
1242
1243   @Override
1244   public void configureFromExistingVirtualFile(VirtualFile f) {
1245     configureByFileInner(f);
1246   }
1247
1248   private PsiFile configureByFileInner(final VirtualFile copy) {
1249     return configureInner(copy, SelectionAndCaretMarkupLoader.fromFile(copy, getProject()));
1250   }
1251
1252   private PsiFile configureInner(@NotNull final VirtualFile copy, final SelectionAndCaretMarkupLoader loader) {
1253     assertInitialized();
1254     new WriteCommandAction.Simple(getProject()) {
1255       public void run() {
1256         try {
1257           copy.setBinaryContent(loader.newFileText.getBytes(copy.getCharset()), 0, 0, null);
1258         }
1259         catch (IOException e) {
1260           throw new RuntimeException(e);
1261         }
1262         myFile = myPsiManager.findFile(copy);
1263         myEditor = createEditor(copy);
1264         assert myEditor != null : "Editor couldn't be created for file: " +
1265                                   copy.getPath() +
1266                                   ", use copyFileToProject(..) method for this file instead of configureByFile(..)";
1267         if (loader.caretMarker != null) {
1268           int offset = loader.caretMarker.getStartOffset();
1269           myEditor.getCaretModel().moveToOffset(offset);
1270         }
1271         if (loader.selStartMarker != null && loader.selEndMarker != null) {
1272           myEditor.getSelectionModel().setSelection(loader.selStartMarker.getStartOffset(), loader.selEndMarker.getStartOffset());
1273         }
1274
1275         Module module = getModule();
1276         if (module != null) {
1277           for (Facet facet : FacetManager.getInstance(module).getAllFacets()) {
1278             module.getMessageBus().syncPublisher(FacetManager.FACETS_TOPIC).facetConfigurationChanged(facet);
1279           }
1280         }
1281       }
1282     }.execute().throwException();
1283
1284
1285     return myFile;
1286   }
1287
1288   @Override
1289   public VirtualFile findFileInTempDir(final String filePath) {
1290     if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
1291       return myTempDirFixture.getFile(filePath);
1292     }
1293     String fullPath = getTempDirPath() + "/" + filePath;
1294
1295     final VirtualFile copy = LocalFileSystem.getInstance().refreshAndFindFileByPath(fullPath.replace(File.separatorChar, '/'));
1296     assert copy != null : "file " + fullPath + " not found";
1297     return copy;
1298   }
1299
1300   @Nullable
1301   private Editor createEditor(VirtualFile file) {
1302     final Project project = getProject();
1303     final FileEditorManager instance = FileEditorManager.getInstance(project);
1304     if (file.getFileType().isBinary()) {
1305       return null;
1306     }
1307     return instance.openTextEditor(new OpenFileDescriptor(project, file, 0), false);
1308   }
1309
1310   private void collectAndCheckHighlightings(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, Ref<Long> duration)
1311     throws Exception {
1312     ExpectedHighlightingData data =
1313       new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
1314     data.init();
1315     collectAndCheckHighlightings(data, duration);
1316   }
1317
1318   private void collectAndCheckHighlightings(final ExpectedHighlightingData data, final Ref<Long> duration) {
1319     final Project project = getProject();
1320     PsiDocumentManager.getInstance(project).commitAllDocuments();
1321
1322     ((PsiFileImpl)myFile).calcTreeElement(); //to load text
1323
1324     //to initialize caches
1325     CacheManager.SERVICE.getInstance(project).getFilesWithWord(XXX, UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(project), true);
1326
1327     List<HighlightInfo> infos;
1328     try {
1329       ((PsiManagerImpl)PsiManager.getInstance(project)).setAssertOnFileLoadingFilter(myJavaFilesFilter);
1330
1331       final long start = System.currentTimeMillis();
1332 //    ProfilingUtil.startCPUProfiling();
1333       infos = doHighlighting();
1334       removeDuplicatedRangesForInjected(infos);
1335       final long elapsed = System.currentTimeMillis() - start;
1336       duration.set(duration.isNull() ? elapsed : duration.get().longValue() + elapsed);
1337 //    ProfilingUtil.captureCPUSnapshot("testing");
1338     }
1339     finally {
1340       ((PsiManagerImpl)PsiManager.getInstance(project)).setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
1341     }
1342
1343
1344     data.checkResult(infos, myEditor.getDocument().getText());
1345   }
1346
1347   private static void removeDuplicatedRangesForInjected(List<HighlightInfo> infos) {
1348     Collections.sort(infos, new Comparator<HighlightInfo>() {
1349       @Override
1350       public int compare(HighlightInfo o1, HighlightInfo o2) {
1351         final int i = o2.startOffset - o1.startOffset;
1352         return i != 0 ? i : o1.getSeverity().myVal - o2.getSeverity().myVal;
1353       }
1354     });
1355     HighlightInfo prevInfo = null;
1356     for (Iterator<HighlightInfo> it = infos.iterator(); it.hasNext();) {
1357       final HighlightInfo info = it.next();
1358       if (prevInfo != null &&
1359           info.getSeverity() == HighlightInfoType.SYMBOL_TYPE_SEVERITY &&
1360           info.description == null &&
1361           info.startOffset == prevInfo.startOffset &&
1362           info.endOffset == prevInfo.endOffset) {
1363         it.remove();
1364       }
1365       prevInfo = info.type == HighlightInfoType.INJECTED_LANGUAGE_FRAGMENT ? info : null;
1366     }
1367   }
1368
1369   @Override
1370   @NotNull
1371   public List<HighlightInfo> doHighlighting() {
1372     final Project project = getProject();
1373     PsiDocumentManager.getInstance(project).commitAllDocuments();
1374
1375     return instantiateAndRun(getFile(), getEditor(), ArrayUtil.EMPTY_INT_ARRAY, myAllowDirt);
1376   }
1377
1378   @NotNull
1379   public static List<HighlightInfo> instantiateAndRun(@NotNull PsiFile file,
1380                                                       @NotNull Editor editor,
1381                                                       @NotNull int[] toIgnore,
1382                                                       boolean canChangeDocument) {
1383     Project project = file.getProject();
1384     ensureIndexesUpToDate(project);
1385     DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project);
1386     TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(editor);
1387     List<HighlightInfo> infos = codeAnalyzer.runPasses(file, editor.getDocument(), textEditor, toIgnore, canChangeDocument, null);
1388     infos.addAll(DaemonCodeAnalyzerImpl.getFileLevelHighlights(project, file));
1389     return infos;
1390   }
1391
1392   public static void ensureIndexesUpToDate(Project project) {
1393     if (!DumbService.isDumb(project)) {
1394       FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, null);
1395       FileBasedIndex.getInstance().ensureUpToDate(TodoIndex.NAME, project, null);
1396     }
1397   }
1398
1399   @Override
1400   public String getTestDataPath() {
1401     return myTestDataPath;
1402   }
1403
1404   @Override
1405   public Project getProject() {
1406     return myProjectFixture.getProject();
1407   }
1408
1409   @Override
1410   public Module getModule() {
1411     return myProjectFixture.getModule();
1412   }
1413
1414   @Override
1415   public Editor getEditor() {
1416     return myEditor;
1417   }
1418
1419   @Override
1420   public int getCaretOffset() {
1421     return myEditor.getCaretModel().getOffset();
1422   }
1423
1424   @Override
1425   public PsiFile getFile() {
1426     return myFile;
1427   }
1428
1429   public static List<IntentionAction> getAvailableIntentions(@NotNull final Editor editor, @NotNull final PsiFile file) {
1430     return ApplicationManager.getApplication().runReadAction(new Computable<List<IntentionAction>>() {
1431       @Override
1432       public List<IntentionAction> compute() {
1433         return doGetAvailableIntentions(editor, file);
1434       }
1435     });
1436   }
1437
1438   private static List<IntentionAction> doGetAvailableIntentions(@NotNull Editor editor, @NotNull PsiFile file) {
1439     ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo();
1440     ShowIntentionsPass.getActionsToShow(editor, file, intentions, -1);
1441     List<HighlightInfo.IntentionActionDescriptor> descriptors = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
1442     descriptors.addAll(intentions.intentionsToShow);
1443     descriptors.addAll(intentions.errorFixesToShow);
1444     descriptors.addAll(intentions.inspectionFixesToShow);
1445     descriptors.addAll(intentions.guttersToShow);
1446
1447     PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
1448     List<IntentionAction> result = new ArrayList<IntentionAction>();
1449
1450     List<HighlightInfo> infos = DaemonCodeAnalyzerImpl.getFileLevelHighlights(file.getProject(), file);
1451     for (HighlightInfo info : infos) {
1452       for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
1453         HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first;
1454         if (actionInGroup.getAction().isAvailable(file.getProject(), editor, file)) {
1455           descriptors.add(actionInGroup);
1456         }
1457       }
1458     }
1459
1460     // add all intention options for simplicity
1461     for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) {
1462       result.add(descriptor.getAction());
1463       List<IntentionAction> options = descriptor.getOptions(element,editor);
1464       if (options != null) {
1465         for (IntentionAction option : options) {
1466           if (option.isAvailable(file.getProject(), editor, file)) {
1467             result.add(option);
1468           }
1469         }
1470       }
1471     }
1472     return result;
1473   }
1474
1475   @Override
1476   public void allowTreeAccessForFile(final VirtualFile file) {
1477     myJavaFilesFilter.allowTreeAccessForFile(file);
1478   }
1479
1480   @Override
1481   public void allowTreeAccessForAllFiles() {
1482     myJavaFilesFilter.allowTreeAccessForAllFiles();
1483   }
1484
1485   static class SelectionAndCaretMarkupLoader {
1486     final String newFileText;
1487     final RangeMarker caretMarker;
1488     final RangeMarker selStartMarker;
1489     final RangeMarker selEndMarker;
1490
1491     static SelectionAndCaretMarkupLoader fromFile(String path, Project project) throws IOException {
1492       return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(FileUtil.loadFile(new File(path))),
1493                                                project);
1494     }
1495
1496     static SelectionAndCaretMarkupLoader fromFile(VirtualFile file, Project project) {
1497       final String text;
1498       try {
1499         text = VfsUtil.loadText(file);
1500       }
1501       catch (IOException e) {
1502         throw new RuntimeException(e);
1503       }
1504       return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(text), project);
1505     }
1506
1507     static SelectionAndCaretMarkupLoader fromText(String text, Project project) {
1508       return new SelectionAndCaretMarkupLoader(text, project);
1509     }
1510
1511     private SelectionAndCaretMarkupLoader(String fileText, Project project) {
1512       final Document document = EditorFactory.getInstance().createDocument(fileText);
1513
1514       int caretIndex = fileText.indexOf(CARET_MARKER);
1515       int selStartIndex = fileText.indexOf(SELECTION_START_MARKER);
1516       int selEndIndex = fileText.indexOf(SELECTION_END_MARKER);
1517
1518       caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
1519       selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
1520       selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
1521
1522       new WriteCommandAction(project) {
1523         @Override
1524         protected void run(Result result) throws Exception {
1525           if (caretMarker != null) {
1526             document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
1527           }
1528           if (selStartMarker != null) {
1529             document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
1530           }
1531           if (selEndMarker != null) {
1532             document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
1533           }
1534         }
1535       }.execute();
1536
1537       newFileText = document.getText();
1538     }
1539   }
1540
1541   private void checkResultByFile(@NonNls String expectedFile,
1542                                  @NotNull PsiFile originalFile,
1543                                  boolean stripTrailingSpaces) throws IOException {
1544     if (!stripTrailingSpaces) {
1545       EditorUtil.fillVirtualSpaceUntilCaret(myEditor);
1546     }
1547     PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
1548
1549     final String fileText = originalFile.getText();
1550     final String path = getTestDataPath() + "/" + expectedFile;
1551
1552     /*final VirtualFile result = LocalFileSystem.getInstance().findFileByPath(path);
1553     final int caret = myEditor.getCaretModel().getOffset();
1554     final String newText = myFile == originalFile ? fileText.substring(0, caret) + "<caret>" + fileText.substring(caret) : fileText;
1555     VfsUtil.saveText(result, newText);*/
1556
1557     checkResult(expectedFile, stripTrailingSpaces,
1558                 SelectionAndCaretMarkupLoader.fromFile(path, getProject()), fileText);
1559
1560   }
1561
1562   private void checkResult(final String expectedFile,
1563                            final boolean stripTrailingSpaces,
1564                            final SelectionAndCaretMarkupLoader loader,
1565                            String actualText) {
1566     assertInitialized();
1567     Project project = getProject();
1568
1569     project.getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
1570     if (stripTrailingSpaces) {
1571       actualText = stripTrailingSpaces(actualText);
1572     }
1573
1574     PsiDocumentManager.getInstance(project).commitAllDocuments();
1575
1576     String newFileText1 = loader.newFileText;
1577     if (stripTrailingSpaces) {
1578       newFileText1 = stripTrailingSpaces(newFileText1);
1579     }
1580
1581     actualText = StringUtil.convertLineSeparators(actualText);
1582
1583     //noinspection HardCodedStringLiteral
1584     Assert.assertEquals("Text mismatch in file " + expectedFile, newFileText1, actualText);
1585
1586     if (loader.caretMarker != null) {
1587       final int tabSize = CodeStyleSettingsManager.getSettings(getProject()).getIndentOptions(StdFileTypes.JAVA).TAB_SIZE;
1588
1589       int caretLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.caretMarker.getStartOffset());
1590       int caretCol = EditorUtil.calcColumnNumber(null, loader.newFileText, StringUtil.lineColToOffset(loader.newFileText, caretLine, 0), loader.caretMarker.getStartOffset(), tabSize);
1591
1592       final int actualLine = myEditor.getCaretModel().getLogicalPosition().line;
1593       final int actualCol = myEditor.getCaretModel().getLogicalPosition().column;
1594       boolean caretPositionEquals = caretLine == actualLine && caretCol == actualCol;
1595       assertTrue("Caret position in " + expectedFile + " differs. Expected " + genCaretPositionPresentation(caretLine, caretCol) +
1596         ". Actual " + genCaretPositionPresentation(actualLine, actualCol), caretPositionEquals);
1597     }
1598
1599     if (loader.selStartMarker != null && loader.selEndMarker != null) {
1600       int selStartLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selStartMarker.getStartOffset());
1601       int selStartCol = loader.selStartMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0);
1602
1603       int selEndLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selEndMarker.getEndOffset());
1604       int selEndCol = loader.selEndMarker.getEndOffset() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0);
1605
1606       final int selStartLineActual = StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionStart());
1607       final int selStartColActual = myEditor.getSelectionModel().getSelectionStart() - StringUtil.lineColToOffset(loader.newFileText, selStartLineActual, 0);
1608
1609       final int selEndLineActual = StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionEnd());
1610       final int selEndColActual = myEditor.getSelectionModel().getSelectionEnd() - StringUtil.lineColToOffset(loader.newFileText, selEndLineActual, 0);
1611
1612       final boolean selectionEquals = selStartCol == selStartColActual &&
1613                                       selStartLine == selStartLineActual &&
1614                                       selEndCol == selEndColActual &&
1615                                       selEndLine == selEndLineActual;
1616       Assert.assertTrue("selection in " +
1617                           expectedFile +
1618                           " differs. Expected " +
1619                           genSelectionPresentation(selStartLine, selStartCol, selEndLine, selEndCol) +
1620                           ". Actual " +
1621                           genSelectionPresentation(selStartLineActual, selStartColActual, selEndLineActual, selEndColActual),
1622                         selectionEquals);
1623     }
1624     else if (myEditor != null) {
1625       Assert.assertTrue("has no selection in " + expectedFile, !myEditor.getSelectionModel().hasSelection());
1626     }
1627   }
1628
1629   private static String genCaretPositionPresentation(int line, int col) {
1630     line++;
1631     col++;
1632     return "(" + line + ", " + col + ")";
1633   }
1634
1635   private static String genSelectionPresentation(int startLine, int startCol, int endLine, int endCol) {
1636     startCol++;
1637     startLine++;
1638     endCol++;
1639     endLine++;
1640     return "(" + startLine + ", " + startCol + ")-(" + endLine + ", " + endCol + ")";
1641   }
1642
1643   private static String stripTrailingSpaces(String actualText) {
1644     final Document document = EditorFactory.getInstance().createDocument(actualText);
1645     ((DocumentImpl)document).stripTrailingSpaces();
1646     actualText = document.getText();
1647     return actualText;
1648   }
1649
1650   public void canChangeDocumentDuringHighlighting(boolean canI) {
1651     myAllowDirt = canI;
1652   }
1653
1654   private static final String START_FOLD = "<fold\\stext=\'[^\']*\'(\\sexpand=\'[^\']*\')*>";
1655   private static final String END_FOLD = "</fold>";
1656
1657   private class Border implements Comparable<Border> {
1658     public static final boolean LEFT = true;
1659     public static final boolean RIGHT = false;
1660     public boolean mySide;
1661     public int myOffset;
1662     public String myText;
1663     public boolean myIsExpanded;
1664
1665     private Border(boolean side, int offset, String text, boolean isExpanded) {
1666       mySide = side;
1667       myOffset = offset;
1668       myText = text;
1669       myIsExpanded = isExpanded;
1670     }
1671
1672     public boolean isExpanded() {
1673       return myIsExpanded;
1674     }
1675
1676     public boolean isSide() {
1677       return mySide;
1678     }
1679
1680     public int getOffset() {
1681       return myOffset;
1682     }
1683
1684     public String getText() {
1685       return myText;
1686     }
1687
1688     public int compareTo(Border o) {
1689       return getOffset() < o.getOffset() ? 1 : -1;
1690     }
1691   }
1692
1693   private String getFoldingDescription(@NotNull String content, @NotNull String initialFileName,
1694                                        boolean doCheckCollapseStatus) {
1695     configureByText(FileTypeManager.getInstance().getFileTypeByFileName(initialFileName), content);
1696     CodeFoldingManager.getInstance(getProject()).buildInitialFoldings(myEditor);
1697
1698     final FoldingModel model = myEditor.getFoldingModel();
1699     final FoldRegion[] foldingRegions = model.getAllFoldRegions();
1700     final List<Border> borders = new LinkedList<Border>();
1701
1702     for (FoldRegion region : foldingRegions) {
1703       borders.add(new Border(Border.LEFT, region.getStartOffset(), region.getPlaceholderText(), region.isExpanded()));
1704       borders.add(new Border(Border.RIGHT, region.getEndOffset(), "", region.isExpanded()));
1705     }
1706     Collections.sort(borders);
1707
1708     StringBuilder result = new StringBuilder(myEditor.getDocument().getText());
1709     for (Border border : borders) {
1710       result.insert(border.getOffset(), border.isSide() == Border.LEFT ? "<fold text=\'" + border.getText() + "\'" +
1711                                                                          (doCheckCollapseStatus ? " expand=\'" +
1712                                                                                                     border.isExpanded() +
1713                                                                                                     "\'" : "") +
1714                                                                           ">" : END_FOLD);
1715     }
1716
1717     return result.toString();
1718   }
1719
1720   private void testFoldingRegions(final String verificationFileName, boolean doCheckCollapseStatus) {
1721     String expectedContent;
1722     try {
1723       expectedContent = FileUtil.loadFile(new File(verificationFileName));
1724     }
1725     catch (IOException e) {
1726       throw new RuntimeException(e);
1727     }
1728     Assert.assertNotNull(expectedContent);
1729
1730     expectedContent = StringUtil.replace(expectedContent, "\r", "");
1731     final String cleanContent = expectedContent.replaceAll(START_FOLD, "").replaceAll(END_FOLD, "");
1732     final String actual = getFoldingDescription(cleanContent, verificationFileName, doCheckCollapseStatus);
1733
1734     assertEquals(expectedContent, actual);
1735   }
1736
1737   public void testFoldingWithCollapseStatus(final String verificationFileName) {
1738     testFoldingRegions(verificationFileName, true);
1739   }
1740
1741   public void testFolding(final String verificationFileName) {
1742     testFoldingRegions(verificationFileName, false);
1743   }
1744
1745   @Override
1746   public void assertPreferredCompletionItems(final int selected, @NonNls final String... expected) {
1747     final LookupImpl lookup = getLookup();
1748     assertNotNull(lookup);
1749
1750     final LinkedHashMap<LookupElement,StringBuilder> relevanceStrings = lookup.getRelevanceStrings();
1751
1752     final JList list = lookup.getList();
1753     final List<LookupElement> model = lookup.getItems();
1754     final List<String> actual = new ArrayList<String>();
1755     final int count = lookup.getPreferredItemsCount();
1756     for (int i = 0; i < count; i++) {
1757       actual.add(model.get(i).getLookupString());
1758     }
1759     if (!actual.equals(Arrays.asList(expected))) {
1760       final List<String> strings = new ArrayList<String>();
1761       for (int i = 0; i < model.size(); i++) {
1762         final LookupElement item = model.get(i);
1763         strings.add(item.getLookupString() + " " + relevanceStrings.get(item));
1764         if (i == count - 1) {
1765           strings.add("---");
1766         }
1767       }
1768       assertOrderedEquals(strings, expected);
1769     }
1770     assertEquals(selected, list.getSelectedIndex());
1771   }
1772
1773   @Override
1774   public void testStructureView(Consumer<StructureViewComponent> consumer) {
1775     assert myFile != null : "configure first";
1776
1777     final VirtualFile vFile = myFile.getVirtualFile();
1778     assert vFile != null : "no virtual file for " + myFile;
1779
1780     final FileEditor fileEditor = FileEditorManager.getInstance(getProject()).getSelectedEditor(vFile);
1781     assert fileEditor != null : "editor not opened for " + vFile;
1782
1783     final StructureViewBuilder builder = LanguageStructureViewBuilder.INSTANCE.getStructureViewBuilder(myFile);
1784     assert builder != null : "no builder for " + myFile;
1785
1786     StructureViewComponent component = null;
1787     try {
1788       component = (StructureViewComponent)builder.createStructureView(fileEditor, myProjectFixture.getProject());
1789       consumer.consume(component);
1790     }
1791     finally {
1792       if (component != null) Disposer.dispose(component);
1793     }
1794   }
1795
1796   private LookupImpl getLookup() {
1797     return (LookupImpl)LookupManager.getActiveLookup(myEditor);
1798   }
1799
1800 }