mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
jetCheck: restart shrinking from beginning: sometimes it helps to shrink more
This commit is contained in:
@@ -76,20 +76,35 @@ class PropertyFailureImpl<T> implements PropertyFailure<T> {
|
||||
}
|
||||
|
||||
private void shrink() {
|
||||
ShrinkStep step = minimized.data.shrink();
|
||||
while (step != null) {
|
||||
step = findSuccessfulShrink(step);
|
||||
if (step != null) {
|
||||
step = step.onSuccess(minimized.data);
|
||||
}
|
||||
NodeId limit = null;
|
||||
while (true) {
|
||||
ShrinkStep lastSuccessfulShrink = shrinkIteration(limit);
|
||||
if (lastSuccessfulShrink == null) break;
|
||||
limit = lastSuccessfulShrink.getNodeAfter();
|
||||
}
|
||||
}
|
||||
|
||||
private ShrinkStep shrinkIteration(NodeId limit) {
|
||||
ShrinkStep lastSuccessfulShrink = null;
|
||||
ShrinkStep step = minimized.data.shrink();
|
||||
while (step != null) {
|
||||
step = findSuccessfulShrink(step, limit);
|
||||
if (step != null) {
|
||||
lastSuccessfulShrink = step;
|
||||
step = step.onSuccess(minimized.data);
|
||||
}
|
||||
}
|
||||
return lastSuccessfulShrink;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ShrinkStep findSuccessfulShrink(ShrinkStep step) {
|
||||
private ShrinkStep findSuccessfulShrink(ShrinkStep step, @Nullable NodeId limit) {
|
||||
List<CustomizedNode> combinatorial = new ArrayList<>();
|
||||
|
||||
while (step != null) {
|
||||
if (limit != null && limit.number <= step.getNodeAfter().number) {
|
||||
break;
|
||||
}
|
||||
StructureNode node = step.apply(minimized.data);
|
||||
if (node != null && iteration.session.generatedHashes.add(node.hashCode())) {
|
||||
CombinatorialIntCustomizer customizer = new CombinatorialIntCustomizer();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
package jetCheck;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -70,4 +71,20 @@ class RemoveListRange extends ShrinkStep {
|
||||
int newLength = Math.min(length * 2, start - 1);
|
||||
return new RemoveListRange(inheritor, start, start - newLength, newLength);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
NodeId getNodeAfter() {
|
||||
return node.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RemoveListRange{" +
|
||||
"last=" + lastSuccessfulRemove +
|
||||
", start=" + start +
|
||||
", length=" + length +
|
||||
", node=" + node.id + ": " + node +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ abstract class ShrinkStep {
|
||||
@Nullable
|
||||
abstract ShrinkStep onFailure();
|
||||
|
||||
@NotNull
|
||||
abstract NodeId getNodeAfter();
|
||||
|
||||
static ShrinkStep create(@NotNull NodeId replaced,
|
||||
@NotNull StructureElement replacement,
|
||||
@Nullable Function<StructureNode, ShrinkStep> onSuccess,
|
||||
@@ -45,6 +48,17 @@ abstract class ShrinkStep {
|
||||
ShrinkStep onFailure() {
|
||||
return onFailure == null ? null : onFailure.get();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
NodeId getNodeAfter() {
|
||||
return replacement.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "replace " + replaced + " with " + replacement;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +110,17 @@ class StructureNode extends StructureElement {
|
||||
ShrinkStep onFailure() {
|
||||
return wrapChildShrink(index, step.onFailure());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
NodeId getNodeAfter() {
|
||||
return step.getNodeAfter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "-" + step.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ public class GeneratorTest extends PropertyCheckerTestCase {
|
||||
public void testListSumMod() {
|
||||
checkFalsified(nonEmptyLists(integers()),
|
||||
l -> l.stream().mapToInt(Integer::intValue).sum() % 10 != 0,
|
||||
181);
|
||||
390);
|
||||
}
|
||||
|
||||
public void testListContainsDivisible() {
|
||||
@@ -44,7 +44,7 @@ public class GeneratorTest extends PropertyCheckerTestCase {
|
||||
public void testIsSorted() {
|
||||
PropertyFailure<List<Integer>> failure = checkFalsified(nonEmptyLists(integers()),
|
||||
l -> l.stream().sorted().collect(Collectors.toList()).equals(l),
|
||||
20);
|
||||
22);
|
||||
List<Integer> value = failure.getMinimalCounterexample().getExampleValue();
|
||||
assertEquals(2, value.size());
|
||||
assertTrue(value.toString(), value.stream().allMatch(i -> Math.abs(i) < 2));
|
||||
@@ -57,7 +57,7 @@ public class GeneratorTest extends PropertyCheckerTestCase {
|
||||
public void testSortedDoublesNonDescending() {
|
||||
PropertyFailure<List<Double>> failure = checkFalsified(listsOf(doubles()),
|
||||
l -> isSorted(l.stream().sorted().collect(Collectors.toList())),
|
||||
35);
|
||||
41);
|
||||
assertEquals(2, failure.getMinimalCounterexample().getExampleValue().size());
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
*/
|
||||
package jetCheck;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static jetCheck.Generator.*;
|
||||
|
||||
@@ -17,7 +21,7 @@ public class ShrinkTest extends PropertyCheckerTestCase {
|
||||
String s = l.toString();
|
||||
return !"abcdefghijklmnopqrstuvwxyz()[]#!".chars().allMatch(c -> s.indexOf((char)c) >= 0);
|
||||
},
|
||||
225);
|
||||
258);
|
||||
}
|
||||
|
||||
public void testShrinkingNonEmptyList() {
|
||||
@@ -27,4 +31,19 @@ public class ShrinkTest extends PropertyCheckerTestCase {
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
public void testWhenEarlyObjectsCannotBeShrunkBeforeLater() {
|
||||
Generator<String> gen = listsOf(IntDistribution.uniform(0, 2), listsOf(IntDistribution.uniform(0, 2), sampledFrom('a', 'b'))).map(List::toString);
|
||||
Set<String> failing = new HashSet<>(Arrays.asList("[[a, b], [a, b]]", "[[a, b], [a]]", "[[a], [a]]", "[[a]]", "[]"));
|
||||
Predicate<String> property = s -> !failing.contains(s);
|
||||
checkFalsified(gen, property, 0); // prove that it sometimes fails
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
try {
|
||||
PropertyChecker.forAll(gen).shouldHold(property);
|
||||
}
|
||||
catch (PropertyFalsified e) {
|
||||
assertEquals("[]", e.getBreakingValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user