Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/main/java/com/ocadotechnology/gembus/test/Arranger.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ public static <T> T some(final Class<T> type, final String... excludedFields) {
*/
public static <T> T some(final Class<T> type, final Map<String, Supplier<?>> overrides) {
CurrentEnhancedRandom.set(random);
String[] toIgnore = overrides.keySet().toArray(new String[overrides.size()]);
String[] toIgnore = overrides.keySet().stream()
.filter(field -> !ReflectionHelper.isPrimitiveField(type, field))
.toArray(String[]::new);
T result = random.nextObject(type, toIgnore);
if (type.isRecord()) {
return Rearranger.copy(result, overrides);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.github.classgraph.ClassGraph;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -47,6 +48,22 @@ class ReflectionHelper {
.collect(Collectors.toList());
}

static boolean isPrimitiveField(Class<?> clazz, String fieldName) {
if (fieldName == null || fieldName.isEmpty()) {
return false;
}
Class<?> current = clazz;
while (current != null) {
try {
Field field = current.getDeclaredField(fieldName);
return field.getType().isPrimitive();
} catch (NoSuchFieldException e) {
current = current.getSuperclass();
}
}
return false;
}

Map<Class<?>, CustomArranger<?>> createAllCustomArrangers() {
return customArrangers = arrangerConstructors.stream()
.map(constructor -> createCustomArranger(constructor))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import static com.ocadotechnology.gembus.test.Arranger.someObjects;
import static org.assertj.core.api.Assertions.assertThat;

public class ArrangerTestEnumSet {
public class ArrangerEnumSetTest {

@Test
@DisplayName("SHOULD not try to initialize file WHEN an override is delivered")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;

public class ArrangerTestNestedObjects {
public class ArrangerNestedObjectsTest {

static final String FIXED_TEXT = "text";

Expand Down Expand Up @@ -127,7 +127,7 @@ class NestedStructureArranger extends CustomArranger<NestedStructure> {
@Override
protected NestedStructure instance() {
NestedStructure nestedStructure = enhancedRandom.nextObject(NestedStructure.class, "dummyId");
nestedStructure.text = ArrangerTestNestedObjects.FIXED_TEXT;
nestedStructure.text = ArrangerNestedObjectsTest.FIXED_TEXT;
return nestedStructure;
}
}
Expand All @@ -148,7 +148,7 @@ class NestedStructure2Arranger extends CustomArranger<NestedStructure2> {
@Override
protected NestedStructure2 instance() {
NestedStructure2 nestedStructure = enhancedRandom.nextObject(NestedStructure2.class);
nestedStructure.text = ArrangerTestNestedObjects.FIXED_TEXT;
nestedStructure.text = ArrangerNestedObjectsTest.FIXED_TEXT;
return nestedStructure;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

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

public class ArrangerTestOverrideDefaults {
public class ArrangerOverrideDefaultsTest {

@AfterEach
public void cleanupProperties() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.ThrowableAssert.catchThrowable;

public class ArrangerTestOverrides {
public class ArrangerOverridesTest {
HashMap<String, Supplier<?>> overrides = new HashMap<>();

@Test
Expand Down Expand Up @@ -89,7 +89,7 @@ void should_throwException_when_supplyingWrongTypeInOverrides() {

//then
assertThat(actual).isInstanceOf(IllegalArgumentException.class)
.hasMessage("Can not set java.lang.String field com.ocadotechnology.gembus.test.ArrangerTestOverrides$ToOverride.text to java.lang.Long");
.hasMessage("Can not set java.lang.String field com.ocadotechnology.gembus.test.ArrangerOverridesTest$ToOverride.text to java.lang.Long");
}

@Test
Expand All @@ -102,7 +102,7 @@ void should_throwException_when_supplyingOverrideForNonExistingField() {

//then
assertThat(actual).isInstanceOf(IllegalArgumentException.class)
.hasMessage("Failed to override field nonexisting in class com.ocadotechnology.gembus.test.ArrangerTestOverrides$ToOverride");
.hasMessage("Failed to override field nonexisting in class com.ocadotechnology.gembus.test.ArrangerOverridesTest$ToOverride");
}

@Test
Expand Down Expand Up @@ -162,7 +162,7 @@ void should_throwException_when_supplyingOverrideForNonExistingRecordField() {

//then
assertThat(actual).isInstanceOf(IllegalArgumentException.class)
.hasMessage("Failed to override field nonexisting in class com.ocadotechnology.gembus.test.ArrangerTestOverrides$RecordToOverride");
.hasMessage("Failed to override field nonexisting in class com.ocadotechnology.gembus.test.ArrangerOverridesTest$RecordToOverride. Field not found.");
}

@Test
Expand All @@ -175,7 +175,9 @@ void should_throwException_when_supplyingWrongTypeInOverridesForRecord() {
Throwable actual = catchThrowable(() -> some(RecordToOverride.class, overrides));

//then
assertThat(actual).isInstanceOf(ObjectCreationException.class);
assertThat(actual)
.isInstanceOf(IllegalArgumentException.class)
.hasCauseInstanceOf(ObjectCreationException.class);
}

static class ToOverride {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
import java.util.Optional;
import java.util.Set;

import static com.ocadotechnology.gembus.test.Arranger.some;
import static com.ocadotechnology.gembus.test.Arranger.someSimplified;
import static com.ocadotechnology.gembus.test.Arranger.*;
import static org.assertj.core.api.Assertions.assertThat;

public class ArrangerRecordsTest {
Expand Down Expand Up @@ -105,7 +104,7 @@ void should_limitTheNestingLevel_when_inDirectlyRecursiveStructures() {

//then
assertThat(actual.value()).isNotNull();
assertThat(actual.child().child().child().child()).isEqualTo(new DirectlyNested(null,null));
assertThat(actual.child().child().child().child()).isEqualTo(new DirectlyNested(null, null));
assertThat(actual.child().child().value()).isNotNull();
}

Expand All @@ -120,9 +119,39 @@ void should_notRepeatTheSameValues_when_generatingRecords() {
assertThat(actual1.surname()).isNotEqualTo(actual2.surname());
assertThat(actual1.age()).isNotEqualTo(actual2.age());
}

@Test
void should_overridePrimitivesInRecords() {
//given
long expectedLong = someLong();
int expectedInt = someInteger();

//when
RecordWithPrimitive actual = some(RecordWithPrimitive.class, Map.of(
"big", () -> expectedLong,
"small", () -> expectedInt
));

//then
assertThat(actual.big()).isEqualTo(expectedLong);
assertThat(actual.small()).isEqualTo(expectedInt);
}

@Test
void should_overrideObjectsInRecords() {
//given
int expectedValue = someInteger();

//when
Data actual = some(Data.class, Map.of("value", () -> expectedValue));

//then
assertThat(actual.value()).isEqualTo(expectedValue);
}
}

record PersonRecord(String name, String surname, Integer age) {}
record PersonRecord(String name, String surname, Integer age) {
}

record Data(Integer value, String name, Set<String> tags, List<NestedStructure> classWithCustomArranger) {
Data {
Expand Down Expand Up @@ -159,4 +188,7 @@ protected Always42 instance() {
}

record DirectlyNested(DirectlyNested child, Integer value) {
}

record RecordWithPrimitive(long big, int small) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright © 2020 Ocado (marian.jureczko@ocado.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ocadotechnology.gembus.test;

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

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.stream.Stream;

class ReflectionHelperTest {

@ParameterizedTest(name = "{3}")
@MethodSource("allCases")
void should_detectPrimitiveField(Class<?> clazz, String fieldName, boolean expected, String description) {
//when
boolean actual = ReflectionHelper.isPrimitiveField(clazz, fieldName);

//then
assertThat(actual).isEqualTo(expected);
}

static Stream<Arguments> allCases() {
return Stream.of(
Arguments.of(PlainClass.class, "primitive", true, "SHOULD detect primitive WHEN field is primitive in plain class"),
Arguments.of(PlainClass.class, "boxed", false, "SHOULD detect non-primitive WHEN field is boxed in plain class"),
Arguments.of(PlainRecord.class, "primitive", true, "SHOULD detect primitive WHEN field is primitive in record"),
Arguments.of(PlainRecord.class, "boxed", false, "SHOULD detect non-primitive WHEN field is boxed in record"),
Arguments.of(ChildWithPrimitiveParent.class, "primitive", true, "SHOULD detect primitive WHEN field is inherited from parent"),
Arguments.of(ChildWithBoxedParent.class, "boxed", false, "SHOULD detect non-primitive WHEN field is inherited from parent"),
Arguments.of(ChildHidesWithBoxed.class, "value", false, "SHOULD detect non-primitive WHEN child hides parent field"),
Arguments.of(ChildHidesWithPrimitive.class, "value", true, "SHOULD detect primitive WHEN child hides parent field"),
Arguments.of(PlainClass.class, "missing", false, "SHOULD return false WHEN field does not exist"),
Arguments.of(PlainClass.class, "", false, "SHOULD return false WHEN field name is empty"),
Arguments.of(PlainClass.class, null, false, "SHOULD return false WHEN field name is null")
);
}

static class PlainClass {
int primitive;
Integer boxed;
}

record PlainRecord(int primitive, Integer boxed) {
}

static class ParentWithPrimitive {
int primitive;
}

static class ChildWithPrimitiveParent extends ParentWithPrimitive {
}

static class ParentWithBoxed {
Integer boxed;
}

static class ChildWithBoxedParent extends ParentWithBoxed {
}

static class ParentPrimitiveValue {
int value;
}

static class ChildHidesWithBoxed extends ParentPrimitiveValue {
String value;
}

static class ParentBoxedValue {
String value;
}

static class ChildHidesWithPrimitive extends ParentBoxedValue {
int value;
}
}