Skip to content

Commit

Permalink
resolving merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
mjureczko committed Oct 28, 2024
1 parent 565b48f commit e00f72d
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 140 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,13 +318,11 @@ Eventually, we may end up with something like this:
class ShopFixture {
Repository repo;
public void shopWithNineProductsAndFourCustomers() {
Stream.generate(() -> Arranger.some(Product.class))
.limit(9)
.forEach(p -> repo.save(p));
Arranger.someObjects(Product.class, 9)
.forEach(p -> repo.save(p));

Stream.generate(() -> Arranger.some(Customer.class))
.limit(4)
.forEach(p -> repo.save(p));
Arranger.someObjects(Customer.class, 4)
.forEach(p -> repo.save(p));
}
}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,11 @@ EnhancedRandom simplifiedRandom() {
return randomWithArrangers(simplifiedArrangers, new EnhancedRandom.Builder(ArrangersConfigurer::getEasyRandomSimplifiedParameters));
}

EnhancedRandom randomForGivenConfiguration(Class<?> type, boolean withoutGivenType, Map<Class<?>, CustomArranger<?>> arrangers, Supplier<EasyRandomParameters> parametersSupplier) {
EnhancedRandom randomForGivenConfiguration(Class<?> type, Map<Class<?>, CustomArranger<?>> arrangers, Supplier<EasyRandomParameters> parametersSupplier) {
EnhancedRandom.Builder randomBuilder = new EnhancedRandom.Builder(parametersSupplier);
long seed = SeedHelper.calculateSeed();
if (withoutGivenType && arrangers.get(type) != null) {
CustomArranger<?> arrangerToUpdate = arrangers.get(type);
if (arrangerToUpdate != null) {
seed = SeedHelper.customArrangerTypeSpecificSeedRespectingRandomSeedSetting(type);
arrangers = withoutGivenType(arrangers, type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,9 @@
public abstract class CustomArranger<T> {

protected EnhancedRandom enhancedRandom = null;
protected final Class<T> type;
protected final Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

protected CustomArranger() {
this.type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
initEnhancedRandom();
}

protected CustomArranger(Class<T> type) {
this.type = type;
initEnhancedRandom();
}

private void initEnhancedRandom() {
if (ArrangersConfigurer.defaultInitialized.get()) {
enhancedRandom = ArrangersConfigurer.instance().defaultRandom();
} else {
Expand Down
94 changes: 9 additions & 85 deletions src/main/java/com/ocadotechnology/gembus/test/EnhancedRandom.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,15 @@
*/
package com.ocadotechnology.gembus.test;

import com.ocadotechnology.gembus.test.experimental.SealedInterfaceArranger;
import org.jeasy.random.EasyRandom;
import org.jeasy.random.EasyRandomParameters;
import org.jeasy.random.api.Randomizer;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.function.Function.identity;

/**
* Class for random object generator.
*/
Expand Down Expand Up @@ -96,90 +84,26 @@ public <T> Stream<T> objects(final Class<T> type, final int amount, final String
}

private <T> EasyRandom selectEasyRandomWithRespectToExclusion(Class<T> type, String[] excludedFields) {
if (newEasyRandomWithCustomRandomizersOrFieldExclusionConfigIsRequired(type, excludedFields)) {
return createEasyRandomWithCustomRandomizersAndExclusions(type, excludedFields);
if (newEasyRandomWithFieldExclusionConfigIsRequired(type, excludedFields)) {
return createEasyRandomWithExclusions(type, excludedFields);
}
return easyRandom;
}

private <T> boolean newEasyRandomWithCustomRandomizersOrFieldExclusionConfigIsRequired(Class<T> type, String[] excludedFields) {
private <T> boolean newEasyRandomWithFieldExclusionConfigIsRequired(Class<T> type, String[] excludedFields) {
/* There is a logical inconsistency in using a custom arranger and field exclusion for the same type - the
* exclusion can be configured in the custom arranger. Technically, creating an arranger with exclusion disables
* the custom arranger for the type that is being instantiated. */
return !arrangers.containsKey(type) && (excludedFields.length != 0 || isSealedInterface(type) || !nestedSealedInterfaceFields(type).isEmpty());
return !arrangers.containsKey(type) && excludedFields.length != 0;
}

private <T> EasyRandom createEasyRandomWithCustomRandomizersAndExclusions(Class<T> type, String[] excludedFields) {
private <T> EasyRandom createEasyRandomWithExclusions(Class<T> type, String[] excludedFields) {
Set<String> fields = new HashSet<>(Arrays.asList(excludedFields));
var forSealedInterfaces = createCustomArrangersForSealedInterfaces(type, fields);
Set<String> cacheKey = getCacheKey(fields, forSealedInterfaces.keySet());
cache.computeIfAbsent(cacheKey, key -> {
HashMap<Class<?>, CustomArranger<?>> enhancedArrangers = new HashMap<>(arrangers);
enhancedArrangers.putAll(forSealedInterfaces);
EnhancedRandom er = ArrangersConfigurer.instance()
.randomForGivenConfiguration(type, !forSealedInterfaces.containsKey(type), enhancedArrangers, () -> addExclusionToParameters(fields));
cache.computeIfAbsent(fields, key -> {
EnhancedRandom er = ArrangersConfigurer.instance().randomForGivenConfiguration(type, arrangers, () -> addExclusionToParameters(fields));
return er.easyRandom;
});
return cache.get(cacheKey);
}

private Set<String> getCacheKey(Set<String> fields, Set<Class<?>> sealedInterfaces) {
Set<String> cacheKey = new HashSet<>(fields);
cacheKey.addAll(sealedInterfaces.stream().map(Class::getName).toList());
return cacheKey;
}

private <T> Map<Class<?>, CustomArranger<?>> createCustomArrangersForSealedInterfaces(Class<T> type, Set<String> excludedFields) {
Map<Class<?>, CustomArranger<?>> sealedInterfaceArrangers = new HashMap<>();
if (isSealedInterface(type)) {
sealedInterfaceArrangers.put(type, new SealedInterfaceArranger<T>(type));
}
sealedInterfaceArrangers.putAll(nestedSealedInterfaceFields(type)
.entrySet()
.stream()
.filter(entry -> !excludedFields.contains(entry.getKey()))
.map(Map.Entry::getValue)
.collect(Collectors.toMap(identity(), SealedInterfaceArranger::new)));
return sealedInterfaceArrangers;
}

private <T> Map<String, Class<?>> nestedSealedInterfaceFields(Class<T> type) {
return allNestedFields(new HashMap<>(), type)
.entrySet()
.stream()
.filter(entry -> isSealedInterface(entry.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

private Map<String, Class<?>> allNestedFields(Map<String, Class<?>> acc, Class<?> clazz) {
if (clazz == null || clazz.isPrimitive()) {
return Map.of();
}
if (isSealedInterface(clazz)) {
for (Class<?> permittedSubclasses : clazz.getPermittedSubclasses()) {
acc.putAll(allNestedFields(acc, permittedSubclasses));
}
}
for (Field field : clazz.getDeclaredFields()) {
if (!acc.containsKey(field.getName())) {
if (field.getGenericType() instanceof ParameterizedType parameterizedType) {
for (var genericType : parameterizedType.getActualTypeArguments()) {
if(genericType instanceof Class<?> genericTypeClass) {
acc.put(field.getName(), genericTypeClass);
acc.putAll(allNestedFields(acc, genericTypeClass));
}
}
} else {
acc.put(field.getName(), field.getType());
acc.putAll(allNestedFields(acc, field.getType()));
}
}
}
return acc;
}

private static boolean isSealedInterface(Class<?> type) {
return type.isSealed() && type.isInterface();
return cache.get(fields);
}

private EasyRandomParameters addExclusionToParameters(Set<String> fields) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package com.ocadotechnology.gembus.test;

import com.ocadotechnology.gembus.test.experimental.SealedInterfaceArranger;
import io.github.classgraph.ClassGraph;

import java.lang.reflect.Constructor;
Expand All @@ -40,7 +39,6 @@ class ReflectionHelper {
.loadClasses(CustomArranger.class, true)
.stream()
.filter(clazz -> isNotAbstract(clazz))
.filter(clazz -> !SealedInterfaceArranger.class.equals(clazz))
.map(clazz -> extractConstructor(clazz))
.filter(constructor -> constructor.isPresent())
.map(constructor -> constructor.get())
Expand Down

This file was deleted.

0 comments on commit e00f72d

Please sign in to comment.