2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.intellij.testFramework.fixtures.impl;
19 import com.intellij.analysis.AnalysisScope;
20 import com.intellij.codeHighlighting.HighlightDisplayLevel;
21 import com.intellij.codeHighlighting.TextEditorHighlightingPass;
22 import com.intellij.codeInsight.CodeInsightActionHandler;
23 import com.intellij.codeInsight.TargetElementUtilBase;
24 import com.intellij.codeInsight.completion.CodeCompletionHandlerBase;
25 import com.intellij.codeInsight.completion.CompletionContext;
26 import com.intellij.codeInsight.completion.CompletionProgressIndicator;
27 import com.intellij.codeInsight.completion.CompletionType;
28 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
29 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
30 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
31 import com.intellij.codeInsight.daemon.impl.*;
32 import com.intellij.codeInsight.intention.IntentionAction;
33 import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
34 import com.intellij.codeInsight.lookup.LookupElement;
35 import com.intellij.codeInsight.lookup.LookupManager;
36 import com.intellij.codeInsight.lookup.impl.LookupImpl;
37 import com.intellij.codeInspection.*;
38 import com.intellij.codeInspection.ex.*;
39 import com.intellij.facet.Facet;
40 import com.intellij.facet.FacetManager;
41 import com.intellij.find.FindManager;
42 import com.intellij.find.findUsages.FindUsagesHandler;
43 import com.intellij.find.findUsages.FindUsagesOptions;
44 import com.intellij.find.impl.FindManagerImpl;
45 import com.intellij.ide.DataManager;
46 import com.intellij.lang.annotation.HighlightSeverity;
47 import com.intellij.openapi.Disposable;
48 import com.intellij.openapi.actionSystem.DataContext;
49 import com.intellij.openapi.actionSystem.IdeActions;
50 import com.intellij.openapi.application.ApplicationManager;
51 import com.intellij.openapi.application.ModalityState;
52 import com.intellij.openapi.application.Result;
53 import com.intellij.openapi.command.WriteCommandAction;
54 import com.intellij.openapi.editor.Document;
55 import com.intellij.openapi.editor.Editor;
56 import com.intellij.openapi.editor.EditorFactory;
57 import com.intellij.openapi.editor.RangeMarker;
58 import com.intellij.openapi.editor.actionSystem.EditorActionManager;
59 import com.intellij.openapi.editor.ex.DocumentEx;
60 import com.intellij.openapi.editor.ex.util.EditorUtil;
61 import com.intellij.openapi.editor.markup.GutterIconRenderer;
62 import com.intellij.openapi.editor.markup.RangeHighlighter;
63 import com.intellij.openapi.extensions.ExtensionPoint;
64 import com.intellij.openapi.extensions.ExtensionPointName;
65 import com.intellij.openapi.extensions.ExtensionsArea;
66 import com.intellij.openapi.fileEditor.FileEditorManager;
67 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
68 import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
69 import com.intellij.openapi.fileTypes.FileType;
70 import com.intellij.openapi.fileTypes.FileTypeManager;
71 import com.intellij.openapi.module.Module;
72 import com.intellij.openapi.progress.ProgressIndicator;
73 import com.intellij.openapi.progress.ProgressManager;
74 import com.intellij.openapi.project.DumbServiceImpl;
75 import com.intellij.openapi.project.Project;
76 import com.intellij.openapi.util.*;
77 import com.intellij.openapi.util.io.FileUtil;
78 import com.intellij.openapi.util.text.StringUtil;
79 import com.intellij.openapi.vfs.LocalFileSystem;
80 import com.intellij.openapi.vfs.VfsUtil;
81 import com.intellij.openapi.vfs.VirtualFile;
82 import com.intellij.openapi.vfs.VirtualFileFilter;
83 import com.intellij.profile.codeInspection.InspectionProfileManager;
84 import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
85 import com.intellij.psi.*;
86 import com.intellij.psi.impl.PsiManagerImpl;
87 import com.intellij.psi.impl.cache.impl.todo.TodoIndex;
88 import com.intellij.psi.impl.source.PostprocessReformattingAspect;
89 import com.intellij.psi.impl.source.PsiFileImpl;
90 import com.intellij.psi.impl.source.resolve.FileContextUtil;
91 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
92 import com.intellij.psi.search.GlobalSearchScope;
93 import com.intellij.psi.search.UsageSearchContext;
94 import com.intellij.psi.stubs.StubUpdatingIndex;
95 import com.intellij.psi.util.PsiUtilBase;
96 import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor;
97 import com.intellij.refactoring.rename.RenameProcessor;
98 import com.intellij.refactoring.rename.RenamePsiElementProcessor;
99 import com.intellij.testFramework.*;
100 import com.intellij.testFramework.fixtures.*;
101 import com.intellij.usageView.UsageInfo;
102 import com.intellij.util.ArrayUtil;
103 import com.intellij.util.CommonProcessors;
104 import com.intellij.util.Function;
105 import com.intellij.util.SmartList;
106 import com.intellij.util.containers.ContainerUtil;
107 import com.intellij.util.indexing.FileBasedIndex;
108 import gnu.trove.THashMap;
109 import junit.framework.Assert;
110 import org.jetbrains.annotations.NonNls;
111 import org.jetbrains.annotations.NotNull;
112 import org.jetbrains.annotations.Nullable;
114 import javax.swing.*;
116 import java.io.IOException;
117 import java.io.OutputStream;
121 * @author Dmitry Avdeev
123 @SuppressWarnings({"TestMethodWithIncorrectSignature"})
124 public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsightTestFixture {
126 @NonNls private static final String PROFILE = "Configurable";
128 private PsiManagerImpl myPsiManager;
129 private PsiFile myFile;
130 private Editor myEditor;
131 private String myTestDataPath;
132 private boolean myEmptyLookup;
134 private InspectionProfileEntry[] myInspections;
135 private final Map<String, InspectionProfileEntry> myAvailableTools = new THashMap<String, InspectionProfileEntry>();
136 private final Map<String, InspectionTool> myAvailableLocalTools = new THashMap<String, InspectionTool>();
138 private final TempDirTestFixture myTempDirFixture;
139 protected final IdeaProjectTestFixture myProjectFixture;
140 @NonNls private static final String XXX = "XXX";
141 private PsiElement myFileContext;
142 private final FileTreeAccessFilter myJavaFilesFilter = new FileTreeAccessFilter();
144 public CodeInsightTestFixtureImpl(IdeaProjectTestFixture projectFixture, TempDirTestFixture tempDirTestFixture) {
145 myProjectFixture = projectFixture;
146 myTempDirFixture = tempDirTestFixture;
149 public void setTestDataPath(String dataPath) {
150 myTestDataPath = dataPath;
153 public String getTempDirPath() {
154 return myTempDirFixture.getTempDirPath();
157 public TempDirTestFixture getTempDirFixture() {
158 return myTempDirFixture;
161 public VirtualFile copyFileToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath) throws IOException {
162 File fromFile = new File(getTestDataPath() + "/" + sourceFilePath);
163 if (!fromFile.exists()) {
164 fromFile = new File(sourceFilePath);
167 if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
168 VirtualFile fromVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(fromFile);
169 if (fromVFile == null) {
170 fromVFile = myTempDirFixture.getFile(sourceFilePath);
172 assert fromVFile != null: "can't find testdata file " + sourceFilePath;
173 return myTempDirFixture.copyFile(fromVFile, targetPath);
175 final File destFile = new File(getTempDirPath() + "/" + targetPath);
176 if (!destFile.exists()) {
178 if (fromFile.isDirectory()) {
182 FileUtil.copy(fromFile, destFile);
185 final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
186 Assert.assertNotNull(file);
190 public VirtualFile copyDirectoryToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath) throws IOException {
191 assert getTestDataPath() != null: "test data path not specified";
192 final File fromFile = new File(getTestDataPath() + "/" + sourceFilePath);
193 if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
194 return myTempDirFixture.copyAll(fromFile.getPath(), targetPath);
197 final File destFile = new File(getTempDirPath() + "/" + targetPath);
198 FileUtil.copyDir(fromFile, destFile);
199 final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
200 Assert.assertNotNull(file);
201 file.refresh(false, true);
206 public VirtualFile copyFileToProject(@NonNls final String sourceFilePath) throws IOException {
207 return copyFileToProject(sourceFilePath, sourceFilePath);
210 public void enableInspections(InspectionProfileEntry... inspections) {
211 myInspections = inspections;
212 if (isInitialized()) {
213 configureInspections(myInspections);
217 private boolean isInitialized() {
218 return myPsiManager != null;
221 public void enableInspections(final Class<? extends LocalInspectionTool>... inspections) {
222 final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
223 for (Class clazz: inspections) {
225 LocalInspectionTool inspection = (LocalInspectionTool)clazz.getConstructor().newInstance();
226 tools.add(inspection);
228 catch (Exception e) {
229 throw new RuntimeException("Cannot instantiate " + clazz);
232 enableInspections(tools.toArray(new LocalInspectionTool[tools.size()]));
235 public void disableInspections(InspectionProfileEntry... inspections) {
236 myAvailableTools.clear();
237 myAvailableLocalTools.clear();
238 final ArrayList<InspectionProfileEntry> tools = new ArrayList<InspectionProfileEntry>(Arrays.asList(myInspections));
239 for (Iterator<InspectionProfileEntry> i = tools.iterator(); i.hasNext();) {
240 final InspectionProfileEntry tool = i.next();
241 for (InspectionProfileEntry toRemove: inspections) {
242 if (tool.getShortName().equals(toRemove.getShortName())) {
248 myInspections = tools.toArray(new InspectionProfileEntry[tools.size()]);
249 configureInspections(myInspections);
252 public void enableInspections(InspectionToolProvider... providers) {
253 final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
254 for (InspectionToolProvider provider: providers) {
255 for (Class clazz: provider.getInspectionClasses()) {
257 Object o = clazz.getConstructor().newInstance();
258 if (o instanceof LocalInspectionTool) {
259 LocalInspectionTool inspection = (LocalInspectionTool)o;
260 tools.add(inspection);
263 catch (Exception e) {
264 throw new RuntimeException("Cannot instantiate " + clazz, e);
268 myInspections = tools.toArray(new LocalInspectionTool[tools.size()]);
269 configureInspections(myInspections);
272 public long testHighlighting(final boolean checkWarnings,
273 final boolean checkInfos,
274 final boolean checkWeakWarnings,
275 final String... filePaths) throws Exception {
276 final Ref<Long> duration = new Ref<Long>();
277 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
279 protected void run() throws Exception {
280 if (filePaths.length > 0) {
281 configureByFilesInner(filePaths);
283 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
285 }.execute().throwException();
286 return duration.get().longValue();
289 public long testHighlightingAllFiles(final boolean checkWarnings,
290 final boolean checkInfos,
291 final boolean checkWeakWarnings,
292 @NonNls final String... filePaths) throws Exception {
293 final ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
294 for (String path : filePaths) {
295 files.add(copyFileToProject(path));
297 return testHighlightingAllFiles(checkWarnings, checkInfos, checkWeakWarnings, VfsUtil.toVirtualFileArray(files));
300 public long testHighlightingAllFiles(final boolean checkWarnings,
301 final boolean checkInfos,
302 final boolean checkWeakWarnings,
303 @NonNls final VirtualFile... files) throws Exception {
304 final Ref<Long> duration = new Ref<Long>();
305 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
307 protected void run() throws Exception {
308 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration, files);
310 }.execute().throwException();
311 return duration.get().longValue();
314 private void collectAndCheckHighlightings(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings, final Ref<Long> duration,
315 final VirtualFile[] files) {
316 final List<Trinity<PsiFile, Editor, ExpectedHighlightingData>> datas = ContainerUtil.map2List(files, new Function<VirtualFile, Trinity<PsiFile, Editor, ExpectedHighlightingData>>() {
317 public Trinity<PsiFile, Editor, ExpectedHighlightingData> fun(final VirtualFile file) {
318 final PsiFile psiFile = myPsiManager.findFile(file);
319 assertNotNull(psiFile);
320 final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(psiFile);
321 assertNotNull(document);
322 return Trinity.create(psiFile, createEditor(file), new ExpectedHighlightingData(document, checkWarnings, checkWeakWarnings, checkInfos, psiFile));
325 for (Trinity<PsiFile, Editor, ExpectedHighlightingData> trinity : datas) {
326 myEditor = trinity.second;
327 myFile = trinity.first;
328 collectAndCheckHighlightings(trinity.third, duration);
332 public long checkHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings) throws Exception {
333 final Ref<Long> duration = new Ref<Long>();
334 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
335 protected void run() throws Exception {
336 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
338 }.execute().throwException();
339 return duration.get().longValue();
342 public long checkHighlighting() throws Exception {
343 return checkHighlighting(true, true, true);
346 public long testHighlighting(final String... filePaths) throws Exception {
347 return testHighlighting(true, true, true, filePaths);
350 public long testHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings, final VirtualFile file) throws Exception {
351 final Ref<Long> duration = new Ref<Long>();
352 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
353 protected void run() throws Exception {
354 openFileInEditor(file);
355 collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
357 }.execute().throwException();
358 return duration.get().longValue();
361 public void openFileInEditor(@NotNull final VirtualFile file) {
362 myFile = myPsiManager.findFile(file);
363 myEditor = createEditor(file);
366 public void testInspection(String testDir, InspectionTool tool) throws Exception {
367 VirtualFile sourceDir = copyDirectoryToProject(new File(testDir, "src").getPath(), "src");
368 AnalysisScope scope = new AnalysisScope(getPsiManager().findDirectory(sourceDir));
370 InspectionManagerEx inspectionManager = (InspectionManagerEx) InspectionManager.getInstance(getProject());
371 final GlobalInspectionContextImpl globalContext = inspectionManager.createNewGlobalContext(!(myProjectFixture instanceof LightIdeaTestFixture));
372 globalContext.setCurrentScope(scope);
375 InspectionTestUtil.runTool(tool, scope, globalContext, inspectionManager);
376 InspectionTestUtil.compareToolResults(tool, false, new File(getTestDataPath(), testDir).getPath());
380 public PsiReference getReferenceAtCaretPosition(final String... filePaths) throws Exception {
381 new WriteCommandAction<PsiReference>(myProjectFixture.getProject()) {
382 protected void run(final Result<PsiReference> result) throws Exception {
383 configureByFilesInner(filePaths);
385 }.execute().throwException();
386 return getFile().findReferenceAt(myEditor.getCaretModel().getOffset());
390 public PsiReference getReferenceAtCaretPositionWithAssertion(final String... filePaths) throws Exception {
391 final PsiReference reference = getReferenceAtCaretPosition(filePaths);
392 assert reference != null: "no reference found at " + myEditor.getCaretModel().getLogicalPosition();
397 public List<IntentionAction> getAvailableIntentions(final String... filePaths) throws Exception {
399 return new WriteCommandAction<List<IntentionAction>>(myProjectFixture.getProject()) {
400 protected void run(final Result<List<IntentionAction>> result) throws Exception {
401 configureByFilesInner(filePaths);
402 result.setResult(getAvailableIntentions());
404 }.execute().getResultObject();
408 public List<IntentionAction> getAllQuickFixes(@NonNls final String... filePaths) {
409 return new WriteCommandAction<List<IntentionAction>>(myProjectFixture.getProject()) {
410 protected void run(final Result<List<IntentionAction>> result) throws Exception {
411 configureByFilesInner(filePaths);
412 List<HighlightInfo> infos = doHighlighting();
413 ArrayList<IntentionAction> actions = new ArrayList<IntentionAction>();
414 for (HighlightInfo info : infos) {
415 for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
416 actions.add(pair.getFirst().getAction());
419 result.setResult(actions);
421 }.execute().getResultObject();
425 public List<IntentionAction> getAvailableIntentions() {
427 return getAvailableIntentions(myEditor, myFile);
430 public List<IntentionAction> filterAvailableIntentions(@NotNull final String hint) throws Exception {
431 final List<IntentionAction> availableIntentions = getAvailableIntentions();
432 return ContainerUtil.findAll(availableIntentions, new Condition<IntentionAction>() {
433 public boolean value(final IntentionAction intentionAction) {
434 return intentionAction.getText().startsWith(hint);
439 public IntentionAction findSingleIntention(@NotNull final String hint) throws Exception {
440 final List<IntentionAction> list = filterAvailableIntentions(hint);
441 if (list.size() != 1) {
442 Assert.fail(StringUtil.join(getAvailableIntentions(), new Function<IntentionAction, String>() {
443 public String fun(final IntentionAction intentionAction) {
444 return intentionAction.getText();
448 return UsefulTestCase.assertOneElement(list);
451 public IntentionAction getAvailableIntention(final String intentionName, final String... filePaths) throws Exception {
452 List<IntentionAction> intentions = getAvailableIntentions(filePaths);
453 return CodeInsightTestUtil.findIntentionByText(intentions, intentionName);
456 public void launchAction(@NotNull final IntentionAction action) throws Exception {
457 new WriteCommandAction(myProjectFixture.getProject()) {
458 protected void run(final Result result) throws Exception {
459 ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText());
461 }.execute().throwException();
465 public void testCompletion(final String[] filesBefore, final String fileAfter) throws Exception {
467 configureByFiles(filesBefore);
468 final LookupElement[] items = complete(CompletionType.BASIC);
470 System.out.println("items = " + Arrays.toString(items));
472 checkResultByFile(fileAfter);
475 protected void assertInitialized() {
476 Assert.assertNotNull("setUp() hasn't been called", myPsiManager);
479 public void testCompletion(String fileBefore, String fileAfter, final String... additionalFiles) throws Exception {
480 testCompletion(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)), fileAfter);
483 public void testCompletionVariants(final String fileBefore, final String... expectedItems) throws Exception {
485 final List<String> result = getCompletionVariants(fileBefore);
486 UsefulTestCase.assertSameElements(result, expectedItems);
489 public List<String> getCompletionVariants(final String... filesBefore) throws Exception {
491 configureByFiles(filesBefore);
492 final LookupElement[] items = complete(CompletionType.BASIC);
493 Assert.assertNotNull("No lookup was shown, probably there was only one lookup element that was inserted automatically", items);
494 return getLookupElementStrings();
498 public List<String> getLookupElementStrings() {
500 final LookupElement[] elements = getLookupElements();
501 if (elements == null) return null;
503 return ContainerUtil.map(elements, new Function<LookupElement, String>() {
504 public String fun(final LookupElement lookupItem) {
505 return lookupItem.getLookupString();
510 public void testRename(final String fileBefore, final String fileAfter, final String newName, final String... additionalFiles) throws Exception {
512 configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)));
513 testRename(fileAfter, newName);
516 public void testRename(final String fileAfter, final String newName) throws Exception {
517 renameElementAtCaret(newName);
518 checkResultByFile(fileAfter);
521 public void renameElementAtCaret(final String newName) throws Exception {
523 final PsiElement element = TargetElementUtilBase.findTargetElement(getCompletionEditor(), TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED |
524 TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
525 assert element != null : "element not found in file " + myFile.getName() + " at caret position, offset " +
526 myEditor.getCaretModel().getOffset();
527 renameElement(element, newName);
530 public void renameElement(final PsiElement element, final String newName) throws Exception {
531 final boolean searchInComments = false;
532 final boolean searchTextOccurrences = false;
533 renameElement(element, newName, searchInComments, searchTextOccurrences);
536 public void renameElement(final PsiElement element,
537 final String newName,
538 final boolean searchInComments,
539 final boolean searchTextOccurrences) throws Exception {
540 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
541 protected void run() throws Exception {
542 final PsiElement substitution = RenamePsiElementProcessor.forElement(element).substituteElementToRename(element, myEditor);
543 new RenameProcessor(myProjectFixture.getProject(), substitution, newName, searchInComments, searchTextOccurrences).run();
545 }.execute().throwException();
548 public void type(final char c) {
550 new WriteCommandAction(getProject()) {
551 protected void run(Result result) throws Exception {
552 EditorActionManager actionManager = EditorActionManager.getInstance();
553 final DataContext dataContext = DataManager.getInstance().getDataContext();
555 performEditorAction(IdeActions.ACTION_EDITOR_BACKSPACE);
559 if (LookupManager.getActiveLookup(getEditor()) != null) {
560 performEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM);
564 performEditorAction(IdeActions.ACTION_EDITOR_ENTER);
568 if (LookupManager.getInstance(getProject()).getActiveLookup() != null) {
569 performEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE);
574 actionManager.getTypedAction().actionPerformed(getEditor(), c, dataContext);
579 public void performEditorAction(final String actionId) {
581 final DataContext dataContext = DataManager.getInstance().getDataContext();
582 EditorActionManager actionManager = EditorActionManager.getInstance();
583 actionManager.getActionHandler(actionId).execute(getEditor(), dataContext);
586 public Collection<UsageInfo> testFindUsages(@NonNls final String... fileNames) throws Exception {
588 configureByFiles(fileNames);
589 final PsiElement targetElement = TargetElementUtilBase
590 .findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
591 assert targetElement != null : "Cannot find referenced element";
592 return findUsages(targetElement);
595 public Collection<UsageInfo> findUsages(@NotNull final PsiElement targetElement) {
596 final Project project = getProject();
597 final FindUsagesHandler handler = ((FindManagerImpl)FindManager.getInstance(project)).getFindUsagesManager().getFindUsagesHandler(targetElement, false);
599 final CommonProcessors.CollectProcessor<UsageInfo> processor = new CommonProcessors.CollectProcessor<UsageInfo>();
600 final FindUsagesOptions options = new FindUsagesOptions(project, null);
601 options.isUsages = true;
602 assert handler != null : "Cannot find handler for: " + targetElement;
603 final PsiElement[] psiElements = ArrayUtil.mergeArrays(handler.getPrimaryElements(), handler.getSecondaryElements(), PsiElement.class);
604 for (PsiElement psiElement : psiElements) {
605 handler.processElementUsages(psiElement, processor, options);
607 return processor.getResults();
610 public void moveFile(@NonNls final String filePath, @NonNls final String to, final String... additionalFiles) throws Exception {
612 final Project project = myProjectFixture.getProject();
613 new WriteCommandAction.Simple(project) {
614 protected void run() throws Exception {
615 configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, filePath)));
616 final VirtualFile file = findFileInTempDir(to);
617 assert file.isDirectory() : to + " is not a directory";
618 final PsiDirectory directory = myPsiManager.findDirectory(file);
619 new MoveFilesOrDirectoriesProcessor(project, new PsiElement[] {myFile}, directory,
620 false, false, null, null).run();
622 }.execute().throwException();
627 public GutterIconRenderer findGutter(final String filePath) throws Exception {
629 final Project project = myProjectFixture.getProject();
630 final Ref<GutterIconRenderer> result = new Ref<GutterIconRenderer>();
631 new WriteCommandAction.Simple(project) {
633 protected void run() throws Exception {
634 final int offset = configureByFilesInner(filePath);
636 final Collection<HighlightInfo> infos = doHighlighting();
637 for (HighlightInfo info :infos) {
638 if (info.endOffset >= offset && info.startOffset <= offset) {
639 final GutterIconRenderer renderer = info.getGutterIconRenderer();
640 if (renderer != null) {
641 result.set(renderer);
648 }.execute().throwException();
653 public Collection<GutterIconRenderer> findAllGutters(final String filePath) throws Exception {
655 final Project project = myProjectFixture.getProject();
656 final SortedMap<Integer, List<GutterIconRenderer>> result = new TreeMap<Integer, List<GutterIconRenderer>>();
657 new WriteCommandAction.Simple(project) {
659 protected void run() throws Exception {
660 configureByFilesInner(filePath);
662 for (HighlightInfo info : doHighlighting()) {
663 addGutterIconRenderer(info.getGutterIconRenderer(), info.startOffset);
666 for (final RangeHighlighter highlighter : myEditor.getDocument().getMarkupModel(project).getAllHighlighters()) {
667 addGutterIconRenderer(highlighter.getGutterIconRenderer(), highlighter.getStartOffset());
671 private void addGutterIconRenderer(final GutterIconRenderer renderer, final int offset) {
672 if (renderer == null) return;
674 List<GutterIconRenderer> renderers = result.get(offset);
675 if (renderers == null) {
676 result.put(offset, renderers = new SmartList<GutterIconRenderer>());
678 renderers.add(renderer);
681 }.execute().throwException();
682 return ContainerUtil.concat(result.values());
686 public PsiFile addFileToProject(@NonNls final String relativePath, @NonNls final String fileText) throws IOException {
688 return addFileToProject(getTempDirPath(), relativePath, fileText);
691 protected PsiFile addFileToProject(String rootPath, String relativePath, String fileText) throws IOException {
692 if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
693 final VirtualFile file = myTempDirFixture.createFile(relativePath, fileText);
694 return PsiManager.getInstance(getProject()).findFile(file);
697 return ((HeavyIdeaTestFixture)myProjectFixture).addFileToProject(rootPath, relativePath, fileText);
700 public <T> void registerExtension(final ExtensionsArea area, final ExtensionPointName<T> epName, final T extension) {
702 final ExtensionPoint<T> extensionPoint = area.getExtensionPoint(epName);
703 extensionPoint.registerExtension(extension);
704 disposeOnTearDown(new Disposable() {
705 public void dispose() {
706 extensionPoint.unregisterExtension(extension);
711 public PsiManager getPsiManager() {
715 public LookupElement[] complete(final CompletionType type) {
717 myEmptyLookup = false;
718 new WriteCommandAction(getProject()) {
719 protected void run(Result result) throws Exception {
720 final CodeInsightActionHandler handler = new CodeCompletionHandlerBase(type) {
721 protected PsiFile createFileCopy(final PsiFile file) {
722 final PsiFile copy = super.createFileCopy(file);
723 if (myFileContext != null) {
724 final PsiElement contextCopy = myFileContext.copy();
725 final PsiFile containingFile = contextCopy.getContainingFile();
726 if (containingFile instanceof PsiFileImpl) {
727 ((PsiFileImpl)containingFile).setOriginalFile(myFileContext.getContainingFile());
729 setContext(copy, contextCopy);
735 protected void completionFinished(final int offset1, final int offset2, final CompletionContext context, final CompletionProgressIndicator indicator,
736 final LookupElement[] items) {
737 myEmptyLookup = items.length == 0;
738 super.completionFinished(offset1, offset2, context, indicator, items);
741 Editor editor = getCompletionEditor();
742 handler.invoke(getProject(), editor, PsiUtilBase.getPsiFileInEditor(editor, getProject()));
745 return getLookupElements();
749 protected Editor getCompletionEditor() {
750 return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
754 public LookupElement[] completeBasic() {
755 return complete(CompletionType.BASIC);
759 public LookupElement[] getLookupElements() {
760 LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
761 if (lookup == null) {
762 return myEmptyLookup ? LookupElement.EMPTY_ARRAY : null;
765 final List<LookupElement> list = lookup.getItems();
766 return list.toArray(new LookupElement[list.size()]);
770 public void checkResult(final String text) throws IOException {
771 checkResult(text, false);
774 public void checkResult(String text, boolean stripTrailingSpaces) throws IOException {
775 PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
776 EditorUtil.fillVirtualSpaceUntilCaret(myEditor);
777 checkResult("TEXT", stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromText(text, getProject()), myFile.getText());
780 public void checkResultByFile(final String expectedFile) throws Exception {
781 checkResultByFile(expectedFile, false);
784 public void checkResultByFile(final String expectedFile, final boolean ignoreTrailingWhitespaces) throws Exception {
786 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
788 protected void run() throws Exception {
789 checkResultByFile(expectedFile, myFile, ignoreTrailingWhitespaces);
791 }.execute().throwException();
794 public void checkResultByFile(final String filePath, final String expectedFile, final boolean ignoreTrailingWhitespaces) throws Exception {
797 new WriteCommandAction.Simple(myProjectFixture.getProject()) {
799 protected void run() throws Exception {
800 final VirtualFile copy = findFileInTempDir(filePath.replace(File.separatorChar, '/'));
801 final PsiFile psiFile = myPsiManager.findFile(copy);
802 assert psiFile != null;
803 checkResultByFile(expectedFile, psiFile, ignoreTrailingWhitespaces);
805 }.execute().throwException();
808 public void setUp() throws Exception {
811 myProjectFixture.setUp();
812 myTempDirFixture.setUp();
813 myPsiManager = (PsiManagerImpl)PsiManager.getInstance(getProject());
814 configureInspections(myInspections == null ? new LocalInspectionTool[0] : myInspections);
815 DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
818 private void enableInspectionTool(InspectionProfileEntry tool){
819 final String shortName = tool.getShortName();
820 final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
822 String id = tool instanceof LocalInspectionTool ? ((LocalInspectionTool)tool).getID() : shortName;
823 HighlightDisplayKey.register(shortName, tool.getDisplayName(), id);
825 myAvailableTools.put(shortName, tool);
826 myAvailableLocalTools.put(shortName, tool instanceof LocalInspectionTool ?
827 new LocalInspectionToolWrapper((LocalInspectionTool)tool) :
828 (InspectionTool)tool);
831 private void configureInspections(final InspectionProfileEntry[] tools) {
832 for (InspectionProfileEntry tool : tools) {
833 enableInspectionTool(tool);
836 final InspectionProfileImpl profile = new InspectionProfileImpl(PROFILE) {
838 public ModifiableModel getModifiableModel() {
844 public InspectionProfileEntry[] getInspectionTools(PsiElement element) {
845 final Collection<InspectionTool> tools = myAvailableLocalTools.values();
846 return tools.toArray(new InspectionTool[tools.size()]);
850 public List<ToolsImpl> getAllEnabledInspectionTools() {
851 List<ToolsImpl> result = new ArrayList<ToolsImpl>();
852 for (InspectionProfileEntry entry : getInspectionTools(null)) {
853 result.add(new ToolsImpl(entry, entry.getDefaultLevel(), true));
858 public boolean isToolEnabled(HighlightDisplayKey key, PsiElement element) {
859 return key != null && key.toString() != null && myAvailableTools.containsKey(key.toString());
862 public HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey key, PsiElement element) {
863 final InspectionProfileEntry entry = myAvailableTools.get(key.toString());
864 return entry != null ? entry.getDefaultLevel() : HighlightDisplayLevel.WARNING;
867 public InspectionTool getInspectionTool(@NotNull String shortName, @NotNull PsiElement element) {
868 return myAvailableLocalTools.get(shortName);
871 final InspectionProfileManager inspectionProfileManager = InspectionProfileManager.getInstance();
872 inspectionProfileManager.addProfile(profile);
873 Disposer.register(getProject(), new Disposable() {
874 public void dispose() {
875 inspectionProfileManager.deleteProfile(PROFILE);
878 inspectionProfileManager.setRootProfile(profile.getName());
879 InspectionProjectProfileManager.getInstance(getProject()).updateProfile(profile);
880 InspectionProjectProfileManager.getInstance(getProject()).setProjectProfile(profile.getName());
883 public void tearDown() throws Exception {
884 if (SwingUtilities.isEventDispatchThread()) {
885 LookupManager.getInstance(getProject()).hideActiveLookup();
888 ApplicationManager.getApplication().invokeAndWait(new Runnable() {
890 LookupManager.getInstance(getProject()).hideActiveLookup();
892 }, ModalityState.NON_MODAL);
895 FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
896 VirtualFile[] openFiles = editorManager.getOpenFiles();
897 for (VirtualFile openFile : openFiles) {
898 editorManager.closeFile(openFile);
901 myProjectFixture.tearDown();
902 myTempDirFixture.tearDown();
907 private int configureByFilesInner(@NonNls String... filePaths) throws IOException {
911 for (int i = filePaths.length - 1; i > 0; i--) {
912 configureByFileInner(filePaths[i]);
914 return configureByFileInner(filePaths[0]);
917 public void configureByFile(final String file) throws IOException {
919 new WriteCommandAction.Simple(getProject()) {
920 protected void run() throws Exception {
921 configureByFilesInner(file);
926 public void configureByFiles(@NonNls final String... files) throws Exception {
927 new WriteCommandAction.Simple(getProject()) {
928 protected void run() throws Exception {
929 configureByFilesInner(files);
934 public PsiFile configureByText(final FileType fileType, @NonNls final String text) throws IOException {
936 final String extension = fileType.getDefaultExtension();
937 final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
938 if (fileTypeManager.getFileTypeByExtension(extension) != fileType) {
939 new WriteCommandAction(getProject()) {
940 protected void run(Result result) throws Exception {
941 fileTypeManager.associateExtension(fileType, extension);
945 final VirtualFile vFile;
946 if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
947 final VirtualFile root = LightPlatformTestCase.getSourceRoot();
948 root.refresh(false, false);
949 vFile = root.findOrCreateChildData(this, "aaa." + extension);
952 final File tempFile = File.createTempFile("aaa", "." + extension, new File(getTempDirPath()));
953 vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile);
955 VfsUtil.saveText(vFile, text);
956 configureInner(vFile, SelectionAndCaretMarkupLoader.fromFile(vFile, getProject()));
960 public PsiFile configureByText(String fileName, @NonNls String text) throws IOException {
961 return configureByText(FileTypeManager.getInstance().getFileTypeByFileName(fileName), text);
964 public Document getDocument(final PsiFile file) {
966 return PsiDocumentManager.getInstance(getProject()).getDocument(file);
969 public void setFileContext(@Nullable final PsiElement context) {
970 myFileContext = context;
971 setContext(myFile, context);
977 * @return caret offset or -1 if caret marker does not present
978 * @throws IOException
980 private int configureByFileInner(@NonNls String filePath) throws IOException {
982 final VirtualFile file = copyFileToProject(filePath);
983 return configureByFileInner(file);
986 public int configureFromTempProjectFile(final String filePath) throws IOException {
987 return configureByFileInner(findFileInTempDir(filePath));
990 public void configureFromExistingVirtualFile(VirtualFile f) throws IOException {
991 configureByFileInner(f);
994 private int configureByFileInner(final VirtualFile copy) throws IOException {
995 return configureInner(copy, SelectionAndCaretMarkupLoader.fromFile(copy, getProject()));
998 private int configureInner(@NotNull final VirtualFile copy, final SelectionAndCaretMarkupLoader loader) {
1001 final OutputStream outputStream = copy.getOutputStream(null, 0, 0);
1002 outputStream.write(loader.newFileText.getBytes());
1003 outputStream.close();
1005 catch (IOException e) {
1006 throw new RuntimeException(e);
1008 myFile = myPsiManager.findFile(copy);
1009 setContext(myFile, myFileContext);
1010 myEditor = createEditor(copy);
1011 assert myEditor != null : "Editor couldn't be created for file: " + copy.getPath() + ", use copyFileToProject(..) method for this file instead of configureByFile(..)" ;
1013 if (loader.caretMarker != null) {
1014 offset = loader.caretMarker.getStartOffset();
1015 myEditor.getCaretModel().moveToOffset(offset);
1017 if (loader.selStartMarker != null && loader.selEndMarker != null) {
1018 myEditor.getSelectionModel().setSelection(loader.selStartMarker.getStartOffset(), loader.selEndMarker.getStartOffset());
1021 Module module = getModule();
1022 if (module != null) {
1023 for (Facet facet : FacetManager.getInstance(module).getAllFacets()) {
1024 module.getMessageBus().syncPublisher(FacetManager.FACETS_TOPIC).facetConfigurationChanged(facet);
1031 private static void setContext(final PsiFile file, final PsiElement context) {
1032 if (file != null && context != null) {
1033 file.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, new IdentitySmartPointer<PsiElement>(context));
1037 public VirtualFile findFileInTempDir(final String filePath) {
1038 if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
1039 return myTempDirFixture.getFile(filePath);
1041 String fullPath = getTempDirPath() + "/" + filePath;
1043 final VirtualFile copy = LocalFileSystem.getInstance().refreshAndFindFileByPath(fullPath.replace(File.separatorChar, '/'));
1044 assert copy != null : "file " + fullPath + " not found";
1049 private Editor createEditor(VirtualFile file) {
1050 final Project project = getProject();
1051 final FileEditorManager instance = FileEditorManager.getInstance(project);
1052 if (file.getFileType().isBinary()) {
1055 return instance.openTextEditor(new OpenFileDescriptor(project, file, 0), false);
1058 private void collectAndCheckHighlightings(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, Ref<Long> duration)
1060 ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
1062 collectAndCheckHighlightings(data, duration);
1065 private void collectAndCheckHighlightings(final ExpectedHighlightingData data, final Ref<Long> duration) {
1066 final Project project = getProject();
1067 PsiDocumentManager.getInstance(project).commitAllDocuments();
1069 ((PsiFileImpl)myFile).calcTreeElement(); //to load text
1071 //to initialize caches
1072 myPsiManager.getCacheManager().getFilesWithWord(XXX, UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(project), true);
1074 ((PsiManagerImpl)PsiManager.getInstance(project)).setAssertOnFileLoadingFilter(myJavaFilesFilter);
1076 final long start = System.currentTimeMillis();
1077 // ProfilingUtil.startCPUProfiling();
1078 List<HighlightInfo> infos = doHighlighting();
1079 removeDuplicatedRangesForInjected(infos);
1080 final long elapsed = System.currentTimeMillis() - start;
1081 duration.set(duration.isNull()? elapsed : duration.get().longValue() + elapsed);
1082 // ProfilingUtil.captureCPUSnapshot("testing");
1084 ((PsiManagerImpl)PsiManager.getInstance(project)).setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
1086 data.checkResult(infos, myEditor.getDocument().getText());
1089 private static void removeDuplicatedRangesForInjected(List<HighlightInfo> infos) {
1090 Collections.sort(infos, new Comparator<HighlightInfo>() {
1091 public int compare(HighlightInfo o1, HighlightInfo o2) {
1092 final int i = o2.startOffset - o1.startOffset;
1093 return i != 0 ? i : o1.getSeverity().myVal - o2.getSeverity().myVal;
1096 HighlightInfo prevInfo = null;
1097 for (Iterator<HighlightInfo> it = infos.iterator(); it.hasNext();) {
1098 final HighlightInfo info = it.next();
1099 if (prevInfo != null &&
1100 info.getSeverity() == HighlightSeverity.INFORMATION &&
1101 info.description == null &&
1102 info.startOffset == prevInfo.startOffset &&
1103 info.endOffset == prevInfo.endOffset) {
1106 prevInfo = info.getSeverity() == HighlightInfoType.INJECTED_FRAGMENT_SEVERITY ? info : null;
1111 public List<HighlightInfo> doHighlighting() {
1112 final Project project = myProjectFixture.getProject();
1113 PsiDocumentManager.getInstance(project).commitAllDocuments();
1116 ApplicationManager.getApplication().runReadAction(new Computable<List<HighlightInfo>>() {
1117 public List<HighlightInfo> compute() {
1118 return instantiateAndRun(getFile(), getEditor(), ArrayUtil.EMPTY_INT_ARRAY, false);
1124 public static List<HighlightInfo> instantiateAndRun(PsiFile file, Editor editor, int[] toIgnore, boolean allowDirt) {
1125 Project project = file.getProject();
1126 ensureIndexesUpToDate(project);
1127 DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project);
1128 FileStatusMap fileStatusMap = codeAnalyzer.getFileStatusMap();
1129 for (int ignoreId : toIgnore) {
1130 fileStatusMap.markFileUpToDate(editor.getDocument(), file, ignoreId);
1132 fileStatusMap.allowDirt(allowDirt);
1134 TextEditorBackgroundHighlighter highlighter = (TextEditorBackgroundHighlighter)TextEditorProvider.getInstance().getTextEditor(editor).getBackgroundHighlighter();
1135 final List<TextEditorHighlightingPass> passes = highlighter.getPasses(toIgnore);
1136 final ProgressIndicator progress = new DaemonProgressIndicator();
1137 ProgressManager.getInstance().runProcess(new Runnable() {
1139 for (TextEditorHighlightingPass pass : passes) {
1140 pass.collectInformation(progress);
1141 pass.applyInformationToEditor();
1145 List<HighlightInfo> infos = DaemonCodeAnalyzerImpl.getHighlights(editor.getDocument(), project);
1146 return infos == null ? Collections.<HighlightInfo>emptyList() : new ArrayList<HighlightInfo>(infos);
1149 fileStatusMap.allowDirt(true);
1150 codeAnalyzer.clearPasses();
1154 private static void ensureIndexesUpToDate(Project project) {
1155 FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, null);
1156 FileBasedIndex.getInstance().ensureUpToDate(TodoIndex.NAME, project, null);
1157 assertTrue(!DumbServiceImpl.getInstance(project).isDumb());
1160 public String getTestDataPath() {
1161 return myTestDataPath;
1164 public Project getProject() {
1165 return myProjectFixture.getProject();
1168 public Module getModule() {
1169 return myProjectFixture.getModule();
1172 public Editor getEditor() {
1176 public PsiFile getFile() {
1180 public static List<IntentionAction> getAvailableIntentions(final Editor editor, final PsiFile file) {
1181 return ApplicationManager.getApplication().runReadAction(new Computable<List<IntentionAction>>() {
1182 public List<IntentionAction> compute() {
1183 return doGetAvailableIntentions(editor, file);
1188 private static List<IntentionAction> doGetAvailableIntentions(Editor editor, PsiFile file) {
1189 ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo();
1190 ShowIntentionsPass.getActionsToShow(editor, file, intentions, -1);
1191 List<HighlightInfo.IntentionActionDescriptor> descriptors = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
1192 descriptors.addAll(intentions.intentionsToShow);
1193 descriptors.addAll(intentions.errorFixesToShow);
1194 descriptors.addAll(intentions.inspectionFixesToShow);
1195 descriptors.addAll(intentions.guttersToShow);
1197 PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
1198 List<IntentionAction> result = new ArrayList<IntentionAction>();
1200 List<HighlightInfo> infos = DaemonCodeAnalyzerImpl.getFileLevelHighlights(file.getProject(), file);
1201 for (HighlightInfo info : infos) {
1202 for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
1203 HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first;
1204 if (actionInGroup.getAction().isAvailable(file.getProject(), editor, file)) {
1205 descriptors.add(actionInGroup);
1210 // add all intention options for simplicity
1211 for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) {
1212 result.add(descriptor.getAction());
1213 List<IntentionAction> options = descriptor.getOptions(element);
1214 if (options != null) {
1215 for (IntentionAction option : options) {
1216 if (option.isAvailable(file.getProject(), editor, file)) {
1225 public void allowTreeAccessForFile(final VirtualFile file) {
1226 myJavaFilesFilter.allowTreeAccessForFile(file);
1229 public void allowTreeAccessForAllFiles() {
1230 myJavaFilesFilter.allowTreeAccessForAllFiles();
1233 static class SelectionAndCaretMarkupLoader {
1234 final String newFileText;
1235 final RangeMarker caretMarker;
1236 final RangeMarker selStartMarker;
1237 final RangeMarker selEndMarker;
1239 static SelectionAndCaretMarkupLoader fromFile(String path, Project project) throws IOException {
1240 return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(new String(FileUtil.loadFileText(new File(path)))), project);
1242 static SelectionAndCaretMarkupLoader fromFile(VirtualFile file, Project project) throws IOException {
1243 return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(VfsUtil.loadText(file)), project);
1246 static SelectionAndCaretMarkupLoader fromText(String text, Project project) {
1247 return new SelectionAndCaretMarkupLoader(text, project);
1250 private SelectionAndCaretMarkupLoader(String fileText, Project project) {
1251 final Document document = EditorFactory.getInstance().createDocument(fileText);
1253 int caretIndex = fileText.indexOf(CARET_MARKER);
1254 int selStartIndex = fileText.indexOf(SELECTION_START_MARKER);
1255 int selEndIndex = fileText.indexOf(SELECTION_END_MARKER);
1257 caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
1258 selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
1259 selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
1261 new WriteCommandAction(project) {
1262 protected void run(Result result) throws Exception {
1263 if (caretMarker != null) {
1264 document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
1266 if (selStartMarker != null) {
1267 document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
1269 if (selEndMarker != null) {
1270 document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
1275 newFileText = document.getText();
1279 private void checkResultByFile(@NonNls String expectedFile,
1280 @NotNull PsiFile originalFile,
1281 boolean stripTrailingSpaces) throws IOException {
1282 if (!stripTrailingSpaces) {
1283 EditorUtil.fillVirtualSpaceUntilCaret(myEditor);
1285 PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
1286 checkResult(expectedFile, stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromFile(getTestDataPath() + "/" + expectedFile, getProject()), originalFile.getText());
1289 private void checkResult(final String expectedFile,
1290 final boolean stripTrailingSpaces,
1291 final SelectionAndCaretMarkupLoader loader,
1292 String actualText) {
1293 assertInitialized();
1294 Project project = myProjectFixture.getProject();
1296 project.getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
1297 if (stripTrailingSpaces) {
1298 actualText = stripTrailingSpaces(actualText);
1301 PsiDocumentManager.getInstance(project).commitAllDocuments();
1303 String newFileText1 = loader.newFileText;
1304 if (stripTrailingSpaces) {
1305 newFileText1 = stripTrailingSpaces(newFileText1);
1308 actualText = StringUtil.convertLineSeparators(actualText);
1310 //noinspection HardCodedStringLiteral
1311 Assert.assertEquals("Text mismatch in file " + expectedFile, newFileText1, actualText);
1313 if (loader.caretMarker != null) {
1314 int caretLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.caretMarker.getStartOffset());
1315 int caretCol = loader.caretMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, caretLine, 0);
1317 Assert.assertEquals("caretLine", caretLine + 1, myEditor.getCaretModel().getLogicalPosition().line + 1);
1318 Assert.assertEquals("caretColumn", caretCol + 1, myEditor.getCaretModel().getLogicalPosition().column + 1);
1321 if (loader.selStartMarker != null && loader.selEndMarker != null) {
1322 int selStartLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selStartMarker.getStartOffset());
1323 int selStartCol = loader.selStartMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0);
1325 int selEndLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selEndMarker.getEndOffset());
1326 int selEndCol = loader.selEndMarker.getEndOffset() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0);
1328 Assert.assertEquals("selectionStartLine", selStartLine + 1,
1329 StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionStart()) + 1);
1331 Assert.assertEquals("selectionStartCol", selStartCol + 1, myEditor.getSelectionModel().getSelectionStart() -
1332 StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0) + 1);
1334 Assert.assertEquals("selectionEndLine", selEndLine + 1,
1335 StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionEnd()) + 1);
1337 Assert.assertEquals("selectionEndCol", selEndCol + 1,
1338 myEditor.getSelectionModel().getSelectionEnd() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0) +
1341 else if (myEditor != null) {
1342 Assert.assertTrue("has no selection", !myEditor.getSelectionModel().hasSelection());
1346 private static String stripTrailingSpaces(String actualText) {
1347 final Document document = EditorFactory.getInstance().createDocument(actualText);
1348 ((DocumentEx)document).stripTrailingSpaces(false);
1349 actualText = document.getText();