Merge branch 'ypankratyev/goto_testdata_fixes'
[idea/community.git] / platform / testFramework / src / com / intellij / testFramework / fixtures / CodeInsightTestFixture.java
1 /*
2  * Copyright 2000-2017 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.testFramework.fixtures;
17
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;
53
54 import java.util.Collection;
55 import java.util.List;
56
57 /**
58  * @author Dmitry Avdeev
59  * @link http://www.jetbrains.org/intellij/sdk/docs/basics/testing_plugins.html
60  * @see IdeaTestFixtureFactory#createCodeInsightFixture(IdeaProjectTestFixture)
61  */
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";
70
71   /**
72    * Returns the in-memory editor instance.
73    *
74    * @return the in-memory editor instance.
75    */
76   Editor getEditor();
77
78   /**
79    * Returns the offset of the caret in the in-memory editor instance.
80    *
81    * @return the offset of the caret in the in-memory editor instance.
82    */
83   int getCaretOffset();
84
85   /**
86    * Returns the file currently loaded into the in-memory editor.
87    *
88    * @return the file currently loaded into the in-memory editor.
89    */
90   PsiFile getFile();
91
92   void setTestDataPath(@NotNull String dataPath);
93
94   @NotNull
95   String getTestDataPath();
96
97   @NotNull
98   String getTempDirPath();
99
100   @NotNull
101   TempDirTestFixture getTempDirFixture();
102
103   /**
104    * Copies a file from the testdata directory to the same relative path in the test project directory.
105    *
106    * @return the VirtualFile for the copied file in the test project directory.
107    */
108   @NotNull
109   VirtualFile copyFileToProject(@TestDataFile @NotNull String sourceFilePath);
110
111   /**
112    * Copies a file from the testdata directory to the specified path in the test project directory.
113    *
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.
117    */
118   @NotNull
119   VirtualFile copyFileToProject(@TestDataFile @NotNull String sourceFilePath, @NotNull String targetPath);
120
121   /**
122    * Copies a directory from the testdata directory to the specified path in the test project directory.
123    *
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.
127    */
128   @NotNull
129   VirtualFile copyDirectoryToProject(@TestDataFile @NotNull String sourceFilePath, @NotNull String targetPath);
130
131   /**
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.
134    *
135    * @param filePath path to the file, relative to the testdata path.
136    * @return the PSI file for the copied and opened file.
137    */
138   PsiFile configureByFile(@TestDataFile @NotNull String filePath);
139
140   /**
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.
143    *
144    * @param filePaths path to the files, relative to the testdata path.
145    * @return the PSI files for the copied files.
146    */
147   @NotNull
148   PsiFile[] configureByFiles(@TestDataFile @NotNull String... filePaths);
149
150   /**
151    * Loads the specified text, treated as the contents of a file with the specified file type, into the in-memory
152    * editor.
153    *
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.
157    */
158   PsiFile configureByText(@NotNull FileType fileType, @NotNull String text);
159
160   /**
161    * Loads the specified text, treated as the contents of a file with the specified name, into the in-memory
162    * editor.
163    *
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.
167    */
168   PsiFile configureByText(@NotNull String fileName, @NotNull String text);
169
170   /**
171    * Loads the specified file from the test project directory into the in-memory editor.
172    *
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.
175    */
176   PsiFile configureFromTempProjectFile(@NotNull String filePath);
177
178   /**
179    * Loads the specified virtual file from the test project directory into the in-memory editor.
180    *
181    * @param virtualFile the file to load.
182    */
183   void configureFromExistingVirtualFile(@NotNull VirtualFile virtualFile);
184
185   /**
186    * Creates a file with the specified path and contents in the test project directory.
187    *
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.
191    */
192   PsiFile addFileToProject(@NotNull String relativePath, @NotNull String fileText);
193
194   /**
195    * Compares the contents of the in-memory editor with the specified file. The trailing whitespaces are not ignored
196    * by the comparison.
197    *
198    * @param expectedFile path to file to check against, relative to the testdata path.
199    */
200   void checkResultByFile(@TestDataFile @NotNull String expectedFile);
201
202   /**
203    * Compares the contents of the in-memory editor with the specified file, optionally ignoring trailing whitespaces.
204    *
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.
207    */
208   void checkResultByFile(@TestDataFile @NotNull String expectedFile, boolean ignoreTrailingWhitespaces);
209
210   /**
211    * Compares a file in the test project with a file in the testdata directory.
212    *
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.
216    */
217   void checkResultByFile(@NotNull String filePath,
218                          @TestDataFile @NotNull String expectedFile,
219                          boolean ignoreTrailingWhitespaces);
220
221   /**
222    * Enables inspections for highlighting tests.
223    * Should be called BEFORE {@link #setUp()}. And do not forget to call {@link #tearDown()}
224    *
225    * @param inspections inspections to be enabled in highlighting tests.
226    * @see #enableInspections(InspectionToolProvider...)
227    */
228   void enableInspections(@NotNull InspectionProfileEntry... inspections);
229
230   void enableInspections(@NotNull Class<? extends LocalInspectionTool>... inspections);
231
232   void enableInspections(@NotNull Collection<Class<? extends LocalInspectionTool>> inspections);
233
234   void disableInspections(@NotNull InspectionProfileEntry... inspections);
235
236   /**
237    * Enable all inspections provided by given providers.
238    *
239    * @param providers providers to be enabled.
240    * @see #enableInspections(Class[])
241    */
242   void enableInspections(@NotNull InspectionToolProvider... providers);
243
244   /**
245    * Runs highlighting test for the given files.
246    * Checks for {@link #ERROR_MARKER} markers by default.
247    * <p/>
248    * Double quotes in "descr" attribute of markers must be escaped by either one or two backslashes
249    * (see {@link ExpectedHighlightingData#extractExpectedHighlightsSet(Document)}).
250    *
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.
256    */
257   long testHighlighting(boolean checkWarnings,
258                         boolean checkInfos,
259                         boolean checkWeakWarnings,
260                         @TestDataFile @NotNull String... filePaths);
261
262   long testHighlightingAllFiles(boolean checkWarnings,
263                                 boolean checkInfos,
264                                 boolean checkWeakWarnings,
265                                 @TestDataFile @NotNull String... filePaths);
266
267   long testHighlightingAllFiles(boolean checkWarnings,
268                                 boolean checkInfos,
269                                 boolean checkWeakWarnings,
270                                 @TestDataFile @NotNull VirtualFile... files);
271
272   /**
273    * Check highlighting of file already loaded by configure* methods
274    *
275    * @return duration
276    */
277   long checkHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings);
278
279   long checkHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, boolean ignoreExtraHighlighting);
280
281   long checkHighlighting();
282
283   /**
284    * Runs highlighting test for the given files.
285    * The same as {@link #testHighlighting(boolean, boolean, boolean, String...)} with {@code checkInfos=false}.
286    *
287    * @param filePaths the first file is tested only; the others are just copied along with the first.
288    * @return highlighting duration in milliseconds
289    */
290   long testHighlighting(@TestDataFile @NotNull String... filePaths);
291
292   long testHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, @NotNull VirtualFile file);
293
294   @NotNull
295   HighlightTestInfo testFile(@NotNull String... filePath);
296
297   void openFileInEditor(@NotNull VirtualFile file);
298
299   void testInspection(@NotNull String testDir, @NotNull InspectionToolWrapper toolWrapper);
300
301   /**
302    * @return all highlight infos for current file
303    */
304   @NotNull
305   List<HighlightInfo> doHighlighting();
306
307   @NotNull
308   List<HighlightInfo> doHighlighting(@NotNull HighlightSeverity minimalSeverity);
309
310   /**
311    * Finds the reference in position marked by {@link #CARET_MARKER}.
312    *
313    * @return null if no reference found.
314    * @see #getReferenceAtCaretPositionWithAssertion(String...)
315    */
316   @Nullable
317   PsiReference getReferenceAtCaretPosition(@TestDataFile @NotNull String... filePaths);
318
319   /**
320    * Finds the reference in position marked by {@link #CARET_MARKER}.
321    * Asserts that the reference exists.
322    *
323    * @return founded reference
324    * @see #getReferenceAtCaretPosition(String...)
325    */
326   @NotNull
327   PsiReference getReferenceAtCaretPositionWithAssertion(@TestDataFile @NotNull String... filePaths);
328
329   /**
330    * Collects available intentions at caret position.
331    *
332    * @param filePaths the first file is tested only; the others are just copied along with the first.
333    * @return available intentions.
334    * @see #CARET_MARKER
335    */
336   @NotNull
337   List<IntentionAction> getAvailableIntentions(@TestDataFile @NotNull String... filePaths);
338
339   @NotNull
340   List<IntentionAction> getAllQuickFixes(@TestDataFile @NotNull String... filePaths);
341
342   @NotNull
343   List<IntentionAction> getAvailableIntentions();
344
345   /**
346    * Returns all intentions or quick fixes which are available at the current caret position and whose text starts with the specified hint text.
347    *
348    * @param hint the text that the intention text should begin with.
349    * @return the list of matching intentions
350    */
351   @NotNull
352   List<IntentionAction> filterAvailableIntentions(@NotNull String hint);
353
354   /**
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.
357    *
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.
361    */
362   @NotNull
363   IntentionAction findSingleIntention(@NotNull String hint);
364
365   /**
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.
368    *
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.
372    */
373   @Nullable
374   IntentionAction getAvailableIntention(@NotNull String intentionName, @TestDataFile @NotNull String... filePaths);
375
376   /**
377    * Launches the given action. Use {@link #checkResultByFile(String)} to check the result.
378    *
379    * @param action the action to be launched.
380    */
381   void launchAction(@NotNull IntentionAction action);
382
383   void testCompletion(@NotNull String[] filesBefore, @TestDataFile @NotNull String fileAfter);
384
385   void testCompletionTyping(@NotNull String[] filesBefore, @NotNull String toType, @NotNull @TestDataFile String fileAfter);
386
387   /**
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
390    */
391   void testCompletion(@TestDataFile @NotNull String fileBefore,
392                       @NotNull @TestDataFile String fileAfter,
393                       @TestDataFile @NotNull String... additionalFiles);
394
395   void testCompletionTyping(@NotNull @TestDataFile String fileBefore,
396                             @NotNull String toType,
397                             @NotNull @TestDataFile String fileAfter,
398                             @TestDataFile @NotNull String... additionalFiles);
399
400   /**
401    * Runs basic completion in caret position in fileBefore.
402    * Checks that lookup is shown and it contains items with given lookup strings
403    *
404    * @param items most probably will contain > 1 items
405    */
406   void testCompletionVariants(@NotNull @TestDataFile String fileBefore, @NotNull String... items);
407
408   /**
409    * Launches renaming refactoring and checks the result.
410    *
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)
415    */
416   void testRename(@NotNull @TestDataFile String fileBefore,
417                   @NotNull @TestDataFile String fileAfter,
418                   @NotNull String newName,
419                   @TestDataFile @NotNull String... additionalFiles);
420
421   void testRename(@NotNull @TestDataFile String fileAfter, @NotNull String newName);
422
423   @NotNull
424   Collection<UsageInfo> testFindUsages(@TestDataFile @NotNull String... fileNames);
425
426   @NotNull
427   Collection<UsageInfo> findUsages(@NotNull PsiElement to);
428
429   @NotNull
430   RangeHighlighter[] testHighlightUsages(@NotNull @TestDataFile String... files);
431
432   void moveFile(@NotNull @TestDataFile String filePath, @NotNull String to, @TestDataFile @NotNull String... additionalFiles);
433
434   /**
435    * Returns gutter renderer at the caret position.
436    * Use {@link #CARET_MARKER} to mark the element to check.
437    *
438    * @param filePath file path
439    * @return gutter renderer at the caret position.
440    */
441   @Nullable
442   GutterMark findGutter(@NotNull @TestDataFile String filePath);
443
444   @NotNull
445   List<GutterMark> findGuttersAtCaret();
446
447   @NotNull
448   PsiManager getPsiManager();
449
450   /**
451    * @return null if the only item was auto-completed
452    * @see #completeBasicAllCarets(Character)
453    */
454   LookupElement[] completeBasic();
455
456   /**
457    * @return null if the only item was auto-completed
458    */
459   LookupElement[] complete(@NotNull CompletionType type);
460
461   /**
462    * @return null if the only item was auto-completed
463    */
464   LookupElement[] complete(@NotNull CompletionType type, int invocationCount);
465
466   void checkResult(@NotNull String text);
467
468   void checkResult(@NotNull String text, boolean stripTrailingSpaces);
469
470   void checkResult(@NotNull String filePath, @NotNull String text, boolean stripTrailingSpaces);
471
472   Document getDocument(@NotNull PsiFile file);
473
474   @NotNull
475   List<GutterMark> findAllGutters(@NotNull @TestDataFile String filePath);
476
477   List<GutterMark> findAllGutters();
478
479   void type(final char c);
480
481   void type(@NotNull String s);
482
483   void performEditorAction(@NotNull String actionId);
484
485   /**
486    * If the action is visible and enabled, perform it
487    *
488    * @return updated action's presentation
489    */
490   @NotNull
491   Presentation testAction(@NotNull AnAction action);
492
493   @Nullable
494   List<String> getCompletionVariants(@NotNull @TestDataFile String... filesBefore);
495
496   /**
497    * @return null if the only item was auto-completed
498    */
499   @Nullable
500   LookupElement[] getLookupElements();
501
502   VirtualFile findFileInTempDir(@NotNull String filePath);
503
504   @Nullable
505   List<String> getLookupElementStrings();
506
507   void finishLookup(@MagicConstant(valuesFromClass = Lookup.class) char completionChar);
508
509   LookupEx getLookup();
510
511   @NotNull
512   PsiElement getElementAtCaret();
513
514   void renameElementAtCaret(@NotNull String newName);
515
516   /**
517    * Renames element at caret using injected {@link com.intellij.refactoring.rename.RenameHandler}s.
518    * Very close to {@link #renameElementAtCaret(String)} but uses handlers.
519    *
520    * @param newName new name for the element.
521    */
522   void renameElementAtCaretUsingHandler(@NotNull String newName);
523
524   void renameElement(@NotNull PsiElement element, @NotNull String newName);
525
526   void allowTreeAccessForFile(@NotNull VirtualFile file);
527
528   void allowTreeAccessForAllFiles();
529
530   void renameElement(@NotNull PsiElement element,
531                      @NotNull String newName,
532                      boolean searchInComments,
533                      boolean searchTextOccurrences);
534
535   <T extends PsiElement> T findElementByText(@NotNull String text, @NotNull Class<T> elementClass);
536
537   void testFolding(@NotNull String fileName);
538
539   void testFoldingWithCollapseStatus(@NotNull final String verificationFileName, @Nullable String destinationFileName);
540
541   void testFoldingWithCollapseStatus(@NotNull String fileName);
542
543   void testRainbow(@NotNull String fileName, @NotNull String text, boolean isRainbowOn, boolean withColor);
544
545   void testInlays();
546
547   void checkResultWithInlays(String text);
548
549   void assertPreferredCompletionItems(int selected, @NotNull String... expected);
550
551   /**
552    * Initializes the structure view for the file currently loaded in the editor and passes it to the specified consumer.
553    *
554    * @param consumer the callback in which the actual testing of the structure view is performed.
555    */
556   void testStructureView(@NotNull Consumer<StructureViewComponent> consumer);
557
558   /**
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.
561    *
562    * @param caresAboutInjection true if the fixture should look for an injection at caret, false otherwise.
563    */
564   void setCaresAboutInjection(boolean caresAboutInjection);
565
566   /**
567    * Completes basically (see {@link #completeBasic()}) <strong>all</strong>
568    * carets (places marked with {@link #CARET_MARKER} in file. Example:
569    * <pre>
570    *   PyC&lt;caret&gt; is IDE for Py&lt;caret&gt;
571    * </pre>
572    * should be completed to
573    * <pre>
574    *   PyCharm is IDE for Python
575    * </pre>
576    * Actually, it works just like {@link #completeBasic()} but supports
577    * several  {@link #CARET_MARKER}
578    *
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()
583    */
584   @NotNull
585   List<LookupElement> completeBasicAllCarets(@Nullable Character charToTypeAfterCompletion);
586
587   /**
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
593    */
594   @NotNull
595   List<Object> getGotoClassResults(@NotNull String pattern, boolean searchEverywhere, @Nullable PsiElement contextForSorting);
596
597   /**
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
600    */
601   @NotNull
602   List<Crumb> getBreadcrumbsAtCaret();
603
604   void saveText(@NotNull VirtualFile file, @NotNull String text);
605
606   @NotNull
607   default Disposable getProjectDisposable() {
608     return getProject();
609   }
610 }