Skip to content

Commit

Permalink
concentrates boundary finding to one location
Browse files Browse the repository at this point in the history
  • Loading branch information
henry committed Nov 17, 2017
1 parent 94f23a3 commit 50399bd
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 44 deletions.
2 changes: 1 addition & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.2.4</version>
<version>1.2.5-SNAPSHOT</version>
<executions>
<execution>
<id>pitest</id>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

import org.quicktheories.core.Gen;
import org.quicktheories.core.Strategy;
import org.quicktheories.impl.Distribution;
import org.quicktheories.impl.PrecursorDataPair;
import org.quicktheories.impl.ShapedDataSource;

/**
* Visits (in order) any likely shrink target, minima and maxima before switching to a
Expand All @@ -16,7 +13,7 @@
*/
class BoundarySkewedDistribution<T> implements Distribution<T> {

private ArrayDeque<long[]> toVisit = new ArrayDeque<long[]>();
private ArrayDeque<long[]> toVisit;

private final Gen<T> gen;
private final Strategy config;
Expand All @@ -25,7 +22,7 @@ class BoundarySkewedDistribution<T> implements Distribution<T> {
BoundarySkewedDistribution(Strategy config, Gen<T> gen) {
this.gen = gen;
this.config = config;
findBoundaries(config, gen);
toVisit = findBoundaries(config, gen);
}

public PrecursorDataPair<T> generate() {
Expand All @@ -35,22 +32,23 @@ public PrecursorDataPair<T> generate() {
} else {
forced = new long[0];
}
return generate(gen, forced, config.generateAttempts());
return generate(gen, config, forced);
}

private PrecursorDataPair<T> generate(Gen<T> gen, long[] forced, int maxTries) {
ShapedDataSource buffer = new ShapedDataSource(config.prng(), forced,
maxTries);
private PrecursorDataPair<T> generate(Gen<T> gen, Strategy config, long[] forced) {
ShapedDataSource buffer = new ShapedDataSource(config.prng(), forced, config.generateAttempts());
T t = gen.generate(buffer);
return new PrecursorDataPair<>(buffer.capturedPrecursor(), buffer.failedAssumptions(), t);
}

private void findBoundaries(Strategy config, Gen<T> gen) {
PrecursorDataPair<T> result = generate(gen, new long[0], config.generateAttempts());
toVisit.add(result.precursor().shrinkTarget());
toVisit.add(result.precursor().minLimit());
toVisit.add(result.precursor().maxLimit());


private ArrayDeque<long[]> findBoundaries(Strategy config, Gen<T> gen) {
ArrayDeque<long[]> ordered = new ArrayDeque<>();
PrecursorDataPair<T> startPoint = generate(gen, config, new long[0]);
ordered.add(startPoint.precursor().shrinkTarget());
ordered.add(startPoint.precursor().minLimit());
ordered.add(startPoint.precursor().maxLimit());
return ordered;
}


}
11 changes: 2 additions & 9 deletions core/src/main/java/org/quicktheories/impl/Core.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,8 @@ <T> Optional<Pair<Falsification<T>, PrecursorDataPair<T>>> findFalsifyingValue(

Guidance guidance = config.guidance();

// search randomly but first visit the maxima, minima and shrink point
RandomDistribution<T> randomDistribution = new RandomDistribution<>(config, prop.getGen());
PrecursorDataPair<T> startPoint = randomDistribution.generate();

Distribution<T> randomDistribution = new BoundarySkewedDistribution<>(config, prop.getGen());
ArrayDeque<long[]> toVisit = new ArrayDeque<long[]>();

// Always visit the shrink point, min and max
toVisit.add(startPoint.precursor().shrinkTarget());
toVisit.add(startPoint.precursor().minLimit());
toVisit.add(startPoint.precursor().maxLimit());

Distribution<T> distribution;
for (int i = 0; i != config.examples(); i++) {
Expand Down Expand Up @@ -93,6 +85,7 @@ <T> Optional<Pair<Falsification<T>, PrecursorDataPair<T>>> findFalsifyingValue(
return Optional.empty();
}


<T> List<T> shrink(PrecursorDataPair<T> precursor, Property<T> prop) {
PrecursorDataPair<T> lastSmallestState = precursor;
List<T> falsifyingValues = new ArrayList<T>();
Expand Down
1 change: 0 additions & 1 deletion core/src/test/java/org/quicktheories/core/GenTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ public void mixesValuesRandomlyWithOtherGens() {
assertThat(actual).containsExactly(2,1,4);
}


@SuppressWarnings("unchecked")
@Test
public void mapsToOptionalsWithoutEmptyWhenPercentageIs0() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public void generatesValuesAcrossPositiveRange() {
List<Float> vals = generateValues(testee, 100);
assertThat(vals.stream().filter( f -> f < 100f).count()).isGreaterThan(5);
assertThat(vals.stream().filter( f -> f > 500f).count()).isGreaterThan(40);
assertThat(vals.stream().filter( f -> f > 900f).count()).isLessThan(10);
assertThat(vals.stream().filter( f -> f > 900f).count()).isLessThanOrEqualTo(10);
}

@Test
Expand Down
33 changes: 17 additions & 16 deletions core/src/test/java/org/quicktheories/impl/GenAssert.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@
import org.assertj.core.api.AbstractAssert;
import org.quicktheories.core.Configuration;
import org.quicktheories.core.Gen;
import org.quicktheories.core.PseudoRandom;
import org.quicktheories.core.Strategy;
import org.quicktheories.impl.BoundarySkewedDistribution;
import org.quicktheories.impl.PrecursorDataPair;
import org.quicktheories.impl.ShapedDataSource;

public class GenAssert<T>
extends AbstractAssert<GenAssert<T>, Gen<T>> {
Expand All @@ -27,10 +23,11 @@ public static <T> GenAssert<T> assertThatGenerator(

public GenAssert<T> generatesTheMinAndMax(T min, T max) {
Strategy config = Configuration.systemStrategy().withFixedSeed(0);
BoundarySkewedDistribution<T> boundaries = new BoundarySkewedDistribution<T>(config,actual);
boundaries.generate(); // skip the shrink target
T actualMin = boundaries.generate().value();
T actualMax = boundaries.generate().value();
RandomDistribution<T> random = new RandomDistribution<T>(config,actual);
PrecursorDataPair<T> somePoint = random.generate();

T actualMin = generateFrom(somePoint.precursor().minLimit(), config);
T actualMax = generateFrom(somePoint.precursor().maxLimit(), config);

org.assertj.core.api.Assertions.assertThat(actualMin).isEqualTo(min);
org.assertj.core.api.Assertions.assertThat(actualMax).isEqualTo(max);
Expand All @@ -40,10 +37,10 @@ public GenAssert<T> generatesTheMinAndMax(T min, T max) {
public GenAssert<T> shrinksTowards(T target) {
Strategy config = Configuration.systemStrategy().withFixedSeed(0);
BoundarySkewedDistribution<T> boundaries = new BoundarySkewedDistribution<T>(config,actual);
// test relies on implementation detail that first returned value is the shrink point
T t = boundaries.generate().value();

org.assertj.core.api.Assertions.assertThat(t).isEqualTo(target);
long[] t = boundaries.generate().precursor().shrinkTarget();
T actual = generateFrom(t, config);
org.assertj.core.api.Assertions.assertThat(actual).isEqualTo(target);
return this;
}

Expand Down Expand Up @@ -92,15 +89,19 @@ public GenAssert<T> doesNotGenerate(
}

public static <T> List<T> generateValues(Gen<T> gen, int count) {
PseudoRandom prng = Configuration.defaultPRNG(0);
ShapedDataSource sds = new ShapedDataSource(prng, new long[0], count);
Strategy config = Configuration.systemStrategy().withFixedSeed(0);
BoundarySkewedDistribution<T> dist = new BoundarySkewedDistribution<T>(config, gen);
List<T> generated = new ArrayList<T>();
for (int i = 0; i != count; i++) {
generated.add((T) gen.generate(sds));
generated.add((T) dist.generate().value());
}
return generated;
}



private T generateFrom(long[] ls, Strategy config) {
ForcedDistribution<T> forced = new ForcedDistribution<>(config, actual, ls);
return forced.generate().value();
}

}

0 comments on commit 50399bd

Please sign in to comment.