From ec5c63058923c0b9e67772bf0a42dba18e97f403 Mon Sep 17 00:00:00 2001 From: mhyeon-lee Date: Sat, 2 Oct 2021 18:56:02 +0900 Subject: [PATCH] Fix ArbitraryBuilder generated Arbitrary not affected Validator any with action --- .../arbitrary/ArbitraryValue.java | 251 +++++++++++++----- .../fixturemonkey/test/FixtureMonkeyTest.java | 45 ++++ 2 files changed, 230 insertions(+), 66 deletions(-) diff --git a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/arbitrary/ArbitraryValue.java b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/arbitrary/ArbitraryValue.java index d8a95fc30..a7eac0997 100644 --- a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/arbitrary/ArbitraryValue.java +++ b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/arbitrary/ArbitraryValue.java @@ -74,13 +74,21 @@ public ArbitraryValue( } @Override - public RandomGenerator generator(int genSize) { - return getArbitrary().generator(genSize); + public synchronized RandomGenerator generator(int genSize) { + try { + return getArbitrary().generator(genSize); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary asGeneric() { - return getArbitrary().asGeneric(); + public synchronized Arbitrary asGeneric() { + try { + return getArbitrary().asGeneric(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override @@ -89,107 +97,180 @@ public boolean isUnique() { } @Override - public Optional> exhaustive() { - return getArbitrary().exhaustive(); + public synchronized Optional> exhaustive() { + try { + return getArbitrary().exhaustive(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Optional> exhaustive(long maxNumberOfSamples) { - return getArbitrary().exhaustive(maxNumberOfSamples); + public synchronized Optional> exhaustive(long maxNumberOfSamples) { + try { + return getArbitrary().exhaustive(maxNumberOfSamples); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public EdgeCases edgeCases() { - return getArbitrary().edgeCases(); + public synchronized EdgeCases edgeCases() { + try { + return getArbitrary().edgeCases(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Optional> allValues() { - return getArbitrary().allValues(); + public synchronized Optional> allValues() { + try { + return getArbitrary().allValues(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public void forEachValue(Consumer action) { - getArbitrary().forEachValue(action); + public synchronized void forEachValue(Consumer action) { + try { + getArbitrary().forEachValue(action); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary filter(Predicate filterPredicate) { - return getArbitrary().filter(filterPredicate); + public synchronized Arbitrary filter(Predicate filterPredicate) { + try { + return getArbitrary().filter(filterPredicate); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary map(Function mapper) { - return getArbitrary().map(mapper); + public synchronized Arbitrary map(Function mapper) { + try { + return getArbitrary().map(mapper); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary flatMap(Function> mapper) { - return getArbitrary().flatMap(mapper); + public synchronized Arbitrary flatMap(Function> mapper) { + try { + return getArbitrary().flatMap(mapper); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary injectNull(double nullProbability) { - return getArbitrary().injectNull(nullProbability); + public synchronized Arbitrary injectNull(double nullProbability) { + try { + return getArbitrary().injectNull(nullProbability); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary unique() { - return getArbitrary().unique(); + public synchronized Arbitrary unique() { + try { + return getArbitrary().unique(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary fixGenSize(int genSize) { - return getArbitrary().fixGenSize(genSize); + public synchronized Arbitrary fixGenSize(int genSize) { + try { + return getArbitrary().fixGenSize(genSize); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public ListArbitrary list() { - return getArbitrary().list(); + public synchronized ListArbitrary list() { + try { + return getArbitrary().list(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public SetArbitrary set() { - return getArbitrary().set(); + public synchronized SetArbitrary set() { + try { + return getArbitrary().set(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public StreamArbitrary stream() { - return getArbitrary().stream(); + public synchronized StreamArbitrary stream() { + try { + return getArbitrary().stream(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public IteratorArbitrary iterator() { - return getArbitrary().iterator(); + public synchronized IteratorArbitrary iterator() { + try { + return getArbitrary().iterator(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public StreamableArbitrary array(Class arrayClass) { - return getArbitrary().array(arrayClass); + public synchronized StreamableArbitrary array(Class arrayClass) { + try { + return getArbitrary().array(arrayClass); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary> optional() { - return getArbitrary().optional(); + public synchronized Arbitrary> optional() { + try { + return getArbitrary().optional(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary> collect(Predicate> until) { - return getArbitrary().collect(until); + public synchronized Arbitrary> collect(Predicate> until) { + try { + return getArbitrary().collect(until); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Stream sampleStream() { - return getArbitrary().sampleStream(); + public synchronized Stream sampleStream() { + try { + return getArbitrary().sampleStream(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } - @SuppressWarnings("unchecked") @Override - public T sample() { + public synchronized T sample() { try { - return getArbitrary() - .filter((Predicate)this.validateFilter(validOnly)) - .sample(); + return getArbitrary().sample(); } catch (TooManyFilterMissesException ex) { StringBuilder builder = new StringBuilder(); this.violations.values().forEach(violation -> builder @@ -209,53 +290,91 @@ public T sample() { } @Override - public Arbitrary injectDuplicates(double duplicateProbability) { - return getArbitrary().injectDuplicates(duplicateProbability); + public synchronized Arbitrary injectDuplicates(double duplicateProbability) { + try { + return getArbitrary().injectDuplicates(duplicateProbability); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary> tuple1() { - return getArbitrary().tuple1(); + public synchronized Arbitrary> tuple1() { + try { + return getArbitrary().tuple1(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary> tuple2() { - return getArbitrary().tuple2(); + public synchronized Arbitrary> tuple2() { + try { + return getArbitrary().tuple2(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary> tuple3() { - return getArbitrary().tuple3(); + public synchronized Arbitrary> tuple3() { + try { + return getArbitrary().tuple3(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary> tuple4() { - return getArbitrary().tuple4(); + public synchronized Arbitrary> tuple4() { + try { + return getArbitrary().tuple4(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary> tuple5() { - return getArbitrary().tuple5(); + public synchronized Arbitrary> tuple5() { + try { + return getArbitrary().tuple5(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary ignoreException(Class exceptionType) { - return getArbitrary().ignoreException(exceptionType); + public synchronized Arbitrary ignoreException(Class exceptionType) { + try { + return getArbitrary().ignoreException(exceptionType); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary dontShrink() { - return getArbitrary().dontShrink(); + public synchronized Arbitrary dontShrink() { + try { + return getArbitrary().dontShrink(); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } @Override - public Arbitrary edgeCases(Consumer> configurator) { - return getArbitrary().edgeCases(configurator); + public synchronized Arbitrary edgeCases(Consumer> configurator) { + try { + return getArbitrary().edgeCases(configurator); + } finally { + this.arbitrary = null; // in order to getting new value whenever sampling, set arbitrary as null + } } + @SuppressWarnings("unchecked") private synchronized Arbitrary getArbitrary() { if (this.arbitrary == null) { - this.arbitrary = generateArbitrary.get(); + this.arbitrary = generateArbitrary.get() + .filter((Predicate)this.validateFilter(validOnly)); } return this.arbitrary; } diff --git a/fixture-monkey/src/test/java/com/navercorp/fixturemonkey/test/FixtureMonkeyTest.java b/fixture-monkey/src/test/java/com/navercorp/fixturemonkey/test/FixtureMonkeyTest.java index 5704b5061..a4623bf79 100644 --- a/fixture-monkey/src/test/java/com/navercorp/fixturemonkey/test/FixtureMonkeyTest.java +++ b/fixture-monkey/src/test/java/com/navercorp/fixturemonkey/test/FixtureMonkeyTest.java @@ -18,6 +18,7 @@ package com.navercorp.fixturemonkey.test; +import static java.util.stream.Collectors.toList; import static org.assertj.core.api.BDDAssertions.then; import static org.assertj.core.api.BDDAssertions.thenThrownBy; @@ -42,7 +43,9 @@ import org.junit.platform.commons.util.StringUtils; import net.jqwik.api.Arbitrary; +import net.jqwik.api.Example; import net.jqwik.api.Property; +import net.jqwik.api.TooManyFilterMissesException; import lombok.AllArgsConstructor; import lombok.Builder; @@ -284,6 +287,48 @@ void giveMeOptional() { then(actual).isNotNull(); } + @Property + void giveMeArbitraryThenSample() { + // given + Arbitrary sut = this.sut.giveMeArbitrary(StringWithNotBlankWrapperClass.class); + + // when + StringWithNotBlankWrapperClass actual = sut.sample(); + + then(actual.getValue()).isNotBlank(); + } + + @Property + void giveMeArbitraryThenSampleStream() { + // given + Arbitrary sut = this.sut.giveMeArbitrary(StringWithNotBlankWrapperClass.class); + + // when + List actual = sut.sampleStream().limit(5).collect(toList()); + + actual.forEach(it -> then(it.getValue()).isNotBlank()); + } + + @Example + void giveMeBuilderInvalidThenSampleTooManyFilterMissesException() { + Arbitrary sut = this.sut.giveMeBuilder(StringWithNotBlankWrapperClass.class) + .set("value", "") + .build(); + + thenThrownBy(sut::sample) + .isExactlyInstanceOf(TooManyFilterMissesException.class); + } + + @Example + void giveMeBuilderInvalidThenSampleStreamTooManyFilterMissesException() { + Arbitrary sut = this.sut.giveMeBuilder(StringWithNotBlankWrapperClass.class) + .set("value", "") + .build(); + + thenThrownBy(() -> sut.sampleStream().limit(5).collect(toList())) + .isExactlyInstanceOf(TooManyFilterMissesException.class); + } + @Property void setAfterBuildNotAffected() { // given