diff --git a/fixture-monkey-kotlin/src/main/kotlin/com/navercorp/fixturemonkey/kotlin/FixtureMonkeyExtensions.kt b/fixture-monkey-kotlin/src/main/kotlin/com/navercorp/fixturemonkey/kotlin/FixtureMonkeyExtensions.kt index 3b82dc3c4..e1f643425 100644 --- a/fixture-monkey-kotlin/src/main/kotlin/com/navercorp/fixturemonkey/kotlin/FixtureMonkeyExtensions.kt +++ b/fixture-monkey-kotlin/src/main/kotlin/com/navercorp/fixturemonkey/kotlin/FixtureMonkeyExtensions.kt @@ -20,6 +20,8 @@ package com.navercorp.fixturemonkey.kotlin import com.navercorp.fixturemonkey.ArbitraryBuilder import com.navercorp.fixturemonkey.FixtureMonkey +import com.navercorp.fixturemonkey.api.arbitrary.CombinableArbitrary +import com.navercorp.fixturemonkey.api.experimental.TypedPropertySelector import com.navercorp.fixturemonkey.api.instantiator.Instantiator import com.navercorp.fixturemonkey.api.property.PropertySelector import com.navercorp.fixturemonkey.api.type.TypeReference @@ -229,6 +231,11 @@ class KotlinTypeDefaultArbitraryBuilder( ): KotlinTypeDefaultArbitraryBuilder = this.apply { delegate.instantiate(type, instantiator) } + override fun customizeProperty( + propertySelector: TypedPropertySelector, + combinableArbitraryCustomizer: Function, CombinableArbitrary> + ): ArbitraryBuilder = this.apply { delegate.customizeProperty(propertySelector, combinableArbitraryCustomizer) } + override fun build(): Arbitrary = delegate.build() override fun sample(): T = delegate.sample() diff --git a/fixture-monkey-tests/kotlin-tests/src/test/kotlin/com/navercorp/fixturemonkey/tests/kotlin/KotlinTest.kt b/fixture-monkey-tests/kotlin-tests/src/test/kotlin/com/navercorp/fixturemonkey/tests/kotlin/KotlinTest.kt index d5ad0cb1f..c66733c55 100644 --- a/fixture-monkey-tests/kotlin-tests/src/test/kotlin/com/navercorp/fixturemonkey/tests/kotlin/KotlinTest.kt +++ b/fixture-monkey-tests/kotlin-tests/src/test/kotlin/com/navercorp/fixturemonkey/tests/kotlin/KotlinTest.kt @@ -22,6 +22,7 @@ import com.navercorp.fixturemonkey.FixtureMonkey import com.navercorp.fixturemonkey.api.arbitrary.CombinableArbitrary import com.navercorp.fixturemonkey.api.experimental.JavaGetterMethodPropertySelector.javaGetter import com.navercorp.fixturemonkey.api.experimental.TypedExpressionGenerator.typedRoot +import com.navercorp.fixturemonkey.api.experimental.TypedExpressionGenerator.typedString import com.navercorp.fixturemonkey.api.introspector.AnonymousArbitraryIntrospector import com.navercorp.fixturemonkey.api.introspector.ArbitraryIntrospectorResult import com.navercorp.fixturemonkey.api.introspector.BeanArbitraryIntrospector @@ -894,6 +895,46 @@ class KotlinTest { then(actual).hasSizeLessThan(5) } + @RepeatedTest(TEST_COUNT) + fun customizePropertyAfterSet() { + // given + class StringValue(val value: String) + + val expected = "abc" + + // when + val actual = SUT.giveMeKotlinBuilder() + .setExp(StringValue::value, "abcdef") + .customizeProperty(typedString("value")) { + it.map { str -> str.substring(0..2) } + } + .sample() + .value + + //then + then(actual).isEqualTo(expected) + } + + @RepeatedTest(TEST_COUNT) + fun customizePropertyIgnoredIfSet() { + // given + class StringValue(val value: String) + + val expected = "fixed" + + // when + val actual = SUT.giveMeKotlinBuilder() + .customizeProperty(typedString("value")) { + it.filter { value -> value.length > 5 } + } + .setExp(StringValue::value, expected) + .sample() + .value + + //then + then(actual).isEqualTo(expected) + } + companion object { private val SUT: FixtureMonkey = FixtureMonkey.builder() .plugin(KotlinPlugin()) diff --git a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/ArbitraryBuilder.java b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/ArbitraryBuilder.java index 595ec3804..54a349d1e 100644 --- a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/ArbitraryBuilder.java +++ b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/ArbitraryBuilder.java @@ -36,6 +36,8 @@ import net.jqwik.api.Combinators.F3; import net.jqwik.api.Combinators.F4; +import com.navercorp.fixturemonkey.api.arbitrary.CombinableArbitrary; +import com.navercorp.fixturemonkey.api.experimental.TypedPropertySelector; import com.navercorp.fixturemonkey.api.instantiator.Instantiator; import com.navercorp.fixturemonkey.api.property.PropertySelector; import com.navercorp.fixturemonkey.api.type.TypeReference; @@ -554,4 +556,10 @@ ArbitraryBuilder zipWith( ArbitraryBuilder instantiate(Class type, Instantiator instantiator); ArbitraryBuilder instantiate(TypeReference type, Instantiator instantiator); + + @API(since = "1.0.9", status = Status.MAINTAINED) + ArbitraryBuilder customizeProperty( + TypedPropertySelector propertySelector, + Function, CombinableArbitrary> combinableArbitraryCustomizer + ); } diff --git a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/builder/JavaTypeDefaultTypeArbitraryBuilder.java b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/builder/JavaTypeDefaultTypeArbitraryBuilder.java index 67a72bec6..8a67ad8db 100644 --- a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/builder/JavaTypeDefaultTypeArbitraryBuilder.java +++ b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/builder/JavaTypeDefaultTypeArbitraryBuilder.java @@ -38,6 +38,8 @@ import com.navercorp.fixturemonkey.ArbitraryBuilder; import com.navercorp.fixturemonkey.JavaTypeArbitraryBuilder; +import com.navercorp.fixturemonkey.api.arbitrary.CombinableArbitrary; +import com.navercorp.fixturemonkey.api.experimental.TypedPropertySelector; import com.navercorp.fixturemonkey.api.instantiator.Instantiator; import com.navercorp.fixturemonkey.api.property.PropertySelector; import com.navercorp.fixturemonkey.api.type.TypeReference; @@ -335,4 +337,12 @@ public JavaTypeArbitraryBuilder instantiate(TypeReference type, Instantiat delegate.instantiate(type, instantiator); return this; } + + @Override + public ArbitraryBuilder customizeProperty( + TypedPropertySelector propertySelector, + Function, CombinableArbitrary> combinableArbitraryCustomizer + ) { + return delegate.customizeProperty(propertySelector, combinableArbitraryCustomizer); + } } diff --git a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/customizer/NodeCustomizerManipulator.java b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/customizer/NodeCustomizerManipulator.java index 7959ce7da..d9927cb2a 100644 --- a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/customizer/NodeCustomizerManipulator.java +++ b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/customizer/NodeCustomizerManipulator.java @@ -39,6 +39,12 @@ public NodeCustomizerManipulator( @SuppressWarnings({"rawtypes", "unchecked"}) @Override public void manipulate(ObjectNode objectNode) { - objectNode.addArbitraryCustomizer((Function)arbitraryCustomizer); + if (objectNode.getArbitrary() != null) { + CombinableArbitrary customized = arbitraryCustomizer.apply( + (CombinableArbitrary)objectNode.getArbitrary()); + objectNode.setArbitrary(customized); + } else { + objectNode.addGeneratedArbitraryCustomizer((Function)arbitraryCustomizer); + } } } diff --git a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/experimental/ExperimentalArbitraryBuilder.java b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/experimental/ExperimentalArbitraryBuilder.java index 4bda3fd81..0affd99ea 100644 --- a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/experimental/ExperimentalArbitraryBuilder.java +++ b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/experimental/ExperimentalArbitraryBuilder.java @@ -18,20 +18,11 @@ package com.navercorp.fixturemonkey.experimental; -import java.util.function.Function; - import org.apiguardian.api.API; import org.apiguardian.api.API.Status; import com.navercorp.fixturemonkey.ArbitraryBuilder; -import com.navercorp.fixturemonkey.api.arbitrary.CombinableArbitrary; -import com.navercorp.fixturemonkey.api.experimental.TypedPropertySelector; @API(since = "0.6.12", status = Status.MAINTAINED) public interface ExperimentalArbitraryBuilder extends ArbitraryBuilder { - @API(since = "1.0.9", status = Status.EXPERIMENTAL) - ArbitraryBuilder customizeProperty( - TypedPropertySelector propertySelector, - Function, CombinableArbitrary> combinableArbitraryCustomizer - ); } diff --git a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/tree/ObjectNode.java b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/tree/ObjectNode.java index 9979d7cf4..21e552b50 100644 --- a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/tree/ObjectNode.java +++ b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/tree/ObjectNode.java @@ -160,11 +160,13 @@ public List getArbitraryFilters() { return arbitraryFilters; } - public void addArbitraryCustomizer(Function, CombinableArbitrary> arbitraryCustomizer) { + public void addGeneratedArbitraryCustomizer( + Function, CombinableArbitrary> arbitraryCustomizer + ) { this.arbitraryCustomizers.add(arbitraryCustomizer); } - public List, CombinableArbitrary>> getArbitraryCustomizers() { + public List, CombinableArbitrary>> getGeneratedArbitraryCustomizers() { return arbitraryCustomizers; } diff --git a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/tree/ObjectTree.java b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/tree/ObjectTree.java index 33c5d6bd3..4b7147e42 100644 --- a/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/tree/ObjectTree.java +++ b/fixture-monkey/src/main/java/com/navercorp/fixturemonkey/tree/ObjectTree.java @@ -152,6 +152,14 @@ private CombinableArbitrary generateIntrospected( ); generated = getArbitraryGenerator(node.getResolvedProperty(), arbitraryIntrospector) .generate(childArbitraryGeneratorContext); + + List, CombinableArbitrary>> customizers = + node.getGeneratedArbitraryCustomizers(); + + for (Function, CombinableArbitrary> customizer : customizers) { + generated = customizer.apply(generated); + } + if (node.cacheable()) { monkeyContext.putCachedArbitrary( node.getProperty(), @@ -161,13 +169,6 @@ private CombinableArbitrary generateIntrospected( } } - List, CombinableArbitrary>> arbitraryCustomizers = - node.getArbitraryCustomizers(); - - for (Function, CombinableArbitrary> arbitraryCustomizer : arbitraryCustomizers) { - generated = arbitraryCustomizer.apply(generated); - } - List arbitraryFilters = node.getArbitraryFilters(); for (Predicate predicate : arbitraryFilters) { generated = generated.filter(fixtureMonkeyOptions.getGenerateMaxTries(), predicate);