el tests
[fedora-idea.git] / source / com / intellij / testFramework / fixtures / impl / CodeInsightTestFixtureImpl.java
blob78d006394e0f7f3175d02080480b9b126429d0fd
1 /*
2 * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
3 */
5 package com.intellij.testFramework.fixtures.impl;
7 import com.intellij.codeHighlighting.HighlightDisplayLevel;
8 import com.intellij.codeInsight.CodeInsightActionHandler;
9 import com.intellij.codeInsight.TargetElementUtilBase;
10 import com.intellij.codeInsight.completion.CodeCompletionHandlerBase;
11 import com.intellij.codeInsight.completion.CompletionContext;
12 import com.intellij.codeInsight.completion.CompletionProgressIndicator;
13 import com.intellij.codeInsight.completion.CompletionType;
14 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
15 import com.intellij.codeInsight.daemon.impl.*;
16 import com.intellij.codeInsight.intention.IntentionAction;
17 import com.intellij.codeInsight.intention.IntentionManager;
18 import com.intellij.codeInsight.lookup.LookupElement;
19 import com.intellij.codeInsight.lookup.LookupManager;
20 import com.intellij.codeInsight.lookup.impl.LookupImpl;
21 import com.intellij.codeInspection.InspectionProfileEntry;
22 import com.intellij.codeInspection.InspectionToolProvider;
23 import com.intellij.codeInspection.LocalInspectionTool;
24 import com.intellij.codeInspection.ModifiableModel;
25 import com.intellij.codeInspection.ex.InspectionProfileImpl;
26 import com.intellij.codeInspection.ex.InspectionTool;
27 import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
28 import com.intellij.facet.Facet;
29 import com.intellij.facet.FacetManager;
30 import com.intellij.find.findUsages.FindUsagesHandler;
31 import com.intellij.find.findUsages.FindUsagesManager;
32 import com.intellij.find.findUsages.FindUsagesOptions;
33 import com.intellij.ide.DataManager;
34 import com.intellij.mock.MockProgressIndicator;
35 import com.intellij.openapi.Disposable;
36 import com.intellij.openapi.actionSystem.DataContext;
37 import com.intellij.openapi.actionSystem.IdeActions;
38 import com.intellij.openapi.application.ApplicationManager;
39 import com.intellij.openapi.application.ModalityState;
40 import com.intellij.openapi.application.Result;
41 import com.intellij.openapi.command.WriteCommandAction;
42 import com.intellij.openapi.editor.*;
43 import com.intellij.openapi.editor.actionSystem.EditorActionManager;
44 import com.intellij.openapi.editor.ex.DocumentEx;
45 import com.intellij.openapi.editor.ex.util.EditorUtil;
46 import com.intellij.openapi.editor.markup.GutterIconRenderer;
47 import com.intellij.openapi.extensions.ExtensionPoint;
48 import com.intellij.openapi.extensions.ExtensionPointName;
49 import com.intellij.openapi.extensions.ExtensionsArea;
50 import com.intellij.openapi.fileEditor.FileEditorManager;
51 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
52 import com.intellij.openapi.fileTypes.FileType;
53 import com.intellij.openapi.fileTypes.FileTypeManager;
54 import com.intellij.openapi.fileTypes.StdFileTypes;
55 import com.intellij.openapi.module.Module;
56 import com.intellij.openapi.project.Project;
57 import com.intellij.openapi.util.*;
58 import com.intellij.openapi.util.io.FileUtil;
59 import com.intellij.openapi.util.text.StringUtil;
60 import com.intellij.openapi.vfs.LocalFileSystem;
61 import com.intellij.openapi.vfs.VfsUtil;
62 import com.intellij.openapi.vfs.VirtualFile;
63 import com.intellij.openapi.vfs.VirtualFileFilter;
64 import com.intellij.profile.codeInspection.InspectionProfileManager;
65 import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
66 import com.intellij.psi.*;
67 import com.intellij.psi.impl.JavaPsiFacadeEx;
68 import com.intellij.psi.impl.PsiManagerImpl;
69 import com.intellij.psi.impl.source.PostprocessReformattingAspect;
70 import com.intellij.psi.impl.source.PsiFileImpl;
71 import com.intellij.psi.impl.source.resolve.FileContextUtil;
72 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
73 import com.intellij.psi.search.GlobalSearchScope;
74 import com.intellij.psi.search.UsageSearchContext;
75 import com.intellij.psi.util.PsiUtilBase;
76 import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor;
77 import com.intellij.refactoring.rename.RenameProcessor;
78 import com.intellij.refactoring.rename.RenamePsiElementProcessor;
79 import com.intellij.testFramework.ExpectedHighlightingData;
80 import com.intellij.testFramework.UsefulTestCase;
81 import com.intellij.testFramework.fixtures.*;
82 import com.intellij.usageView.UsageInfo;
83 import com.intellij.util.ArrayUtil;
84 import com.intellij.util.CommonProcessors;
85 import com.intellij.util.Function;
86 import com.intellij.util.SmartList;
87 import com.intellij.util.containers.ContainerUtil;
88 import gnu.trove.THashMap;
89 import gnu.trove.THashSet;
90 import junit.framework.Assert;
91 import org.jetbrains.annotations.NonNls;
92 import org.jetbrains.annotations.NotNull;
93 import org.jetbrains.annotations.Nullable;
95 import javax.swing.*;
96 import java.io.File;
97 import java.io.IOException;
98 import java.io.OutputStream;
99 import java.util.*;
102 * @author Dmitry Avdeev
104 public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsightTestFixture {
106 @NonNls private static final String PROFILE = "Configurable";
108 private PsiManagerImpl myPsiManager;
109 private PsiFile myFile;
110 private Editor myEditor;
111 private String myTestDataPath;
112 private boolean myEmptyLookup;
114 private LocalInspectionTool[] myInspections;
115 private final Map<String, LocalInspectionTool> myAvailableTools = new THashMap<String, LocalInspectionTool>();
116 private final Map<String, LocalInspectionToolWrapper> myAvailableLocalTools = new THashMap<String, LocalInspectionToolWrapper>();
118 private final TempDirTestFixture myTempDirFixture = new TempDirTestFixtureImpl();
119 private final IdeaProjectTestFixture myProjectFixture;
120 private final Set<VirtualFile> myAddedClasses = new THashSet<VirtualFile>();
121 @NonNls private static final String XXX = "XXX";
122 private PsiElement myFileContext;
124 public CodeInsightTestFixtureImpl(IdeaProjectTestFixture projectFixture) {
125 myProjectFixture = projectFixture;
128 public void setTestDataPath(String dataPath) {
129 myTestDataPath = dataPath;
132 public String getTempDirPath() {
133 return myTempDirFixture.getTempDirPath();
136 public TempDirTestFixture getTempDirFixture() {
137 return myTempDirFixture;
140 public VirtualFile copyFileToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath) throws IOException {
141 final File destFile = new File(getTempDirPath() + "/" + targetPath);
142 if (!destFile.exists()) {
143 File fromFile = new File(getTestDataPath() + "/" + sourceFilePath);
144 if (!fromFile.exists()) {
145 fromFile = new File(sourceFilePath);
148 if (fromFile.isDirectory()) {
149 destFile.mkdirs();
150 } else {
151 FileUtil.copy(fromFile, destFile);
154 final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
155 Assert.assertNotNull(file);
156 return file;
159 public VirtualFile copyDirectoryToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath) throws IOException {
160 final File destFile = new File(getTempDirPath() + "/" + targetPath);
161 final File fromFile = new File(getTestDataPath() + "/" + sourceFilePath);
162 FileUtil.copyDir(fromFile, destFile);
163 final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
164 Assert.assertNotNull(file);
165 file.refresh(false, true);
166 return file;
169 public VirtualFile copyFileToProject(@NonNls final String sourceFilePath) throws IOException {
170 return copyFileToProject(sourceFilePath, sourceFilePath);
173 public void enableInspections(LocalInspectionTool... inspections) {
174 myInspections = inspections;
175 if (isInitialized()) {
176 configureInspections(myInspections);
180 private boolean isInitialized() {
181 return myPsiManager != null;
184 public void enableInspections(final Class<? extends LocalInspectionTool>... inspections) {
185 final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
186 for (Class clazz: inspections) {
187 try {
188 LocalInspectionTool inspection = (LocalInspectionTool)clazz.getConstructor().newInstance();
189 tools.add(inspection);
191 catch (Exception e) {
192 throw new RuntimeException("Cannot instantiate " + clazz);
195 enableInspections(tools.toArray(new LocalInspectionTool[tools.size()]));
198 public void disableInspections(LocalInspectionTool... inspections) {
199 myAvailableTools.clear();
200 myAvailableLocalTools.clear();
201 final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>(Arrays.asList(myInspections));
202 for (Iterator<LocalInspectionTool> i = tools.iterator(); i.hasNext();) {
203 final LocalInspectionTool tool = i.next();
204 for (LocalInspectionTool toRemove: inspections) {
205 if (tool.getShortName().equals(toRemove.getShortName())) {
206 i.remove();
207 break;
211 myInspections = tools.toArray(new LocalInspectionTool[tools.size()]);
212 configureInspections(myInspections);
215 public void enableInspections(InspectionToolProvider... providers) {
216 final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
217 for (InspectionToolProvider provider: providers) {
218 for (Class clazz: provider.getInspectionClasses()) {
219 try {
220 LocalInspectionTool inspection = (LocalInspectionTool)clazz.getConstructor().newInstance();
221 tools.add(inspection);
223 catch (Exception e) {
224 throw new RuntimeException("Cannot instantiate " + clazz);
228 myInspections = tools.toArray(new LocalInspectionTool[tools.size()]);
229 configureInspections(myInspections);
232 public long testHighlighting(final boolean checkWarnings,
233 final boolean checkInfos,
234 final boolean checkWeakWarnings,
235 final String... filePaths) throws Throwable {
237 final Ref<Long> duration = new Ref<Long>();
238 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
240 protected void run() throws Throwable {
241 configureByFilesInner(filePaths);
242 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
244 }.execute().throwException();
245 return duration.get().longValue();
248 public long checkHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings) throws Throwable {
249 final Ref<Long> duration = new Ref<Long>();
250 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
251 protected void run() throws Throwable {
252 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
254 }.execute().throwException();
255 return duration.get().longValue();
258 public long checkHighlighting() throws Throwable {
259 return checkHighlighting(true, true, true);
262 public long testHighlighting(final String... filePaths) throws Throwable {
263 return testHighlighting(true, true, true, filePaths);
266 public long testHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings, final VirtualFile file) throws Throwable {
267 final Ref<Long> duration = new Ref<Long>();
268 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
269 protected void run() throws Throwable {
270 myFile = myPsiManager.findFile(file);
271 myEditor = createEditor(file);
272 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
274 }.execute().throwException();
275 return duration.get().longValue();
278 @Nullable
279 public PsiReference getReferenceAtCaretPosition(final String... filePaths) throws Throwable {
280 new WriteCommandAction<PsiReference>(myProjectFixture.getProject()) {
281 protected void run(final Result<PsiReference> result) throws Throwable {
282 configureByFilesInner(filePaths);
284 }.execute().throwException();
285 return getFile().findReferenceAt(myEditor.getCaretModel().getOffset());
288 @NotNull
289 public PsiReference getReferenceAtCaretPositionWithAssertion(final String... filePaths) throws Throwable {
290 final PsiReference reference = getReferenceAtCaretPosition(filePaths);
291 assert reference != null: "no reference found at " + myEditor.getCaretModel().getLogicalPosition();
292 return reference;
295 @NotNull
296 public List<IntentionAction> getAvailableIntentions(final String... filePaths) throws Throwable {
298 final Project project = myProjectFixture.getProject();
299 return new WriteCommandAction<List<IntentionAction>>(project) {
300 protected void run(final Result<List<IntentionAction>> result) throws Throwable {
301 configureByFilesInner(filePaths);
302 result.setResult(CodeInsightTestFixtureImpl.this.getAvailableIntentions());
304 }.execute().getResultObject();
307 @NotNull
308 public List<IntentionAction> getAvailableIntentions() {
309 int offset = myEditor.getCaretModel().getOffset();
310 return getAvailableIntentions(myProjectFixture.getProject(), doHighlighting(), offset, myEditor, myFile);
313 public List<IntentionAction> filterAvailableIntentions(@NotNull final String hint) throws Throwable {
314 return ContainerUtil.findAll(getAvailableIntentions(),new Condition<IntentionAction>() {
315 public boolean value(final IntentionAction intentionAction) {
316 return intentionAction.getText().contains(hint);
321 public IntentionAction getAvailableIntention(final String intentionName, final String... filePaths) throws Throwable {
322 List<IntentionAction> intentions = getAvailableIntentions(filePaths);
323 return CodeInsightTestUtil.findIntentionByText(intentions, intentionName);
326 public void launchAction(@NotNull final IntentionAction action) throws Throwable {
327 new WriteCommandAction(myProjectFixture.getProject()) {
328 protected void run(final Result result) throws Throwable {
329 action.invoke(getProject(), getEditor(), getFile());
331 }.execute().throwException();
335 public void testCompletion(final String[] filesBefore, final String fileAfter) throws Throwable {
336 assertInitialized();
337 configureByFiles(filesBefore);
338 final LookupElement[] items = complete(CompletionType.BASIC);
339 if (items != null) {
340 System.out.println("items = " + Arrays.toString(items));
342 checkResultByFile(fileAfter);
345 private void assertInitialized() {
346 Assert.assertNotNull("setUp() hasn't been called", myPsiManager);
349 public void testCompletion(String fileBefore, String fileAfter, final String... additionalFiles) throws Throwable {
350 testCompletion(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)), fileAfter);
353 public void testCompletionVariants(final String fileBefore, final String... expectedItems) throws Throwable {
354 assertInitialized();
355 final List<String> result = getCompletionVariants(fileBefore);
356 UsefulTestCase.assertSameElements(result, expectedItems);
359 public List<String> getCompletionVariants(final String fileBefore) throws Throwable {
360 assertInitialized();
361 configureByFiles(fileBefore);
362 final LookupElement[] items = complete(CompletionType.BASIC);
363 Assert.assertNotNull("No lookup was shown, probably there was only one lookup element that was inserted automatically", items);
364 return getLookupElementStrings();
367 @Nullable
368 public List<String> getLookupElementStrings() {
369 assertInitialized();
370 final LookupElement[] elements = getLookupElements();
371 if (elements == null) return null;
373 return ContainerUtil.map(elements, new Function<LookupElement, String>() {
374 public String fun(final LookupElement lookupItem) {
375 return lookupItem.getLookupString();
380 public void testRename(final String fileBefore, final String fileAfter, final String newName, final String... additionalFiles) throws Throwable {
381 assertInitialized();
382 configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)));
383 testRename(fileAfter, newName);
386 public void testRename(final String fileAfter, final String newName) throws Throwable {
387 assertInitialized();
388 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
389 protected void run() throws Throwable {
390 PsiElement element = TargetElementUtilBase.findTargetElement(getCompletionEditor(), TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED | TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
391 assert element != null: "element not found in file " + myFile.getName() + " at caret position, offset " + myEditor.getCaretModel().getOffset();
392 final PsiElement substitution = RenamePsiElementProcessor.forElement(element).substituteElementToRename(element, myEditor);
393 new RenameProcessor(myProjectFixture.getProject(), substitution, newName, false, false).run();
394 checkResultByFile(fileAfter, myFile, false);
396 }.execute().throwException();
399 public void type(final char c) {
400 assertInitialized();
401 new WriteCommandAction(getProject()) {
402 protected void run(Result result) throws Throwable {
403 EditorActionManager actionManager = EditorActionManager.getInstance();
404 final DataContext dataContext = DataManager.getInstance().getDataContext();
405 if (c == '\b') {
406 performEditorAction(IdeActions.ACTION_EDITOR_BACKSPACE);
407 return;
409 if (c == '\n') {
410 performEditorAction(IdeActions.ACTION_EDITOR_ENTER);
411 return;
413 if (c == '\t') {
414 if (LookupManager.getInstance(getProject()).getActiveLookup() != null) {
415 actionManager.getActionHandler(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE).execute(getEditor(), dataContext);
416 return;
420 actionManager.getTypedAction().actionPerformed(getEditor(), c, dataContext);
422 }.execute();
425 public void performEditorAction(final String actionId) {
426 assertInitialized();
427 final DataContext dataContext = DataManager.getInstance().getDataContext();
428 EditorActionManager actionManager = EditorActionManager.getInstance();
429 actionManager.getActionHandler(actionId).execute(getEditor(), dataContext);
432 public JavaPsiFacade getJavaFacade() {
433 assertInitialized();
434 return JavaPsiFacade.getInstance(getProject());
437 public Collection<UsageInfo> testFindUsages(@NonNls final String... fileNames) throws Throwable {
438 assertInitialized();
439 configureByFiles(fileNames);
440 PsiElement referenceTo = TargetElementUtilBase
441 .findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
443 assert referenceTo != null : "Cannot find referenced element";
444 final Project project = getProject();
445 final FindUsagesHandler handler = new FindUsagesManager(project, null).getFindUsagesHandler(referenceTo, false);
447 final CommonProcessors.CollectProcessor<UsageInfo> processor = new CommonProcessors.CollectProcessor<UsageInfo>();
448 final FindUsagesOptions options = new FindUsagesOptions(project);
449 options.isUsages = true;
450 assert handler != null : "Cannot find handler for: " + referenceTo;
451 final PsiElement[] psiElements = ArrayUtil.mergeArrays(handler.getPrimaryElements(), handler.getSecondaryElements(), PsiElement.class);
452 for (PsiElement psiElement : psiElements) {
453 handler.processElementUsages(psiElement, processor, options);
455 return processor.getResults();
458 public void moveFile(@NonNls final String filePath, @NonNls final String to, final String... additionalFiles) throws Throwable {
459 assertInitialized();
460 final Project project = myProjectFixture.getProject();
461 new WriteCommandAction.Simple(project) {
462 protected void run() throws Throwable {
463 configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, filePath)));
464 final VirtualFile file = findFileInTempDir(to);
465 assert file.isDirectory() : to + " is not a directory";
466 final PsiDirectory directory = myPsiManager.findDirectory(file);
467 new MoveFilesOrDirectoriesProcessor(project, new PsiElement[] {myFile}, directory,
468 false, false, null, null).run();
470 }.execute().throwException();
474 @Nullable
475 public GutterIconRenderer findGutter(final String filePath) throws Throwable {
476 assertInitialized();
477 final Project project = myProjectFixture.getProject();
478 final Ref<GutterIconRenderer> result = new Ref<GutterIconRenderer>();
479 new WriteCommandAction.Simple(project) {
481 protected void run() throws Throwable {
482 final int offset = configureByFilesInner(filePath);
484 final Collection<HighlightInfo> infos = doHighlighting();
485 for (HighlightInfo info :infos) {
486 if (info.endOffset >= offset && info.startOffset <= offset) {
487 final GutterIconRenderer renderer = info.getGutterIconRenderer();
488 if (renderer != null) {
489 result.set(renderer);
490 return;
496 }.execute().throwException();
497 return result.get();
500 @NotNull
501 public Collection<GutterIconRenderer> findAllGutters(final String filePath) throws Throwable {
502 assertInitialized();
503 final Project project = myProjectFixture.getProject();
504 final SortedMap<HighlightInfo, List<GutterIconRenderer>> result = new TreeMap<HighlightInfo, List<GutterIconRenderer>>(new Comparator<HighlightInfo>() {
505 public int compare(final HighlightInfo o1, final HighlightInfo o2) {
506 return o1.startOffset - o2.startOffset;
509 new WriteCommandAction.Simple(project) {
511 protected void run() throws Throwable {
512 configureByFilesInner(filePath);
514 final Collection<HighlightInfo> infos = doHighlighting();
515 for (HighlightInfo info :infos) {
516 final GutterIconRenderer renderer = info.getGutterIconRenderer();
517 if (renderer != null) {
518 List<GutterIconRenderer> renderers = result.get(info);
519 if (renderers == null) {
520 result.put(info, renderers = new SmartList<GutterIconRenderer>());
522 renderers.add(renderer);
527 }.execute().throwException();
528 return ContainerUtil.concat(result.values());
531 public PsiClass addClass(@NotNull @NonNls final String classText) throws IOException {
532 assertInitialized();
533 final PsiClass psiClass = ((HeavyIdeaTestFixture)myProjectFixture).addClass(getTempDirPath(), classText);
534 myAddedClasses.add(psiClass.getContainingFile().getVirtualFile());
535 return psiClass;
538 public PsiFile addFileToProject(@NonNls final String relativePath, @NonNls final String fileText) throws IOException {
539 assertInitialized();
540 return ((HeavyIdeaTestFixture)myProjectFixture).addFileToProject(getTempDirPath(), relativePath, fileText);
543 public <T> void registerExtension(final ExtensionsArea area, final ExtensionPointName<T> epName, final T extension) {
544 assertInitialized();
545 final ExtensionPoint<T> extensionPoint = area.getExtensionPoint(epName);
546 extensionPoint.registerExtension(extension);
547 disposeOnTearDown(new Disposable() {
548 public void dispose() {
549 extensionPoint.unregisterExtension(extension);
554 public PsiManager getPsiManager() {
555 return myPsiManager;
558 public LookupElement[] complete(final CompletionType type) {
559 assertInitialized();
560 myEmptyLookup = false;
561 new WriteCommandAction(getProject()) {
562 protected void run(Result result) throws Throwable {
563 final CodeInsightActionHandler handler = new CodeCompletionHandlerBase(type) {
564 protected PsiFile createFileCopy(final PsiFile file) {
565 final PsiFile copy = super.createFileCopy(file);
566 if (myFileContext != null) {
567 final PsiElement contextCopy = myFileContext.copy();
568 final PsiFile containingFile = contextCopy.getContainingFile();
569 if (containingFile instanceof PsiFileImpl) {
570 ((PsiFileImpl)containingFile).setOriginalFile(myFileContext.getContainingFile());
572 setContext(copy, contextCopy);
574 return copy;
577 @Override
578 protected void completionFinished(final int offset1, final int offset2, final CompletionContext context, final CompletionProgressIndicator indicator,
579 final LookupElement[] items) {
580 myEmptyLookup = items.length == 0;
581 super.completionFinished(offset1, offset2, context, indicator, items);
584 Editor editor = getCompletionEditor();
585 handler.invoke(getProject(), editor, PsiUtilBase.getPsiFileInEditor(editor, getProject()));
587 }.execute();
588 return getLookupElements();
591 @Nullable
592 protected Editor getCompletionEditor() {
593 return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
596 @Nullable
597 public LookupElement[] completeBasic() {
598 return complete(CompletionType.BASIC);
601 @Nullable
602 public LookupElement[] getLookupElements() {
603 LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
604 if (lookup == null) {
605 return myEmptyLookup ? LookupElement.EMPTY_ARRAY : null;
607 else {
608 return lookup.getSortedItems();
612 public void checkResult(final String text) throws IOException {
613 PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
614 checkResult("TEXT", false, SelectionAndCaretMarkupLoader.fromText(text, getProject()), myFile.getText());
617 public void checkResultByFile(final String expectedFile) throws Throwable {
618 checkResultByFile(expectedFile, false);
621 public void checkResultByFile(final String expectedFile, final boolean ignoreWhitespaces) throws Throwable {
622 assertInitialized();
623 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
625 protected void run() throws Throwable {
626 checkResultByFile(expectedFile, myFile, ignoreWhitespaces);
628 }.execute().throwException();
631 public void checkResultByFile(final String filePath, final String expectedFile, final boolean ignoreWhitespaces) throws Throwable {
632 assertInitialized();
634 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
636 protected void run() throws Throwable {
637 String fullPath = getTempDirPath() + "/" + filePath;
638 final VirtualFile copy = LocalFileSystem.getInstance().refreshAndFindFileByPath(fullPath.replace(File.separatorChar, '/'));
639 assert copy != null : "file not found: " + fullPath;
640 final PsiFile psiFile = myPsiManager.findFile(copy);
641 assert psiFile != null;
642 checkResultByFile(expectedFile, psiFile, ignoreWhitespaces);
644 }.execute().throwException();
647 public void setUp() throws Exception {
648 super.setUp();
650 myProjectFixture.setUp();
651 myTempDirFixture.setUp();
652 myPsiManager = (PsiManagerImpl)PsiManager.getInstance(getProject());
653 configureInspections(myInspections == null ? new LocalInspectionTool[0] : myInspections);
656 private void enableInspectionTool(LocalInspectionTool tool){
657 final String shortName = tool.getShortName();
658 final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
659 if (key == null){
660 HighlightDisplayKey.register(shortName, tool.getDisplayName(), tool.getID());
662 myAvailableTools.put(shortName, tool);
663 myAvailableLocalTools.put(shortName, new LocalInspectionToolWrapper(tool));
666 private void configureInspections(final LocalInspectionTool[] tools) {
667 for (LocalInspectionTool tool : tools) {
668 enableInspectionTool(tool);
671 final InspectionProfileImpl profile = new InspectionProfileImpl(PROFILE) {
672 public ModifiableModel getModifiableModel() {
673 mySource = this;
674 return this;
677 public InspectionProfileEntry[] getInspectionTools() {
678 final Collection<LocalInspectionToolWrapper> tools = myAvailableLocalTools.values();
679 return tools.toArray(new LocalInspectionToolWrapper[tools.size()]);
682 public boolean isToolEnabled(HighlightDisplayKey key) {
683 return key != null && key.toString() != null && myAvailableTools != null && myAvailableTools.containsKey(key.toString());
686 public HighlightDisplayLevel getErrorLevel(HighlightDisplayKey key) {
687 final LocalInspectionTool localInspectionTool = key == null ? null : myAvailableTools.get(key.toString());
688 return localInspectionTool != null ? localInspectionTool.getDefaultLevel() : HighlightDisplayLevel.WARNING;
691 public InspectionTool getInspectionTool(String shortName) {
692 return myAvailableLocalTools.get(shortName);
695 final InspectionProfileManager inspectionProfileManager = InspectionProfileManager.getInstance();
696 inspectionProfileManager.addProfile(profile);
697 Disposer.register(getProject(), new Disposable() {
698 public void dispose() {
699 inspectionProfileManager.deleteProfile(PROFILE);
702 inspectionProfileManager.setRootProfile(profile.getName());
703 InspectionProjectProfileManager.getInstance(getProject()).updateProfile(profile);
706 public void tearDown() throws Exception {
707 if (SwingUtilities.isEventDispatchThread()) {
708 LookupManager.getInstance(getProject()).hideActiveLookup();
710 else {
711 ApplicationManager.getApplication().invokeAndWait(new Runnable() {
712 public void run() {
713 LookupManager.getInstance(getProject()).hideActiveLookup();
715 }, ModalityState.NON_MODAL);
718 FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
719 VirtualFile[] openFiles = editorManager.getOpenFiles();
720 for (VirtualFile openFile : openFiles) {
721 editorManager.closeFile(openFile);
724 myProjectFixture.tearDown();
725 myTempDirFixture.tearDown();
727 super.tearDown();
730 private int configureByFilesInner(@NonNls String... filePaths) throws IOException {
731 assertInitialized();
732 myFile = null;
733 myEditor = null;
734 for (int i = filePaths.length - 1; i > 0; i--) {
735 configureByFileInner(filePaths[i]);
737 return configureByFileInner(filePaths[0]);
740 public void configureByFile(final String file) throws IOException {
741 assertInitialized();
742 new WriteCommandAction.Simple(getProject()) {
743 protected void run() throws Throwable {
744 configureByFilesInner(file);
746 }.execute();
749 public void configureByFiles(@NonNls final String... files) throws Throwable {
750 new WriteCommandAction.Simple(getProject()) {
751 protected void run() throws Throwable {
752 configureByFilesInner(files);
754 }.execute();
757 public void configureByDirectory(final String dir) {
758 //To change body of implemented methods use File | Settings | File Templates.
761 public PsiFile configureByText(final FileType fileType, @NonNls final String text) throws Throwable {
762 assertInitialized();
763 final String extension = fileType.getDefaultExtension();
764 final File tempFile = File.createTempFile("aaa", "." + extension, new File(getTempDirPath()));
765 final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
766 if (fileTypeManager.getFileTypeByExtension(extension) != fileType) {
767 new WriteCommandAction(getProject()) {
768 protected void run(Result result) throws Throwable {
769 fileTypeManager.associateExtension(fileType, extension);
771 }.execute();
773 final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile);
774 VfsUtil.saveText(vFile, text);
775 assert vFile != null;
776 configureInner(vFile, SelectionAndCaretMarkupLoader.fromFile(vFile, getProject()));
777 return myFile;
780 public Document getDocument(final PsiFile file) {
781 assertInitialized();
782 return PsiDocumentManager.getInstance(getProject()).getDocument(file);
785 public void setFileContext(@Nullable final PsiElement context) {
786 myFileContext = context;
787 setContext(myFile, context);
792 * @param filePath
793 * @return caret offset or -1 if caret marker does not present
794 * @throws IOException
796 private int configureByFileInner(@NonNls String filePath) throws IOException {
797 assertInitialized();
798 copyFileToProject(filePath);
799 return configureFromTempProjectFile(filePath);
802 public int configureFromTempProjectFile(final String filePath) throws IOException {
803 return configureByFileInner(findFileInTempDir(filePath));
806 public void configureFromExistingVirtualFile(VirtualFile f) throws IOException {
807 configureByFileInner(f);
810 private int configureByFileInner(final VirtualFile copy) throws IOException {
811 return configureInner(copy, SelectionAndCaretMarkupLoader.fromFile(copy, getProject()));
814 private int configureInner(@NotNull final VirtualFile copy, final SelectionAndCaretMarkupLoader loader) {
815 assertInitialized();
816 try {
817 final OutputStream outputStream = copy.getOutputStream(null, 0, 0);
818 outputStream.write(loader.newFileText.getBytes());
819 outputStream.close();
821 catch (IOException e) {
822 throw new RuntimeException(e);
824 myFile = myPsiManager.findFile(copy);
825 setContext(myFile, myFileContext);
826 myEditor = createEditor(copy);
827 assert myEditor != null;
828 int offset = -1;
829 if (loader.caretMarker != null) {
830 offset = loader.caretMarker.getStartOffset();
831 myEditor.getCaretModel().moveToOffset(offset);
833 if (loader.selStartMarker != null && loader.selEndMarker != null) {
834 myEditor.getSelectionModel().setSelection(loader.selStartMarker.getStartOffset(), loader.selEndMarker.getStartOffset());
837 Module module = getModule();
838 if (module != null) {
839 for (Facet facet : FacetManager.getInstance(module).getAllFacets()) {
840 module.getMessageBus().syncPublisher(FacetManager.FACETS_TOPIC).facetConfigurationChanged(facet);
844 return offset;
847 private static void setContext(final PsiFile file, final PsiElement context) {
848 if (file != null && context != null) {
849 file.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, new SmartPsiElementPointer() {
850 public PsiElement getElement() {
851 return context;
854 public PsiFile getContainingFile() {
855 return context.getContainingFile();
861 public VirtualFile findFileInTempDir(final String filePath) {
862 String fullPath = getTempDirPath() + "/" + filePath;
864 final VirtualFile copy = LocalFileSystem.getInstance().refreshAndFindFileByPath(fullPath.replace(File.separatorChar, '/'));
865 assert copy != null: "file " + fullPath + " not found";
866 return copy;
869 @Nullable
870 private Editor createEditor(VirtualFile file) {
871 final Project project = getProject();
872 final FileEditorManager instance = FileEditorManager.getInstance(project);
873 if (file.getFileType().isBinary()) {
874 return null;
876 return instance.openTextEditor(new OpenFileDescriptor(project, file, 0), false);
879 private void collectAndCheckHighlightings(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, Ref<Long> duration)
880 throws Exception {
881 final Project project = getProject();
882 ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
884 PsiDocumentManager.getInstance(project).commitAllDocuments();
886 ((PsiFileImpl)myFile).calcTreeElement(); //to load text
888 //to initialize caches
889 myPsiManager.getCacheManager().getFilesWithWord(XXX, UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(project), true);
890 VirtualFileFilter javaFilesFilter = new VirtualFileFilter() {
891 public boolean accept(VirtualFile file) {
892 if (myAddedClasses.contains(file)) return false;
894 FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(file);
895 return fileType == StdFileTypes.JAVA || fileType == StdFileTypes.CLASS;
899 JavaPsiFacadeEx.getInstanceEx(project).setAssertOnFileLoadingFilter(javaFilesFilter); // check repository work
901 final long start = System.currentTimeMillis();
902 // ProfilingUtil.startCPUProfiling();
903 Collection<HighlightInfo> infos = doHighlighting();
904 duration.set(System.currentTimeMillis() - start);
905 // ProfilingUtil.captureCPUSnapshot("testing");
907 JavaPsiFacadeEx.getInstanceEx(project).setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
909 data.checkResult(infos, myEditor.getDocument().getText());
912 @NotNull
913 private Collection<HighlightInfo> doHighlighting() {
915 final Project project = myProjectFixture.getProject();
917 PsiDocumentManager.getInstance(project).commitAllDocuments();
919 Document document = myEditor.getDocument();
920 GeneralHighlightingPass action1 = new GeneralHighlightingPass(project, myFile, document, 0, myFile.getTextLength(), true);
921 action1.doCollectInformation(new MockProgressIndicator());
922 Collection<HighlightInfo> highlights1 = action1.getHighlights();
924 PostHighlightingPass action2 = new PostHighlightingPass(project, myFile, myEditor, 0, myFile.getTextLength());
925 action2.doCollectInformation(new MockProgressIndicator());
926 Collection<HighlightInfo> highlights2 = action2.getHighlights();
928 Collection<HighlightInfo> highlights3 = null;
929 if (!myAvailableTools.isEmpty()) {
930 LocalInspectionsPass inspectionsPass = new LocalInspectionsPass(myFile, myEditor.getDocument(), 0, myFile.getTextLength());
931 inspectionsPass.doCollectInformation(new MockProgressIndicator());
932 highlights3 = inspectionsPass.getHighlights();
935 ExternalToolPass action4 = new ExternalToolPass(myFile, myEditor, 0, myFile.getTextLength());
936 action4.doCollectInformation(new MockProgressIndicator());
937 Collection<HighlightInfo> highlights4 = action4.getHighlights();
939 ArrayList<HighlightInfo> list = new ArrayList<HighlightInfo>();
940 list.addAll(highlights1);
941 list.addAll(highlights2);
942 if (highlights3 != null) {
943 list.addAll(highlights3);
945 list.addAll(highlights4);
946 return list;
949 public String getTestDataPath() {
950 return myTestDataPath;
953 public Project getProject() {
954 return myProjectFixture.getProject();
957 public Module getModule() {
958 return myProjectFixture.getModule();
961 public Editor getEditor() {
962 return myEditor;
965 public PsiFile getFile() {
966 return myFile;
969 public static List<IntentionAction> getAvailableIntentions(final Project project, final Collection<HighlightInfo> infos, final int offset,
970 final Editor editor, final PsiFile file) {
971 final List<IntentionAction> availableActions = new ArrayList<IntentionAction>();
973 for (HighlightInfo info :infos) {
974 if (info.quickFixActionRanges != null) {
975 for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
976 if (offset > 0 && !pair.getSecond().contains(offset)) {
977 continue;
979 final HighlightInfo.IntentionActionDescriptor actionDescriptor = pair.first;
980 final IntentionAction action = actionDescriptor.getAction();
981 if (action.isAvailable(project, editor, file)) {
982 availableActions.add(action);
983 final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
984 assert element != null;
985 final List<IntentionAction> actions = actionDescriptor.getOptions(element);
986 if (actions != null) {
987 for (IntentionAction intentionAction : actions) {
988 if (intentionAction.isAvailable(project, editor, file)) {
989 availableActions.add(intentionAction);
998 for (IntentionAction intentionAction : IntentionManager.getInstance().getIntentionActions()) {
999 if (intentionAction.isAvailable(project, editor, file)) {
1000 availableActions.add(intentionAction);
1003 return availableActions;
1006 static class SelectionAndCaretMarkupLoader {
1007 final String newFileText;
1008 final RangeMarker caretMarker;
1009 final RangeMarker selStartMarker;
1010 final RangeMarker selEndMarker;
1012 static SelectionAndCaretMarkupLoader fromFile(String path, Project project) throws IOException {
1013 return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(new String(FileUtil.loadFileText(new File(path)))), project);
1015 static SelectionAndCaretMarkupLoader fromFile(VirtualFile file, Project project) throws IOException {
1016 return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(VfsUtil.loadText(file)), project);
1019 static SelectionAndCaretMarkupLoader fromText(String text, Project project) {
1020 return new SelectionAndCaretMarkupLoader(text, project);
1023 private SelectionAndCaretMarkupLoader(String fileText, Project project) {
1024 final Document document = EditorFactory.getInstance().createDocument(fileText);
1026 int caretIndex = fileText.indexOf(CARET_MARKER);
1027 int selStartIndex = fileText.indexOf(SELECTION_START_MARKER);
1028 int selEndIndex = fileText.indexOf(SELECTION_END_MARKER);
1030 caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
1031 selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
1032 selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
1034 new WriteCommandAction(project) {
1035 protected void run(Result result) throws Throwable {
1036 if (caretMarker != null) {
1037 document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
1039 if (selStartMarker != null) {
1040 document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
1042 if (selEndMarker != null) {
1043 document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
1046 }.execute();
1048 newFileText = document.getText();
1052 private void checkResultByFile(@NonNls String expectedFile,
1053 @NotNull PsiFile originalFile,
1054 boolean stripTrailingSpaces) throws IOException {
1055 if (!stripTrailingSpaces) {
1056 final LogicalPosition position = myEditor.getCaretModel().getLogicalPosition();
1057 EditorUtil.fillVirtualSpaceUntil(myEditor, position.column, position.line);
1059 PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
1060 checkResult(expectedFile, stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromFile(getTestDataPath() + "/" + expectedFile, getProject()), originalFile.getText());
1063 private void checkResult(final String expectedFile,
1064 final boolean stripTrailingSpaces,
1065 final SelectionAndCaretMarkupLoader loader,
1066 String actualText) {
1067 assertInitialized();
1068 Project project = myProjectFixture.getProject();
1070 project.getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
1071 if (stripTrailingSpaces) {
1072 actualText = stripTrailingSpaces(actualText);
1075 PsiDocumentManager.getInstance(project).commitAllDocuments();
1077 String newFileText1 = loader.newFileText;
1078 if (stripTrailingSpaces) {
1079 newFileText1 = stripTrailingSpaces(newFileText1);
1082 actualText = StringUtil.convertLineSeparators(actualText, "\n");
1084 //noinspection HardCodedStringLiteral
1085 Assert.assertEquals("Text mismatch in file " + expectedFile, newFileText1, actualText);
1087 if (loader.caretMarker != null) {
1088 int caretLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.caretMarker.getStartOffset());
1089 int caretCol = loader.caretMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, caretLine, 0);
1091 Assert.assertEquals("caretLine", caretLine + 1, myEditor.getCaretModel().getLogicalPosition().line + 1);
1092 Assert.assertEquals("caretColumn", caretCol + 1, myEditor.getCaretModel().getLogicalPosition().column + 1);
1095 if (loader.selStartMarker != null && loader.selEndMarker != null) {
1096 int selStartLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selStartMarker.getStartOffset());
1097 int selStartCol = loader.selStartMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0);
1099 int selEndLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selEndMarker.getEndOffset());
1100 int selEndCol = loader.selEndMarker.getEndOffset() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0);
1102 Assert.assertEquals("selectionStartLine", selStartLine + 1,
1103 StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionStart()) + 1);
1105 Assert.assertEquals("selectionStartCol", selStartCol + 1, myEditor.getSelectionModel().getSelectionStart() -
1106 StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0) + 1);
1108 Assert.assertEquals("selectionEndLine", selEndLine + 1,
1109 StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionEnd()) + 1);
1111 Assert.assertEquals("selectionEndCol", selEndCol + 1,
1112 myEditor.getSelectionModel().getSelectionEnd() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0) +
1115 else {
1116 Assert.assertTrue("has no selection", !myEditor.getSelectionModel().hasSelection());
1120 private static String stripTrailingSpaces(String actualText) {
1121 final Document document = EditorFactory.getInstance().createDocument(actualText);
1122 ((DocumentEx)document).stripTrailingSpaces(false);
1123 actualText = document.getText();
1124 return actualText;