2 * Copyright 2000-2017 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.
16 package com.intellij.testFramework.fixtures;
18 import com.intellij.codeInsight.completion.CompletionType;
19 import com.intellij.codeInsight.daemon.GutterMark;
20 import com.intellij.codeInsight.daemon.impl.HighlightInfo;
21 import com.intellij.codeInsight.intention.IntentionAction;
22 import com.intellij.codeInsight.lookup.Lookup;
23 import com.intellij.codeInsight.lookup.LookupElement;
24 import com.intellij.codeInsight.lookup.LookupEx;
25 import com.intellij.codeInspection.InspectionProfileEntry;
26 import com.intellij.codeInspection.InspectionToolProvider;
27 import com.intellij.codeInspection.LocalInspectionTool;
28 import com.intellij.codeInspection.ex.InspectionToolWrapper;
29 import com.intellij.ide.structureView.newStructureView.StructureViewComponent;
30 import com.intellij.lang.annotation.HighlightSeverity;
31 import com.intellij.openapi.Disposable;
32 import com.intellij.openapi.actionSystem.AnAction;
33 import com.intellij.openapi.actionSystem.Presentation;
34 import com.intellij.openapi.editor.Document;
35 import com.intellij.openapi.editor.Editor;
36 import com.intellij.openapi.editor.markup.RangeHighlighter;
37 import com.intellij.openapi.fileTypes.FileType;
38 import com.intellij.openapi.vfs.VirtualFile;
39 import com.intellij.psi.PsiElement;
40 import com.intellij.psi.PsiFile;
41 import com.intellij.psi.PsiManager;
42 import com.intellij.psi.PsiReference;
43 import com.intellij.testFramework.EditorTestUtil;
44 import com.intellij.testFramework.ExpectedHighlightingData;
45 import com.intellij.testFramework.HighlightTestInfo;
46 import com.intellij.testFramework.TestDataFile;
47 import com.intellij.ui.components.breadcrumbs.Crumb;
48 import com.intellij.usageView.UsageInfo;
49 import com.intellij.util.Consumer;
50 import org.intellij.lang.annotations.MagicConstant;
51 import org.jetbrains.annotations.NotNull;
52 import org.jetbrains.annotations.Nullable;
54 import java.util.Collection;
55 import java.util.List;
58 * @author Dmitry Avdeev
59 * @link http://www.jetbrains.org/intellij/sdk/docs/basics/testing_plugins.html
60 * @see IdeaTestFixtureFactory#createCodeInsightFixture(IdeaProjectTestFixture)
62 public interface CodeInsightTestFixture extends IdeaProjectTestFixture {
63 String CARET_MARKER = EditorTestUtil.CARET_TAG;
64 String ERROR_MARKER = "error";
65 String WARNING_MARKER = "warning";
66 String WEAK_WARNING_MARKER = "weak_warning";
67 String INFO_MARKER = "info";
68 String END_LINE_HIGHLIGHT_MARKER = "EOLError";
69 String END_LINE_WARNING_MARKER = "EOLWarning";
72 * Returns the in-memory editor instance.
74 * @return the in-memory editor instance.
79 * Returns the offset of the caret in the in-memory editor instance.
81 * @return the offset of the caret in the in-memory editor instance.
86 * Returns the file currently loaded into the in-memory editor.
88 * @return the file currently loaded into the in-memory editor.
92 void setTestDataPath(@NotNull String dataPath);
95 String getTestDataPath();
98 String getTempDirPath();
101 TempDirTestFixture getTempDirFixture();
104 * Copies a file from the testdata directory to the same relative path in the test project directory.
106 * @return the VirtualFile for the copied file in the test project directory.
109 VirtualFile copyFileToProject(@TestDataFile @NotNull String sourceFilePath);
112 * Copies a file from the testdata directory to the specified path in the test project directory.
114 * @param sourceFilePath path to the source file, relative to the testdata path.
115 * @param targetPath path to the destination, relative to the source root of the test project.
116 * @return the VirtualFile for the copied file in the test project directory.
119 VirtualFile copyFileToProject(@TestDataFile @NotNull String sourceFilePath, @NotNull String targetPath);
122 * Copies a directory from the testdata directory to the specified path in the test project directory.
124 * @param sourceFilePath path to the source directory, relative to the testdata path.
125 * @param targetPath path to the destination, relative to the source root of the test project.
126 * @return the VirtualFile for the copied directory in the test project directory.
129 VirtualFile copyDirectoryToProject(@TestDataFile @NotNull String sourceFilePath, @NotNull String targetPath);
132 * Copies a file from the testdata directory to the same relative path in the test project directory
133 * and opens it in the in-memory editor.
135 * @param filePath path to the file, relative to the testdata path.
136 * @return the PSI file for the copied and opened file.
138 PsiFile configureByFile(@TestDataFile @NotNull String filePath);
141 * Copies multiple files from the testdata directory to the same relative paths in the test project directory
142 * and opens the first of them in the in-memory editor.
144 * @param filePaths path to the files, relative to the testdata path.
145 * @return the PSI files for the copied files.
148 PsiFile[] configureByFiles(@TestDataFile @NotNull String... filePaths);
151 * Loads the specified text, treated as the contents of a file with the specified file type, into the in-memory
154 * @param fileType the file type according to which which the text is interpreted.
155 * @param text the text to load into the in-memory editor.
156 * @return the PSI file created from the specified text.
158 PsiFile configureByText(@NotNull FileType fileType, @NotNull String text);
161 * Loads the specified text, treated as the contents of a file with the specified name, into the in-memory
164 * @param fileName the name of the file (which is used to determine the file type based on the registered filename patterns).
165 * @param text the text to load into the in-memory editor.
166 * @return the PSI file created from the specified text.
168 PsiFile configureByText(@NotNull String fileName, @NotNull String text);
171 * Loads the specified file from the test project directory into the in-memory editor.
173 * @param filePath the path of the file to load, relative to the test project source root.
174 * @return the PSI file for the loaded file.
176 PsiFile configureFromTempProjectFile(@NotNull String filePath);
179 * Loads the specified virtual file from the test project directory into the in-memory editor.
181 * @param virtualFile the file to load.
183 void configureFromExistingVirtualFile(@NotNull VirtualFile virtualFile);
186 * Creates a file with the specified path and contents in the test project directory.
188 * @param relativePath the path for the file to create, relative to the test project source root.
189 * @param fileText the text to put into the created file.
190 * @return the PSI file for the created file.
192 PsiFile addFileToProject(@NotNull String relativePath, @NotNull String fileText);
195 * Compares the contents of the in-memory editor with the specified file. The trailing whitespaces are not ignored
198 * @param expectedFile path to file to check against, relative to the testdata path.
200 void checkResultByFile(@TestDataFile @NotNull String expectedFile);
203 * Compares the contents of the in-memory editor with the specified file, optionally ignoring trailing whitespaces.
205 * @param expectedFile path to file to check against, relative to the testdata path.
206 * @param ignoreTrailingWhitespaces whether trailing whitespaces should be ignored by the comparison.
208 void checkResultByFile(@TestDataFile @NotNull String expectedFile, boolean ignoreTrailingWhitespaces);
211 * Compares a file in the test project with a file in the testdata directory.
213 * @param filePath path to file to be checked, relative to the source root of the test project.
214 * @param expectedFile path to file to check against, relative to the testdata path.
215 * @param ignoreTrailingWhitespaces whether trailing whitespaces should be ignored by the comparison.
217 void checkResultByFile(@NotNull String filePath,
218 @TestDataFile @NotNull String expectedFile,
219 boolean ignoreTrailingWhitespaces);
222 * Enables inspections for highlighting tests.
223 * Should be called BEFORE {@link #setUp()}. And do not forget to call {@link #tearDown()}
225 * @param inspections inspections to be enabled in highlighting tests.
226 * @see #enableInspections(InspectionToolProvider...)
228 void enableInspections(@NotNull InspectionProfileEntry... inspections);
230 void enableInspections(@NotNull Class<? extends LocalInspectionTool>... inspections);
232 void enableInspections(@NotNull Collection<Class<? extends LocalInspectionTool>> inspections);
234 void disableInspections(@NotNull InspectionProfileEntry... inspections);
237 * Enable all inspections provided by given providers.
239 * @param providers providers to be enabled.
240 * @see #enableInspections(Class[])
242 void enableInspections(@NotNull InspectionToolProvider... providers);
245 * Runs highlighting test for the given files.
246 * Checks for {@link #ERROR_MARKER} markers by default.
248 * Double quotes in "descr" attribute of markers must be escaped by either one or two backslashes
249 * (see {@link ExpectedHighlightingData#extractExpectedHighlightsSet(Document)}).
251 * @param checkWarnings enables {@link #WARNING_MARKER} support.
252 * @param checkInfos enables {@link #INFO_MARKER} support.
253 * @param checkWeakWarnings enables {@link #WEAK_WARNING_MARKER} support.
254 * @param filePaths the first file is tested only; the others are just copied along the first.
255 * @return highlighting duration in milliseconds.
257 long testHighlighting(boolean checkWarnings,
259 boolean checkWeakWarnings,
260 @TestDataFile @NotNull String... filePaths);
262 long testHighlightingAllFiles(boolean checkWarnings,
264 boolean checkWeakWarnings,
265 @TestDataFile @NotNull String... filePaths);
267 long testHighlightingAllFiles(boolean checkWarnings,
269 boolean checkWeakWarnings,
270 @TestDataFile @NotNull VirtualFile... files);
273 * Check highlighting of file already loaded by configure* methods
277 long checkHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings);
279 long checkHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, boolean ignoreExtraHighlighting);
281 long checkHighlighting();
284 * Runs highlighting test for the given files.
285 * The same as {@link #testHighlighting(boolean, boolean, boolean, String...)} with {@code checkInfos=false}.
287 * @param filePaths the first file is tested only; the others are just copied along with the first.
288 * @return highlighting duration in milliseconds
290 long testHighlighting(@TestDataFile @NotNull String... filePaths);
292 long testHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, @NotNull VirtualFile file);
295 HighlightTestInfo testFile(@NotNull String... filePath);
297 void openFileInEditor(@NotNull VirtualFile file);
299 void testInspection(@NotNull String testDir, @NotNull InspectionToolWrapper toolWrapper);
302 * @return all highlight infos for current file
305 List<HighlightInfo> doHighlighting();
308 List<HighlightInfo> doHighlighting(@NotNull HighlightSeverity minimalSeverity);
311 * Finds the reference in position marked by {@link #CARET_MARKER}.
313 * @return null if no reference found.
314 * @see #getReferenceAtCaretPositionWithAssertion(String...)
317 PsiReference getReferenceAtCaretPosition(@TestDataFile @NotNull String... filePaths);
320 * Finds the reference in position marked by {@link #CARET_MARKER}.
321 * Asserts that the reference exists.
323 * @return founded reference
324 * @see #getReferenceAtCaretPosition(String...)
327 PsiReference getReferenceAtCaretPositionWithAssertion(@TestDataFile @NotNull String... filePaths);
330 * Collects available intentions at caret position.
332 * @param filePaths the first file is tested only; the others are just copied along with the first.
333 * @return available intentions.
337 List<IntentionAction> getAvailableIntentions(@TestDataFile @NotNull String... filePaths);
340 List<IntentionAction> getAllQuickFixes(@TestDataFile @NotNull String... filePaths);
343 List<IntentionAction> getAvailableIntentions();
346 * Returns all intentions or quick fixes which are available at the current caret position and whose text starts with the specified hint text.
348 * @param hint the text that the intention text should begin with.
349 * @return the list of matching intentions
352 List<IntentionAction> filterAvailableIntentions(@NotNull String hint);
355 * Returns a single intention or quickfix which is available at the current caret position and whose text starts with the specified
356 * hint text. Throws an assertion if no such intentions are found or if multiple intentions match the hint text.
358 * @param hint the text that the intention text should begin with.
359 * @return the matching intention
360 * @throws AssertionError if no intentions are found or if multiple intentions match the hint text.
363 IntentionAction findSingleIntention(@NotNull String hint);
366 * Copies multiple files from the testdata directory to the same relative paths in the test project directory, opens the first of them
367 * in the in-memory editor and returns an intention action or quickfix with the name exactly matching the specified text.
369 * @param intentionName the text that the intention text should be equal to.
370 * @param filePaths the list of file path to copy to the test project directory.
371 * @return the first found intention or quickfix, or null if no matching intention actions are found.
374 IntentionAction getAvailableIntention(@NotNull String intentionName, @TestDataFile @NotNull String... filePaths);
377 * Launches the given action. Use {@link #checkResultByFile(String)} to check the result.
379 * @param action the action to be launched.
381 void launchAction(@NotNull IntentionAction action);
383 void testCompletion(@NotNull String[] filesBefore, @TestDataFile @NotNull String fileAfter);
385 void testCompletionTyping(@NotNull String[] filesBefore, @NotNull String toType, @NotNull @TestDataFile String fileAfter);
388 * Runs basic completion in caret position in fileBefore.
389 * Implies that there is only one completion variant and it was inserted automatically, and checks the result file text with fileAfter
391 void testCompletion(@TestDataFile @NotNull String fileBefore,
392 @NotNull @TestDataFile String fileAfter,
393 @TestDataFile @NotNull String... additionalFiles);
395 void testCompletionTyping(@NotNull @TestDataFile String fileBefore,
396 @NotNull String toType,
397 @NotNull @TestDataFile String fileAfter,
398 @TestDataFile @NotNull String... additionalFiles);
401 * Runs basic completion in caret position in fileBefore.
402 * Checks that lookup is shown and it contains items with given lookup strings
404 * @param items most probably will contain > 1 items
406 void testCompletionVariants(@NotNull @TestDataFile String fileBefore, @NotNull String... items);
409 * Launches renaming refactoring and checks the result.
411 * @param fileBefore original file path. Use {@link #CARET_MARKER} to mark the element to rename.
412 * @param fileAfter result file to be checked against.
413 * @param newName new name for the element.
414 * @see #testRename(String, String)
416 void testRename(@NotNull @TestDataFile String fileBefore,
417 @NotNull @TestDataFile String fileAfter,
418 @NotNull String newName,
419 @TestDataFile @NotNull String... additionalFiles);
421 void testRename(@NotNull @TestDataFile String fileAfter, @NotNull String newName);
424 Collection<UsageInfo> testFindUsages(@TestDataFile @NotNull String... fileNames);
427 Collection<UsageInfo> findUsages(@NotNull PsiElement to);
430 RangeHighlighter[] testHighlightUsages(@NotNull @TestDataFile String... files);
432 void moveFile(@NotNull @TestDataFile String filePath, @NotNull String to, @TestDataFile @NotNull String... additionalFiles);
435 * Returns gutter renderer at the caret position.
436 * Use {@link #CARET_MARKER} to mark the element to check.
438 * @param filePath file path
439 * @return gutter renderer at the caret position.
442 GutterMark findGutter(@NotNull @TestDataFile String filePath);
445 List<GutterMark> findGuttersAtCaret();
448 PsiManager getPsiManager();
451 * @return null if the only item was auto-completed
452 * @see #completeBasicAllCarets(Character)
454 LookupElement[] completeBasic();
457 * @return null if the only item was auto-completed
459 LookupElement[] complete(@NotNull CompletionType type);
462 * @return null if the only item was auto-completed
464 LookupElement[] complete(@NotNull CompletionType type, int invocationCount);
466 void checkResult(@NotNull String text);
468 void checkResult(@NotNull String text, boolean stripTrailingSpaces);
470 void checkResult(@NotNull String filePath, @NotNull String text, boolean stripTrailingSpaces);
472 Document getDocument(@NotNull PsiFile file);
475 List<GutterMark> findAllGutters(@NotNull @TestDataFile String filePath);
477 List<GutterMark> findAllGutters();
479 void type(final char c);
481 void type(@NotNull String s);
483 void performEditorAction(@NotNull String actionId);
486 * If the action is visible and enabled, perform it
488 * @return updated action's presentation
491 Presentation testAction(@NotNull AnAction action);
494 List<String> getCompletionVariants(@NotNull @TestDataFile String... filesBefore);
497 * @return null if the only item was auto-completed
500 LookupElement[] getLookupElements();
502 VirtualFile findFileInTempDir(@NotNull String filePath);
505 List<String> getLookupElementStrings();
507 void finishLookup(@MagicConstant(valuesFromClass = Lookup.class) char completionChar);
509 LookupEx getLookup();
512 PsiElement getElementAtCaret();
514 void renameElementAtCaret(@NotNull String newName);
517 * Renames element at caret using injected {@link com.intellij.refactoring.rename.RenameHandler}s.
518 * Very close to {@link #renameElementAtCaret(String)} but uses handlers.
520 * @param newName new name for the element.
522 void renameElementAtCaretUsingHandler(@NotNull String newName);
524 void renameElement(@NotNull PsiElement element, @NotNull String newName);
526 void allowTreeAccessForFile(@NotNull VirtualFile file);
528 void allowTreeAccessForAllFiles();
530 void renameElement(@NotNull PsiElement element,
531 @NotNull String newName,
532 boolean searchInComments,
533 boolean searchTextOccurrences);
535 <T extends PsiElement> T findElementByText(@NotNull String text, @NotNull Class<T> elementClass);
537 void testFolding(@NotNull String fileName);
539 void testFoldingWithCollapseStatus(@NotNull final String verificationFileName, @Nullable String destinationFileName);
541 void testFoldingWithCollapseStatus(@NotNull String fileName);
543 void testRainbow(@NotNull String fileName, @NotNull String text, boolean isRainbowOn, boolean withColor);
547 void checkResultWithInlays(String text);
549 void assertPreferredCompletionItems(int selected, @NotNull String... expected);
552 * Initializes the structure view for the file currently loaded in the editor and passes it to the specified consumer.
554 * @param consumer the callback in which the actual testing of the structure view is performed.
556 void testStructureView(@NotNull Consumer<StructureViewComponent> consumer);
559 * By default, if the caret in the text passed to {@link #configureByFile(String)} or {@link #configureByText} has an injected fragment
560 * at the caret, the test fixture puts the caret into the injected editor. This method allows to turn off this behavior.
562 * @param caresAboutInjection true if the fixture should look for an injection at caret, false otherwise.
564 void setCaresAboutInjection(boolean caresAboutInjection);
567 * Completes basically (see {@link #completeBasic()}) <strong>all</strong>
568 * carets (places marked with {@link #CARET_MARKER} in file. Example:
570 * PyC<caret> is IDE for Py<caret>
572 * should be completed to
574 * PyCharm is IDE for Python
576 * Actually, it works just like {@link #completeBasic()} but supports
577 * several {@link #CARET_MARKER}
579 * @param charToTypeAfterCompletion after completion this char will be typed if argument is not null.
580 * It could be used to complete suggestion with "\t" for example.
581 * @return list of all completion elements just like in {@link #completeBasic()}
582 * @see #completeBasic()
585 List<LookupElement> completeBasicAllCarets(@Nullable Character charToTypeAfterCompletion);
588 * Get elements found by the Goto Class action called with the given pattern
589 * @param pattern a pattern to search for elements
590 * @param searchEverywhere indicates whether "include non-project classes" checkbox is selected
591 * @param contextForSorting a PsiElement used for "proximity sorting" of the results. The sorting will be disabled if null given.
592 * @return a list of the results (likely PsiElements) found for the given pattern
595 List<Object> getGotoClassResults(@NotNull String pattern, boolean searchEverywhere, @Nullable PsiElement contextForSorting);
598 * Get breadcrumbs to be generated for the current cursor position in the loaded file
599 * @return a list of the breadcrumbs in the order from the topmost element crumb to the deepest
602 List<Crumb> getBreadcrumbsAtCaret();
604 void saveText(@NotNull VirtualFile file, @NotNull String text);
607 default Disposable getProjectDisposable() {