From 484c9e29b960e685a25aba2403ef159a2f978d2f Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 13 Feb 2018 20:45:44 +0100 Subject: [PATCH] mad testing: don't shrink offsets to speed up minimization --- jetCheck/src/org/jetbrains/jetCheck/Generator.java | 4 +++- .../src/org/jetbrains/jetCheck/ImperativeCommand.java | 5 ++++- .../testFramework/propertyBased/ActionOnRange.java | 11 +++++++++++ .../testFramework/propertyBased/DeleteRange.java | 5 ++--- .../propertyBased/InsertLineComment.java | 2 +- .../testFramework/propertyBased/InsertString.java | 2 +- .../testFramework/propertyBased/InvokeCompletion.java | 3 +-- .../testFramework/propertyBased/InvokeIntention.java | 5 ++--- .../testFramework/propertyBased/MadTestingUtil.java | 2 -- 9 files changed, 25 insertions(+), 14 deletions(-) diff --git a/jetCheck/src/org/jetbrains/jetCheck/Generator.java b/jetCheck/src/org/jetbrains/jetCheck/Generator.java index 6046d2896294..6d6e1eefd6c9 100644 --- a/jetCheck/src/org/jetbrains/jetCheck/Generator.java +++ b/jetCheck/src/org/jetbrains/jetCheck/Generator.java @@ -73,7 +73,9 @@ public class Generator { /** * Turns off automatic minimization for the data produced by this generator (and its components, if any). - * This can be useful to speed up minimization by not wasting time on shrinking objects where it makes no sense. + * This can be useful to speed up minimization by not wasting time on shrinking objects where it makes no sense. + * It's especially useful when using stateful generators (e.g. {@link ImperativeCommand}), because + * shrinkable values there can lead to doubling of the shrinking time. */ public Generator noShrink() { return from(data -> data.generateNonShrinkable(this)); diff --git a/jetCheck/src/org/jetbrains/jetCheck/ImperativeCommand.java b/jetCheck/src/org/jetbrains/jetCheck/ImperativeCommand.java index 07a7472a0c86..25073df67947 100644 --- a/jetCheck/src/org/jetbrains/jetCheck/ImperativeCommand.java +++ b/jetCheck/src/org/jetbrains/jetCheck/ImperativeCommand.java @@ -82,7 +82,10 @@ public interface ImperativeCommand { * The message is a Java format string, so you can use it to include the generated value, e.g. * {@code String s = generateValue(stringsOf(asciiLetters(), "Generated %s")}.

* If you don't want to generate message, or would like to show the generated value in a custom way, pass {@code null}. - * You can use {@link #logMessage} later to still leave a trace of this value generation in the log. + * You can use {@link #logMessage} later to still leave a trace of this value generation in the log.

+ * + * Consider making generators non-shrinkable (by invoking {@link Generator#noShrink()}) where possible + * because it can speed up overall failing scenario minimization significantly. */ T generateValue(@NotNull Generator generator, @Nullable String logMessage); diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/ActionOnRange.java b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/ActionOnRange.java index 6c5010d31e6c..69089eca3f3a 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/ActionOnRange.java +++ b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/ActionOnRange.java @@ -29,6 +29,7 @@ import com.intellij.psi.SmartPsiFileRange; import com.intellij.psi.impl.DebugUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jetCheck.Generator; /** * @author peter @@ -98,4 +99,14 @@ abstract class ActionOnRange implements MadTestingAction { } return myFinalRange; } + + @SuppressWarnings("SameParameterValue") + protected int generatePsiOffset(@NotNull Environment env, @Nullable String logMessage) { + return env.generateValue(Generator.integers(0, getFile().getTextLength()).noShrink(), logMessage); + } + + protected int generateDocOffset(@NotNull Environment env, @Nullable String logMessage) { + return env.generateValue(Generator.integers(0, getDocument().getTextLength()).noShrink(), logMessage); + } + } diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/DeleteRange.java b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/DeleteRange.java index 5e3f9296958b..c1861e2ddb21 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/DeleteRange.java +++ b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/DeleteRange.java @@ -36,9 +36,8 @@ public class DeleteRange extends ActionOnRange { public void performCommand(@NotNull Environment env) { PsiFile psiFile = getFile(); - int fileLength = psiFile.getTextLength(); - int startOffset = env.generateValue(Generator.integers(0, fileLength), null); - int endOffset = Math.min(fileLength, startOffset + env.generateValue(Generator.integers(IntDistribution.geometric(10)), null)); + int startOffset = generatePsiOffset(env, null); + int endOffset = Math.min(psiFile.getTextLength(), startOffset + env.generateValue(Generator.integers(IntDistribution.geometric(10)).noShrink(), null)); PsiElement start = psiFile.findElementAt(startOffset); PsiElement end = psiFile.findElementAt(endOffset); if (start == null || end == null) return; diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InsertLineComment.java b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InsertLineComment.java index 8de374acc294..f534241bd2e9 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InsertLineComment.java +++ b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InsertLineComment.java @@ -25,7 +25,7 @@ public class InsertLineComment extends ActionOnRange { public void performCommand(@NotNull Environment env) { PsiDocumentManager.getInstance(getProject()).commitDocument(getDocument()); - int randomOffset = env.generateValue(Generator.integers(0, getFile().getTextLength()), null); + int randomOffset = generatePsiOffset(env, null); PsiElement leaf = getFile().findElementAt(randomOffset); TextRange leafRange = leaf != null ? leaf.getTextRange() : null; int insertOffset = leafRange != null ? leafRange.getEndOffset() : 0; diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InsertString.java b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InsertString.java index 1b4d8f3a94b5..36e137cf1393 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InsertString.java +++ b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InsertString.java @@ -30,7 +30,7 @@ public class InsertString extends ActionOnRange { @Override public void performCommand(@NotNull Environment env) { - int offset = env.generateValue(Generator.integers(0, getDocument().getTextLength()), null); + int offset = generateDocOffset(env, null); String toInsert = env.generateValue(Generator.stringsOf(Generator.asciiPrintableChars()), "Insert '%s' at " + offset + " in " + getPath()); WriteCommandAction.runWriteCommandAction(getProject(), () -> getDocument().insertString(offset, toInsert)); } diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InvokeCompletion.java b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InvokeCompletion.java index b0bc49eff3d7..859e42f249f6 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InvokeCompletion.java +++ b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InvokeCompletion.java @@ -82,8 +82,7 @@ public class InvokeCompletion extends ActionOnRange { @Override public void performCommand(@NotNull Environment env) { - int offset = env.generateValue(Generator.integers(0, getDocument().getTextLength()), - "Invoke basic completion at offset %s (" + getPath() + ")"); + int offset = generateDocOffset(env, "Invoke basic completion at offset %s (" + getPath() + ")"); String selectionCharacters = myPolicy.getPossibleSelectionCharacters(); char c = selectionCharacters.charAt(env.generateValue(Generator.integers(0, selectionCharacters.length() - 1), null)); performActionAt(offset, c, items -> env.generateValue(Generator.sampledFrom(items), null), env::logMessage); diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InvokeIntention.java b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InvokeIntention.java index b6574dfb13bc..4f52c0b541fe 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InvokeIntention.java +++ b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/InvokeIntention.java @@ -74,8 +74,7 @@ public class InvokeIntention extends ActionOnRange { @Override public void performCommand(@NotNull Environment env) { - int offset = env.generateValue(Generator.integers(0, getDocument().getTextLength()), - "Go to offset %s and run daemon (" + getPath() + ")"); + int offset = generateDocOffset(env, "Go to offset %s and run daemon (" + getPath() + ")"); doInvokeIntention(offset, actions -> { if (actions.isEmpty()) { @@ -83,7 +82,7 @@ public class InvokeIntention extends ActionOnRange { return null; } - IntentionAction result = env.generateValue(Generator.sampledFrom(actions), null); + IntentionAction result = env.generateValue(Generator.sampledFrom(actions).noShrink(), null); env.logMessage("Invoke intention '" + result.getText() + "'"); return result; }); diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/MadTestingUtil.java b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/MadTestingUtil.java index bdee0c122595..5ff29a54bfb0 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/MadTestingUtil.java +++ b/platform/testFramework/testSrc/com/intellij/testFramework/propertyBased/MadTestingUtil.java @@ -41,7 +41,6 @@ import com.intellij.testFramework.RunAll; import com.intellij.testFramework.UsefulTestCase; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.util.ThrowableRunnable; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.JBIterable; import com.intellij.util.containers.TreeTraversal; import com.intellij.util.ui.UIUtil; @@ -236,7 +235,6 @@ public class MadTestingUtil { return () -> env -> new RunAll() .append(() -> { File ioFile = env.generateValue(randomFiles, "Working with %s"); - System.out.println(ioFile); VirtualFile vFile = copyFileToProject(ioFile, fixture, rootPath); PsiFile psiFile = fixture.getPsiManager().findFile(vFile); if (psiFile instanceof PsiBinaryFile || psiFile instanceof PsiPlainTextFile) {