Skip to content

Commit

Permalink
Add TypeParameterProperty and ContainerElementProperty (#1114)
Browse files Browse the repository at this point in the history
  • Loading branch information
seongahjo authored Dec 10, 2024
1 parent c87f4f2 commit 7c6b910
Show file tree
Hide file tree
Showing 22 changed files with 536 additions and 216 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
import org.apiguardian.api.API;
import org.apiguardian.api.API.Status;

import com.navercorp.fixturemonkey.api.property.ElementProperty;
import com.navercorp.fixturemonkey.api.property.DefaultContainerElementProperty;
import com.navercorp.fixturemonkey.api.property.Property;
import com.navercorp.fixturemonkey.api.property.TypeParameterProperty;
import com.navercorp.fixturemonkey.api.type.Types;

@API(since = "0.4.0", status = Status.MAINTAINED)
Expand All @@ -45,9 +46,9 @@ public ContainerProperty generate(ContainerPropertyGeneratorContext context) {
List<Property> childProperties = new ArrayList<>();
for (int sequence = 0; sequence < size; sequence++) {
childProperties.add(
new ElementProperty(
new DefaultContainerElementProperty(
property,
elementType,
new TypeParameterProperty(elementType),
sequence,
sequence
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,15 @@
import org.apiguardian.api.API;
import org.apiguardian.api.API.Status;

import com.navercorp.fixturemonkey.api.property.ElementProperty;
import com.navercorp.fixturemonkey.api.property.DefaultContainerElementProperty;
import com.navercorp.fixturemonkey.api.property.Property;
import com.navercorp.fixturemonkey.api.type.TypeReference;
import com.navercorp.fixturemonkey.api.property.TypeParameterProperty;
import com.navercorp.fixturemonkey.api.type.Types;

@API(since = "0.4.3", status = Status.MAINTAINED)
public final class DefaultSingleContainerPropertyGenerator implements ContainerPropertyGenerator {
public static final DefaultSingleContainerPropertyGenerator INSTANCE =
new DefaultSingleContainerPropertyGenerator();
private static final TypeReference<String> DEFAULT_ELEMENT_TYPE = new TypeReference<String>() {
};

@Override
public ContainerProperty generate(ContainerPropertyGeneratorContext context) {
Expand All @@ -51,21 +49,18 @@ public ContainerProperty generate(ContainerPropertyGeneratorContext context) {
);
}

AnnotatedType elementType = elementTypes.isEmpty()
? DEFAULT_ELEMENT_TYPE.getAnnotatedType()
: elementTypes.get(0);

ArbitraryContainerInfo containerInfo = context.getContainerInfo();

int size = containerInfo.getRandomSize();
List<Property> childProperties = new ArrayList<>();
for (int sequence = 0; sequence < size; sequence++) {
Integer elementIndex = sequence;
AnnotatedType elementType = elementTypes.get(0);

childProperties.add(
new ElementProperty(
new DefaultContainerElementProperty(
property,
elementType,
new TypeParameterProperty(elementType),
elementIndex,
sequence
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.navercorp.fixturemonkey.api.property.MapKeyElementProperty;
import com.navercorp.fixturemonkey.api.property.MapValueElementProperty;
import com.navercorp.fixturemonkey.api.property.Property;
import com.navercorp.fixturemonkey.api.property.TypeParameterProperty;
import com.navercorp.fixturemonkey.api.type.Types;

@API(since = "0.4.0", status = Status.MAINTAINED)
Expand Down Expand Up @@ -59,12 +60,12 @@ public ContainerProperty generate(ContainerPropertyGeneratorContext context) {
property,
new MapKeyElementProperty(
property,
keyType,
new TypeParameterProperty(keyType),
0
),
new MapValueElementProperty(
property,
valueType,
new TypeParameterProperty(valueType),
0
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,15 @@

package com.navercorp.fixturemonkey.api.generator;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.annotation.Nullable;

import org.apiguardian.api.API;

import com.navercorp.fixturemonkey.api.property.Property;
import com.navercorp.fixturemonkey.api.property.SingleElementProperty;
import com.navercorp.fixturemonkey.api.property.TypeParameterProperty;
import com.navercorp.fixturemonkey.api.type.Types;

@API(since = "1.0.21", status = API.Status.EXPERIMENTAL)
Expand All @@ -45,37 +41,9 @@ public ContainerProperty generate(ContainerPropertyGeneratorContext context) {
Property property = context.getProperty();

AnnotatedType lambdaReturnAnnotatedType = getLambdaReturnAnnotatedType(property);
Type lambdaReturnType = lambdaReturnAnnotatedType.getType();

Property returnProperty = new Property() {
@Override
public Type getType() {
return lambdaReturnType;
}

@Override
public AnnotatedType getAnnotatedType() {
return lambdaReturnAnnotatedType;
}

@Nullable
@Override
public String getName() {
return null;
}

@Override
public List<Annotation> getAnnotations() {
return Arrays.asList(lambdaReturnAnnotatedType.getAnnotations());
}

@Override
public Object getValue(Object instance) {
return instance;
}
};

SingleElementProperty singleElementProperty = new SingleElementProperty(returnProperty);
SingleElementProperty singleElementProperty =
new SingleElementProperty(property, new TypeParameterProperty(lambdaReturnAnnotatedType));

return new ContainerProperty(
Collections.singletonList(singleElementProperty),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.navercorp.fixturemonkey.api.property.MapKeyElementProperty;
import com.navercorp.fixturemonkey.api.property.MapValueElementProperty;
import com.navercorp.fixturemonkey.api.property.Property;
import com.navercorp.fixturemonkey.api.property.TypeParameterProperty;
import com.navercorp.fixturemonkey.api.type.Types;

@API(since = "0.4.0", status = Status.MAINTAINED)
Expand Down Expand Up @@ -79,12 +80,12 @@ public ContainerProperty generate(ContainerPropertyGeneratorContext context) {
property,
new MapKeyElementProperty(
property,
keyType,
new TypeParameterProperty(keyType),
sequence
),
new MapValueElementProperty(
property,
valueType,
new TypeParameterProperty(valueType),
sequence
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,20 @@

import static com.navercorp.fixturemonkey.api.type.Types.generateAnnotatedTypeWithoutAnnotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.OptionalLong;

import javax.annotation.Nullable;

import org.apiguardian.api.API;
import org.apiguardian.api.API.Status;

import com.navercorp.fixturemonkey.api.property.Property;
import com.navercorp.fixturemonkey.api.property.SingleElementProperty;
import com.navercorp.fixturemonkey.api.property.TypeParameterProperty;
import com.navercorp.fixturemonkey.api.type.Types;

@API(since = "0.4.0", status = Status.MAINTAINED)
Expand All @@ -54,43 +50,9 @@ public ContainerProperty generate(ContainerPropertyGeneratorContext context) {
Property property = context.getProperty();

AnnotatedType valueAnnotatedType = getOptionalValueAnnotatedType(property);
Type valueType = valueAnnotatedType.getType();

Property childProperty = new Property() {
@Override
public Type getType() {
return valueType;
}

@Override
public AnnotatedType getAnnotatedType() {
return valueAnnotatedType;
}

@Nullable
@Override
public String getName() {
return null;
}

@Override
public List<Annotation> getAnnotations() {
return Arrays.asList(valueAnnotatedType.getAnnotations());
}

@Nullable
@Override
public Object getValue(Object instance) {
Class<?> actualType = Types.getActualType(instance.getClass());
if (isOptional(actualType)) {
return getOptionalValue(instance);
}

throw new IllegalArgumentException("given value has no match");
}
};

SingleElementProperty singleElementProperty = new SingleElementProperty(childProperty);

SingleElementProperty singleElementProperty =
new SingleElementProperty(property, new TypeParameterProperty(valueAnnotatedType));

return new ContainerProperty(
Collections.singletonList(singleElementProperty),
Expand Down Expand Up @@ -129,32 +91,4 @@ private AnnotatedType getOptionalValueAnnotatedType(Property optionalProperty) {

return genericsTypes.get(0);
}

private boolean isOptional(Class<?> type) {
return Optional.class.isAssignableFrom(type)
|| OptionalInt.class.isAssignableFrom(type)
|| OptionalLong.class.isAssignableFrom(type)
|| OptionalDouble.class.isAssignableFrom(type);
}

private Object getOptionalValue(Object obj) {
Class<?> actualType = Types.getActualType(obj.getClass());
if (Optional.class.isAssignableFrom(actualType)) {
return ((Optional<?>)obj).orElse(null);
}

if (OptionalInt.class.isAssignableFrom(actualType)) {
return ((OptionalInt)obj).orElse(0);
}

if (OptionalLong.class.isAssignableFrom(actualType)) {
return ((OptionalLong)obj).orElse(0L);
}

if (OptionalDouble.class.isAssignableFrom(actualType)) {
return ((OptionalDouble)obj).orElse(Double.NaN);
}

throw new IllegalArgumentException("given value is not optional, actual type : " + actualType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.navercorp.fixturemonkey.api.property.ElementProperty;
import com.navercorp.fixturemonkey.api.property.DefaultContainerElementProperty;
import com.navercorp.fixturemonkey.api.property.Property;
import com.navercorp.fixturemonkey.api.property.TypeParameterProperty;
import com.navercorp.fixturemonkey.api.type.Types;

@API(since = "0.4.0", status = Status.MAINTAINED)
Expand Down Expand Up @@ -71,9 +72,9 @@ public ContainerProperty generate(ContainerPropertyGeneratorContext context) {
List<Property> childProperties = new ArrayList<>();
for (int sequence = 0; sequence < size; sequence++) {
childProperties.add(
new ElementProperty(
new DefaultContainerElementProperty(
property,
elementType,
new TypeParameterProperty(elementType),
null,
sequence
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
import org.apiguardian.api.API;
import org.apiguardian.api.API.Status;

import com.navercorp.fixturemonkey.api.property.ElementProperty;
import com.navercorp.fixturemonkey.api.property.DefaultContainerElementProperty;
import com.navercorp.fixturemonkey.api.property.Property;
import com.navercorp.fixturemonkey.api.property.TypeParameterProperty;
import com.navercorp.fixturemonkey.api.type.Types;

@API(since = "0.4.0", status = Status.MAINTAINED)
Expand All @@ -55,9 +56,9 @@ public ContainerProperty generate(ContainerPropertyGeneratorContext context) {
List<Property> childProperties = new ArrayList<>();
for (int sequence = 0; sequence < size; sequence++) {
childProperties.add(
new ElementProperty(
new DefaultContainerElementProperty(
property,
elementAnnotatedType,
new TypeParameterProperty(elementAnnotatedType),
sequence,
sequence
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Fixture Monkey
*
* Copyright (c) 2021-present NAVER Corp.
*
* 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.navercorp.fixturemonkey.api.property;

import javax.annotation.Nullable;

import org.apiguardian.api.API;
import org.apiguardian.api.API.Status;

/**
* It represents a property that is a container element.
* Container means that the type has one or more type parameters
* and the type has the properties (called elements) of the type parameters inside it.
* <p>
* For example, {@code List<String>} is a container type because it has one type parameter {@code String}.
*/
@API(since = "1.1.6", status = Status.EXPERIMENTAL)
public interface ContainerElementProperty extends Property {
/**
* It returns the property of the container.
*
* @return the property of the container
*/
Property getContainerProperty();

/**
* It returns the property of the element.
*
* @return the property of the element
*/
Property getElementProperty();

/**
* It returns the sequence of the element.
*
* @return the sequence of the element
*/
int getSequence();

/**
* It returns the index of the element.
*
* @return the index of the element, may be null if the container has no ordering.
*/
@Nullable
Integer getIndex();
}
Loading

0 comments on commit 7c6b910

Please sign in to comment.