mad testing: extract java-specific code, check stubs more frequently

This commit is contained in:
peter
2017-07-18 10:31:33 +02:00
parent aed46fcdd6
commit 64f26ad092
11 changed files with 245 additions and 126 deletions
@@ -47,7 +47,7 @@ public class ApplyRandomIntentionsTest extends AbstractApplyAndRevertTestCase {
AtomicLong rebuildStamp = new AtomicLong();
CheckerSettings settings = CheckerSettings.DEFAULT_SETTINGS.withIterationCount(30);
Generator<InvokeIntention> genIntention = psiJavaFiles().flatMap(InvokeIntention::randomIntentions);
Generator<InvokeIntention> genIntention = psiJavaFiles().flatMap(file -> InvokeIntention.randomIntentions(file, new JavaIntentionPolicy()));
PropertyChecker.forAll(settings, Generator.listsOf(genIntention.noShrink()), list -> {
long startModCount = tracker.getModificationCount();
if (rebuildStamp.getAndSet(startModCount) != startModCount) {
@@ -74,7 +74,7 @@ public class ApplyRandomIntentionsTest extends AbstractApplyAndRevertTestCase {
Generator.constant(new DeleteForeachInitializers(file)),
Generator.constant(new DeleteSecondArgument(file)),
Generator.constant(new MakeAllMethodsVoid(file)));
Generator<MadTestingAction> allActions = Generator.frequency(2, InvokeIntention.randomIntentions(file),
Generator<MadTestingAction> allActions = Generator.frequency(2, InvokeIntention.randomIntentions(file, new JavaIntentionPolicy()),
1, Generator.constant(new RehighlightAllEditors(myProject)),
1, mutation);
return Generator.listsOf(IntDistribution.uniform(0, 5), allActions.noShrink());
@@ -31,7 +31,7 @@ public class CompletionConsistencyTest extends AbstractApplyAndRevertTestCase {
CheckerSettings settings = CheckerSettings.DEFAULT_SETTINGS;
PropertyChecker.forAll(settings.withIterationCount(20), psiJavaFiles(), file -> {
System.out.println("for file: " + file.getVirtualFile().getPresentableUrl());
PropertyChecker.forAll(settings.withIterationCount(10), Generator.listsOf(InvokeCompletion.completions(file)), list -> {
PropertyChecker.forAll(settings.withIterationCount(10), Generator.listsOf(InvokeCompletion.completions(file, new JavaCompletionPolicy())), list -> {
changeAndRevert(myProject, () -> MadTestingAction.runActions(list));
return true;
});
@@ -0,0 +1,65 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.java.propertyBased;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
public abstract class CompletionPolicy {
/**
* @return the lookup string of an element that should be suggested in the given position
*/
public String getExpectedVariant(Editor editor, PsiFile file) {
PsiElement leaf = file.findElementAt(editor.getCaretModel().getOffset());
PsiReference ref = file.findReferenceAt(editor.getCaretModel().getOffset());
PsiElement refTarget = ref == null ? null : ref.resolve();
if (leaf == null) {
return null;
}
String leafText = leaf.getText();
if (leafText.isEmpty() ||
!Character.isLetter(leafText.charAt(0)) ||
leaf instanceof PsiWhiteSpace ||
PsiTreeUtil.getParentOfType(leaf, PsiComment.class, false) != null) {
return null;
}
if (ref != null) {
if (refTarget == null || !shouldSuggestReferenceText(ref)) return null;
}
else {
if (!SyntaxTraverser.psiTraverser(file).filter(PsiErrorElement.class).isEmpty()) {
return null;
}
if (!shouldSuggestNonReferenceLeafText(leaf)) return null;
}
return leafText;
}
protected boolean shouldSuggestNonReferenceLeafText(@NotNull PsiElement leaf) {
return true;
}
protected boolean shouldSuggestReferenceText(@NotNull PsiReference ref) {
return true;
}
}
@@ -29,7 +29,7 @@ import java.util.Objects;
class DeleteRange extends ActionOnRange {
private final PsiFile myFile;
private DeleteRange(PsiFile file, int startOffset, int endOffset) {
DeleteRange(PsiFile file, int startOffset, int endOffset) {
super(file.getViewProvider().getDocument(), startOffset, endOffset);
assert myMarker.getDocument().getTextLength() == file.getTextLength() : file + " " + myMarker.getDocument();
myFile = file;
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.java.propertyBased;
import com.intellij.codeInsight.intention.IntentionAction;
import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
public class IntentionPolicy {
public boolean mayInvokeIntention(@NotNull IntentionAction action) {
return action.startInWriteAction() && !shouldSkipIntention(action.getText());
}
protected boolean shouldSkipIntention(@NotNull String actionText) {
return false;
}
}
@@ -23,7 +23,6 @@ import com.intellij.codeInsight.lookup.LookupEx;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.lookup.impl.LookupImpl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
@@ -31,15 +30,13 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import junit.framework.TestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import slowCheck.Generator;
import slowCheck.IntDistribution;
@@ -52,25 +49,26 @@ import java.util.Set;
* @author peter
*/
class InvokeCompletion extends ActionOnRange {
final int itemIndexRaw;
LookupElement selectedItem;
final char completionChar;
private final int myItemIndexRaw;
private LookupElement mySelectedItem;
private final char myCompletionChar;
private final PsiFile myFile;
private final CompletionPolicy myPolicy;
private final String myConstructorArgs;
InvokeCompletion(Document document, int offset, int itemIndexRaw, char completionChar, PsiFile file) {
super(document, offset, offset);
this.itemIndexRaw = itemIndexRaw;
this.completionChar = completionChar;
InvokeCompletion(PsiFile file, int offset, int itemIndexRaw, char completionChar, CompletionPolicy policy) {
super(file.getViewProvider().getDocument(), offset, offset);
this.myItemIndexRaw = itemIndexRaw;
this.myCompletionChar = completionChar;
myFile = file;
myPolicy = policy;
myConstructorArgs = "_, " + offset + ", " + itemIndexRaw + ", '" + StringUtil.escapeStringCharacters(String.valueOf(completionChar)) + "', _";
}
@Override
public String toString() {
return "CompletionInvocation{" +
"offset=" + getStartOffset() +
", selectedItem=" + selectedItem + "(" + itemIndexRaw + ")" +
", completionChar=" + StringUtil.escapeStringCharacters(String.valueOf(completionChar)) +
'}';
return "InvokeCompletion(" + myConstructorArgs + ")" +
"{" + myFile.getVirtualFile().getPath() + ", offset=" + getStartOffset() + ", selected=" + mySelectedItem + '}';
}
@Override
@@ -89,6 +87,7 @@ class InvokeCompletion extends ActionOnRange {
Disposable raiseCompletionLimit = Disposer.newDisposable();
Registry.get("ide.completion.variant.limit").setValue(100_000, raiseCompletionLimit);
try {
PsiTestUtil.checkPsiStructureWithCommit(myFile, PsiTestUtil::checkStubsMatchText);
performCompletion(editor);
PsiTestUtil.checkPsiStructureWithCommit(myFile, PsiTestUtil::checkStubsMatchText);
}
@@ -101,7 +100,7 @@ class InvokeCompletion extends ActionOnRange {
}
private void performCompletion(Editor editor) {
String expectedVariant = getExpectedVariant(editor, myFile);
String expectedVariant = myPolicy.getExpectedVariant(editor, myFile);
new CodeCompletionHandlerBase(CompletionType.BASIC).invokeCompletion(myFile.getProject(), editor);
@@ -119,9 +118,9 @@ class InvokeCompletion extends ActionOnRange {
checkNoDuplicates(items);
LookupElement item = items.get(itemIndexRaw % items.size());
selectedItem = item;
((LookupImpl)lookup).finishLookup(completionChar, item);
LookupElement item = items.get(myItemIndexRaw % items.size());
mySelectedItem = item;
((LookupImpl)lookup).finishLookup(myCompletionChar, item);
}
private static void checkNoDuplicates(List<LookupElement> items) {
@@ -138,61 +137,13 @@ class InvokeCompletion extends ActionOnRange {
}
}
@Nullable
private static String getExpectedVariant(Editor editor, PsiFile file) {
PsiElement leaf = file.findElementAt(editor.getCaretModel().getOffset());
PsiReference ref = file.findReferenceAt(editor.getCaretModel().getOffset());
PsiElement refTarget = ref == null ? null : ref.resolve();
if (leaf == null) {
return null;
}
String leafText = leaf.getText();
if (leafText.isEmpty() ||
!Character.isLetter(leafText.charAt(0)) ||
leaf instanceof PsiWhiteSpace ||
PsiTreeUtil.getParentOfType(leaf, PsiComment.class, false) != null) {
return null;
}
if (ref != null) {
if (refTarget == null) return null;
if (ref instanceof PsiJavaCodeReferenceElement && !shouldSuggestJavaTarget((PsiJavaCodeReferenceElement)ref)) {
return null;
}
}
else {
if (!SyntaxTraverser.psiTraverser(file).filter(PsiErrorElement.class).isEmpty()) {
return null;
}
if (leaf instanceof PsiIdentifier) return null; // it's not a ref, just some name
if (leaf instanceof PsiKeyword) {
if (leaf.getParent() instanceof PsiClassObjectAccessExpression &&
PsiUtil.resolveClassInType(((PsiClassObjectAccessExpression)leaf.getParent()).getType()) == null) {
return null;
}
}
if (leaf.textMatches(PsiKeyword.TRUE) || leaf.textMatches(PsiKeyword.FALSE)) {
return null; // boolean literal presence depends on expected types, which can be missing in red files
}
}
return leafText;
}
private static boolean shouldSuggestJavaTarget(PsiJavaCodeReferenceElement ref) {
if (PsiTreeUtil.getParentOfType(ref, PsiPackageStatement.class) == null) return false;
PsiElement target = ref.resolve();
if (!ref.isQualified() && target instanceof PsiPackage) return false;
return target != null;
}
@NotNull
static Generator<InvokeCompletion> completions(PsiFile psiFile) {
Document document = psiFile.getViewProvider().getDocument();
static Generator<InvokeCompletion> completions(PsiFile psiFile, CompletionPolicy policy) {
return Generator.from(data -> {
int offset = data.drawInt(IntDistribution.uniform(0, document.getTextLength()));
int offset = data.drawInt(IntDistribution.uniform(0, psiFile.getViewProvider().getDocument().getTextLength()));
int itemIndex = data.drawInt(IntDistribution.uniform(0, 100));
char c = Generator.sampledFrom('\n', '\t', '\r', ' ', '.', '(').generateUnstructured(data);
return new InvokeCompletion(document, offset, itemIndex, c, psiFile);
return new InvokeCompletion(psiFile, offset, itemIndex, c, policy);
});
}
}
@@ -18,7 +18,6 @@ package com.intellij.java.propertyBased;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
@@ -26,7 +25,6 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiInvalidElementAccessException;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
import com.intellij.util.containers.ContainerUtil;
@@ -39,42 +37,32 @@ import java.util.List;
class InvokeIntention extends ActionOnRange {
private final PsiFile myFile;
private final int myIntentionIndex;
private IntentionAction myIntentionAction;
private final IntentionPolicy myPolicy;
private final String myConstructorArgs;
private String myInvocationLog = "not invoked";
private InvokeIntention(PsiFile file, int offset, int intentionIndex) {
InvokeIntention(PsiFile file, int offset, int intentionIndex, IntentionPolicy policy) {
super(file.getViewProvider().getDocument(), offset, offset);
myFile = file;
myIntentionIndex = intentionIndex;
myPolicy = policy;
myConstructorArgs = "_ , " + offset + ", " + intentionIndex + ", _";
}
@NotNull
static Generator<InvokeIntention> randomIntentions(@NotNull PsiFile psiFile) {
static Generator<InvokeIntention> randomIntentions(@NotNull PsiFile psiFile, @NotNull IntentionPolicy policy) {
return Generator.zipWith(Generator.integers(0, psiFile.getTextLength()), Generator.integers(0, 100),
(offset, index) -> new InvokeIntention(psiFile, offset, index)).noShrink();
(offset, index) -> new InvokeIntention(psiFile, offset, index, policy)).noShrink();
}
@Override
public String toString() {
return "InvokeIntention[" + myFile.getVirtualFile().getPath() + ", offset " + getStartOffset() +
", invoke '" + ReadAction.compute(() -> getIntentionText()) + "']";
}
private String getIntentionText() {
if (myIntentionAction == null) {
return "index " + String.valueOf(myIntentionIndex);
}
String name = null;
try {
name = myIntentionAction.getText();
}
catch (PsiInvalidElementAccessException ignore) {
}
return name == null ? myIntentionAction.toString() : name;
return "InvokeIntention(" + myConstructorArgs + "){" + myFile.getVirtualFile().getPath() + "," + myInvocationLog + "}";
}
public void performAction() {
int offset = getStartOffset();
myInvocationLog = "offset " + offset;
if (offset < 0) return;
Editor editor = FileEditorManager.getInstance(myFile.getProject()).openTextEditor(new OpenFileDescriptor(myFile.getProject(), myFile.getVirtualFile(), offset), true);
@@ -82,8 +70,9 @@ class InvokeIntention extends ActionOnRange {
List<HighlightInfo> infos = RehighlightAllEditors.highlightEditor(editor, myFile.getProject());
boolean hasErrors = infos.stream().anyMatch(i -> i.getSeverity() == HighlightSeverity.ERROR);
IntentionAction intention = myIntentionAction = getRandomIntention(editor);
IntentionAction intention = getRandomIntention(editor);
if (intention == null) return;
myInvocationLog += ", invoke '" + intention.getText() + "'";
Document changedDocument = getDocumentToBeChanged(intention);
String textBefore = changedDocument == null ? null : changedDocument.getText();
@@ -116,31 +105,7 @@ class InvokeIntention extends ActionOnRange {
@Nullable
private IntentionAction getRandomIntention(Editor editor) {
List<IntentionAction> actions = ContainerUtil.filter(CodeInsightTestFixtureImpl.getAvailableIntentions(editor, myFile),
action -> action.startInWriteAction() &&
!shouldSkipIntention(action.getText()));
myPolicy::mayInvokeIntention);
return actions.isEmpty() ? null : actions.get(myIntentionIndex % actions.size());
}
private static boolean shouldSkipIntention(String actionText) {
return actionText.startsWith("Flip") ||
actionText.startsWith("Attach annotations") || // changes project model
actionText.startsWith("Convert to string literal") || // can produce uncompilable code by design
actionText.startsWith("Optimize imports") || // https://youtrack.jetbrains.com/issue/IDEA-173801
actionText.startsWith("Make method default") ||
actionText.startsWith("Convert to project line separators") || // changes VFS, not document
actionText.contains("to custom tags") || // changes only inspection settings
actionText.contains("to 'Ignore if annotated by' list") || // changes only inspection settings
actionText.startsWith("Allow these suppressions") || // changes only inspection settings
actionText.startsWith("Typo: Change to...") || // doesn't change file text (starts live template)
actionText.startsWith("Change class type parameter") || // doesn't change file text (starts live template)
actionText.startsWith("Rename reference") || // doesn't change file text (starts live template)
actionText.startsWith("Detail exceptions") || // can produce uncompilable code if 'catch' section contains 'instanceof's
actionText.startsWith("Insert call to super method") || // super method can declare checked exceptions, unexpected at this point
actionText.startsWith("Add qualifier") || // in javadoc; displays a popup which isn't allowed in tests
actionText.startsWith("Cast to ") || // produces uncompilable code by design
actionText.startsWith("Unwrap 'else' branch (changes semantics)") || // might produce code with final variables are initialized several times
actionText.startsWith("Create missing 'switch' branches") || // if all existing branches do 'return something', we don't automatically generate compilable code for new branches
actionText.startsWith("Unimplement");
}
}
@@ -45,8 +45,8 @@ public class JavaCodeInsightSanityTest extends LightPlatformCodeInsightFixtureTe
public void testRandomActivity() {
AbstractApplyAndRevertTestCase.enableAllInspections(getProject(), getTestRootDisposable());
Function<PsiFile, Generator<? extends MadTestingAction>> fileActions = file ->
Generator.anyOf(InvokeIntention.randomIntentions(file),
InvokeCompletion.completions(file),
Generator.anyOf(InvokeIntention.randomIntentions(file, new JavaIntentionPolicy()),
InvokeCompletion.completions(file, new JavaCompletionPolicy()),
DeleteRange.psiRangeDeletions(file));
PropertyChecker.forAll(actionsOnJavaFiles(fileActions), FileWithActions::runActions);
}
@@ -0,0 +1,58 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.java.propertyBased;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
class JavaCompletionPolicy extends CompletionPolicy {
@Override
protected boolean shouldSuggestReferenceText(@NotNull PsiReference ref) {
if (ref instanceof PsiJavaCodeReferenceElement && !shouldSuggestJavaTarget((PsiJavaCodeReferenceElement)ref)) {
return false;
}
return true;
}
private static boolean shouldSuggestJavaTarget(PsiJavaCodeReferenceElement ref) {
if (PsiTreeUtil.getParentOfType(ref, PsiPackageStatement.class) == null) return false;
PsiElement target = ref.resolve();
if (!ref.isQualified() && target instanceof PsiPackage) return false;
return target != null;
}
@Override
protected boolean shouldSuggestNonReferenceLeafText(@NotNull PsiElement leaf) {
if (leaf instanceof PsiIdentifier) return false; // name of some element
if (leaf instanceof PsiKeyword) {
if (leaf.getParent() instanceof PsiClassObjectAccessExpression &&
PsiUtil.resolveClassInType(((PsiClassObjectAccessExpression)leaf.getParent()).getType()) == null) {
return false;
}
}
if (leaf.textMatches(PsiKeyword.TRUE) || leaf.textMatches(PsiKeyword.FALSE)) {
return false; // boolean literal presence depends on expected types, which can be missing in red files
}
return true;
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.java.propertyBased;
import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
public class JavaIntentionPolicy extends IntentionPolicy {
@Override
protected boolean shouldSkipIntention(@NotNull String actionText) {
return actionText.startsWith("Flip") ||
actionText.startsWith("Attach annotations") || // changes project model
actionText.startsWith("Convert to string literal") || // can produce uncompilable code by design
actionText.startsWith("Optimize imports") || // https://youtrack.jetbrains.com/issue/IDEA-173801
actionText.startsWith("Make method default") ||
actionText.startsWith("Convert to project line separators") || // changes VFS, not document
actionText.contains("to custom tags") || // changes only inspection settings
actionText.contains("to 'Ignore if annotated by' list") || // changes only inspection settings
actionText.startsWith("Allow these suppressions") || // changes only inspection settings
actionText.startsWith("Typo: Change to...") || // doesn't change file text (starts live template)
actionText.startsWith("Change class type parameter") || // doesn't change file text (starts live template)
actionText.startsWith("Rename reference") || // doesn't change file text (starts live template)
actionText.startsWith("Detail exceptions") || // can produce uncompilable code if 'catch' section contains 'instanceof's
actionText.startsWith("Insert call to super method") || // super method can declare checked exceptions, unexpected at this point
actionText.startsWith("Add qualifier") || // in javadoc; displays a popup which isn't allowed in tests
actionText.startsWith("Cast to ") || // produces uncompilable code by design
actionText.startsWith("Unwrap 'else' branch (changes semantics)") || // might produce code with final variables are initialized several times
actionText.startsWith("Create missing 'switch' branches") || // if all existing branches do 'return something', we don't automatically generate compilable code for new branches
actionText.startsWith("Unimplement");
}
}
@@ -23,6 +23,7 @@ import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
import org.jetbrains.annotations.NotNull;
@@ -56,6 +57,7 @@ class RehighlightAllEditors implements MadTestingAction {
static List<HighlightInfo> highlightEditor(Editor editor, Project project) {
PsiDocumentManager.getInstance(project).commitAllDocuments();
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
PsiTestUtil.checkStubsMatchText(file);
return CodeInsightTestFixtureImpl.instantiateAndRun(file, editor, new int[0], false);
}
}