Skip to content

Commit

Permalink
Add strategy interface for field/type exclusion
Browse files Browse the repository at this point in the history
  • Loading branch information
fmbenhassine committed Mar 14, 2019
1 parent a213600 commit 8ae7150
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 7 deletions.
Expand Up @@ -57,7 +57,7 @@ public class EasyRandom extends Random {

private final ObjectFactory objectFactory;

private final ExclusionChecker exclusionChecker;
private final ExclusionPolicy exclusionPolicy;

public EasyRandom() {
this(new EasyRandomParameters());
Expand All @@ -76,7 +76,7 @@ public EasyRandom(final EasyRandomParameters easyRandomParameters) {
enumRandomizersByType = new ConcurrentHashMap<>();
fieldPopulator = new FieldPopulator(this, randomizerProvider, arrayPopulator, collectionPopulator, mapPopulator);
fieldPopulator.setScanClasspathForConcreteTypes(easyRandomParameters.isScanClasspathForConcreteTypes());
exclusionChecker = new ExclusionChecker();
exclusionPolicy = easyRandomParameters.getExclusionPolicy();
this.parameters = easyRandomParameters;
}

Expand Down Expand Up @@ -110,7 +110,7 @@ public <T> Stream<T> objects(final Class<T> type, final int streamSize) {
}

<T> T doPopulateBean(final Class<T> type, final RandomizationContext context) {
if (exclusionChecker.shouldBeExcluded(type, context)) {
if (exclusionPolicy.shouldBeExcluded(type, context)) {
return null;
}

Expand Down Expand Up @@ -192,7 +192,7 @@ private <T> void populateFields(final List<Field> fields, final T result, final
}

private <T> void populateField(final Field field, final T result, final RandomizationContext context) throws IllegalAccessException {
if (exclusionChecker.shouldBeExcluded(field, context)) {
if (exclusionPolicy.shouldBeExcluded(field, context)) {
return;
}
if (!parameters.isOverrideDefaultInitialization() && getFieldValue(result, field) != null && !isPrimitiveFieldWithDefaultValue(result, field)) {
Expand Down
Expand Up @@ -23,6 +23,7 @@
*/
package org.jeasy.random;

import org.jeasy.random.api.ExclusionPolicy;
import org.jeasy.random.api.Randomizer;
import org.jeasy.random.api.RandomizerRegistry;
import org.jeasy.random.randomizers.registry.CustomRandomizerRegistry;
Expand Down Expand Up @@ -104,6 +105,9 @@ public class EasyRandomParameters {
private Range<Integer> stringLengthRange;
private Range<LocalDate> dateRange;
private Range<LocalTime> timeRange;
private ExclusionPolicy exclusionPolicy;

// internal params
private CustomRandomizerRegistry customRandomizerRegistry;
private ExclusionRandomizerRegistry exclusionRandomizerRegistry;
private Set<RandomizerRegistry> userRegistries;
Expand All @@ -127,6 +131,7 @@ public EasyRandomParameters() {
userRegistries = new LinkedHashSet<>();
fieldExclusionPredicates = new HashSet<>();
typeExclusionPredicates = new HashSet<>();
exclusionPolicy = new ExclusionChecker();
}

public Range<Integer> getCollectionSizeRange() {
Expand Down Expand Up @@ -213,6 +218,13 @@ public void setIgnoreAbstractTypes(boolean ignoreAbstractTypes) {
this.ignoreAbstractTypes = ignoreAbstractTypes;
}

public ExclusionPolicy getExclusionPolicy() {
return exclusionPolicy;
}
public void setExclusionPolicy(ExclusionPolicy exclusionPolicy) {
this.exclusionPolicy = exclusionPolicy;
}

public Set<Predicate<Field>> getFieldExclusionPredicates() {
return fieldExclusionPredicates;
}
Expand Down Expand Up @@ -296,6 +308,18 @@ public EasyRandomParameters excludeType(Predicate<Class<?>> predicate) {
return this;
}

/**
* Provide a custom exclusion policy.
*
* @param exclusionPolicy to use
* @return the current {@link EasyRandomParameters} instance for method chaining
*/
public EasyRandomParameters exclusionPolicy(ExclusionPolicy exclusionPolicy) {
Objects.requireNonNull(exclusionPolicy, "Exclusion policy must not be null");
this.exclusionPolicy = exclusionPolicy;
return this;
}

/**
* Set the initial random seed.
*
Expand Down
Expand Up @@ -23,6 +23,7 @@
*/
package org.jeasy.random;

import org.jeasy.random.api.ExclusionPolicy;
import org.jeasy.random.api.RandomizerContext;

import java.lang.reflect.Field;
Expand All @@ -37,7 +38,7 @@
*
* @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
*/
class ExclusionChecker {
class ExclusionChecker implements ExclusionPolicy {

/**
* Given the current randomization context, should the field be excluded from being populated ?
Expand All @@ -46,7 +47,7 @@ class ExclusionChecker {
* @param context the current randomization context
* @return true if the field should be excluded, false otherwise
*/
boolean shouldBeExcluded(final Field field, final RandomizerContext context) {
public boolean shouldBeExcluded(final Field field, final RandomizerContext context) {
if (isStatic(field)) {
return true;
}
Expand All @@ -66,7 +67,7 @@ boolean shouldBeExcluded(final Field field, final RandomizerContext context) {
* @param context the current randomization context
* @return true if the type should be excluded, false otherwise
*/
boolean shouldBeExcluded(final Class<?> type, final RandomizerContext context) {
public boolean shouldBeExcluded(final Class<?> type, final RandomizerContext context) {
Set<Predicate<Class<?>>> typeExclusionPredicates = context.getParameters().getTypeExclusionPredicates();
for (Predicate<Class<?>> typeExclusionPredicate : typeExclusionPredicates) {
if (typeExclusionPredicate.test(type)) {
Expand Down
@@ -0,0 +1,54 @@
/**
* The MIT License
*
* Copyright (c) 2019, Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jeasy.random.api;

import java.lang.reflect.Field;

/**
* Strategy interface for field/type exclusion.
*
* @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
* @since 4.0
*/
public interface ExclusionPolicy {

/**
* Given the current randomization context, should the field be excluded from being randomized?
*
* @param field the field to check
* @param context the current randomization context
* @return true if the field should be excluded, false otherwise
*/
boolean shouldBeExcluded(final Field field, final RandomizerContext context);

/**
* Given the current randomization context, should the type be excluded from being randomized?
*
* @param type the type to check
* @param context the current randomization context
* @return true if the type should be excluded, false otherwise
*/
boolean shouldBeExcluded(final Class<?> type, final RandomizerContext context);

}
@@ -0,0 +1,69 @@
/**
* The MIT License
*
* Copyright (c) 2019, Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jeasy.random.parameters;

import org.jeasy.random.EasyRandom;
import org.jeasy.random.EasyRandomParameters;
import org.jeasy.random.api.ExclusionPolicy;
import org.jeasy.random.api.RandomizerContext;
import org.jeasy.random.beans.Address;
import org.jeasy.random.beans.Person;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Field;

import static org.assertj.core.api.Assertions.assertThat;

public class ExclusionPolicyTests {

@Test
void testCustomExclusionPolicy() {
// given
EasyRandomParameters parameters = new EasyRandomParameters()
.exclusionPolicy(new ExclusionPolicy() {
@Override
public boolean shouldBeExcluded(Field field, RandomizerContext context) {
return field.getName().equals("birthDate");
}

@Override
public boolean shouldBeExcluded(Class<?> type, RandomizerContext context) {
return type.isAssignableFrom(Address.class);
}
});
EasyRandom easyRandom = new EasyRandom(parameters);

// when
Person person = easyRandom.nextObject(Person.class);

// then
assertThat(person).isNotNull();
assertThat(person.getName()).isNotNull();
assertThat(person.getEmail()).isNotNull();
assertThat(person.getPhoneNumber()).isNotNull();

assertThat(person.getBirthDate()).isNull();
assertThat(person.getAddress()).isNull();
}
}

0 comments on commit 8ae7150

Please sign in to comment.