Browse Source
We now correctly calculate the number of defaulting masks used to represent constructor arguments. Previously, we've been one off which caused that Kotlin classes with 32/33 parameters weren't able to be instantiated. We also now reuse KotlinDefaultMask to apply defaulting calculation and removed code duplicates.pull/351/head
5 changed files with 233 additions and 17 deletions
@ -0,0 +1,152 @@
@@ -0,0 +1,152 @@
|
||||
/* |
||||
* Copyright 2018 the original author or authors. |
||||
* |
||||
* 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 org.springframework.data.convert; |
||||
|
||||
import static org.assertj.core.api.Assertions.*; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.stream.Collectors; |
||||
import java.util.stream.IntStream; |
||||
|
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.junit.runners.Parameterized; |
||||
import org.junit.runners.Parameterized.Parameters; |
||||
import org.springframework.data.mapping.PersistentEntity; |
||||
import org.springframework.data.mapping.PreferredConstructor.Parameter; |
||||
import org.springframework.data.mapping.context.SampleMappingContext; |
||||
import org.springframework.data.mapping.context.SamplePersistentProperty; |
||||
import org.springframework.data.mapping.model.BasicPersistentEntity; |
||||
import org.springframework.data.mapping.model.ParameterValueProvider; |
||||
import org.springframework.data.mapping.model.With32Args; |
||||
import org.springframework.data.mapping.model.With33Args; |
||||
import org.springframework.test.util.ReflectionTestUtils; |
||||
|
||||
/** |
||||
* Unit test to verify correct object instantiation using Kotlin defaulting via {@link KotlinClassGeneratingEntityInstantiator}. |
||||
* |
||||
* @author Mark Paluch |
||||
*/ |
||||
@RunWith(Parameterized.class) |
||||
public class ParameterizedKotlinInstantiatorUnitTests { |
||||
|
||||
private final String valueToSet = "THE VALUE"; |
||||
private final PersistentEntity<Object, SamplePersistentProperty> entity; |
||||
private final int propertyCount; |
||||
private final int propertyUnderTestIndex; |
||||
private final String propertyUnderTestName; |
||||
private final EntityInstantiator entityInstantiator; |
||||
|
||||
public ParameterizedKotlinInstantiatorUnitTests(PersistentEntity<Object, SamplePersistentProperty> entity, int propertyCount, int propertyUnderTestIndex, String propertyUnderTestName, EntityInstantiator entityInstantiator, String label) { |
||||
this.entity = entity; |
||||
this.propertyCount = propertyCount; |
||||
this.propertyUnderTestIndex = propertyUnderTestIndex; |
||||
this.propertyUnderTestName = propertyUnderTestName; |
||||
this.entityInstantiator = entityInstantiator; |
||||
} |
||||
|
||||
@Parameters(name = "{5}") |
||||
public static List<Object[]> parameters() { |
||||
|
||||
SampleMappingContext context = new SampleMappingContext(); |
||||
|
||||
KotlinClassGeneratingEntityInstantiator generatingInstantiator = new KotlinClassGeneratingEntityInstantiator(); |
||||
ReflectionEntityInstantiator reflectionInstantiator = ReflectionEntityInstantiator.INSTANCE; |
||||
|
||||
List<Object[]> fixtures = new ArrayList<>(); |
||||
fixtures.addAll(createFixture(context, With32Args.class, 32, generatingInstantiator)); |
||||
fixtures.addAll(createFixture(context, With32Args.class, 32, reflectionInstantiator)); |
||||
fixtures.addAll(createFixture(context, With33Args.class, 33, generatingInstantiator)); |
||||
fixtures.addAll(createFixture(context, With33Args.class, 33, reflectionInstantiator)); |
||||
|
||||
return fixtures; |
||||
} |
||||
|
||||
private static List<Object[]> createFixture(SampleMappingContext context, Class<?> entityType, int propertyCount, EntityInstantiator entityInstantiator) { |
||||
|
||||
BasicPersistentEntity<Object, SamplePersistentProperty> persistentEntity = context.getPersistentEntity(entityType); |
||||
|
||||
return IntStream.range(0, propertyCount).mapToObj(i -> { |
||||
|
||||
return new Object[]{persistentEntity, propertyCount, i, Integer.toString(i), entityInstantiator, String.format("Property %d for %s using %s", i, entityType.getSimpleName(), entityInstantiator.getClass().getSimpleName())}; |
||||
}).collect(Collectors.toList()); |
||||
} |
||||
|
||||
@Test // DATACMNS-1402
|
||||
public void shouldCreateInstanceWithSinglePropertySet() { |
||||
|
||||
Object instance = entityInstantiator.createInstance(entity, new SingleParameterValueProvider()); |
||||
|
||||
for (int i = 0; i < propertyCount; i++) { |
||||
|
||||
Object value = ReflectionTestUtils.getField(instance, Integer.toString(i)); |
||||
|
||||
if (propertyUnderTestIndex == i) { |
||||
assertThat(value).describedAs("Property " + i + " of " + entity).isEqualTo(valueToSet); |
||||
} else { |
||||
assertThat(value).describedAs("Property " + i + " of " + entity).isEqualTo(""); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Test // DATACMNS-1402
|
||||
public void shouldCreateInstanceWithAllExceptSinglePropertySet() { |
||||
|
||||
Object instance = entityInstantiator.createInstance(entity, new AllButParameterValueProvider()); |
||||
|
||||
for (int i = 0; i < propertyCount; i++) { |
||||
|
||||
Object value = ReflectionTestUtils.getField(instance, Integer.toString(i)); |
||||
|
||||
if (propertyUnderTestIndex == i) { |
||||
assertThat(value).describedAs("Property " + i + " of " + entity).isEqualTo(""); |
||||
} else { |
||||
assertThat(value).describedAs("Property " + i + " of " + entity).isEqualTo(Integer.toString(i)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return the value to set for the property to test. |
||||
*/ |
||||
class SingleParameterValueProvider implements ParameterValueProvider<SamplePersistentProperty> { |
||||
|
||||
@Override |
||||
public <T> T getParameterValue(Parameter<T, SamplePersistentProperty> parameter) { |
||||
|
||||
if (parameter.getName().equals(propertyUnderTestName)) { |
||||
return (T) valueToSet; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return the property name as value for all properties except the one to test. |
||||
*/ |
||||
class AllButParameterValueProvider implements ParameterValueProvider<SamplePersistentProperty> { |
||||
|
||||
@Override |
||||
public <T> T getParameterValue(Parameter<T, SamplePersistentProperty> parameter) { |
||||
|
||||
if (!parameter.getName().equals(propertyUnderTestName)) { |
||||
return (T) parameter.getName(); |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
/* |
||||
* Copyright 2018 the original author or authors. |
||||
* |
||||
* 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 org.springframework.data.mapping.model |
||||
|
||||
data class With32Args(val `0`: String = "", val `1`: String = "", val `2`: String = "", val `3`: String = "", val `4`: String = "", val `5`: String = "", |
||||
val `6`: String = "", val `7`: String = "", val `8`: String = "", val `9`: String = "", val `10`: String = "", val `11`: String = "", val `12`: String = "", |
||||
val `13`: String = "", val `14`: String = "", val `15`: String = "", val `16`: String = "", val `17`: String = "", val `18`: String = "", val `19`: String = "", |
||||
val `20`: String = "", val `21`: String = "", val `22`: String = "", val `23`: String = "", val `24`: String = "", val `25`: String = "", val `26`: String = "", |
||||
val `27`: String = "", val `28`: String = "", val `29`: String = "", val `30`: String = "", val `31`: String = "" |
||||
) |
||||
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
/* |
||||
* Copyright 2018 the original author or authors. |
||||
* |
||||
* 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 org.springframework.data.mapping.model |
||||
|
||||
data class With33Args(val `0`: String = "", val `1`: String = "", val `2`: String = "", val `3`: String = "", val `4`: String = "", val `5`: String = "", |
||||
val `6`: String = "", val `7`: String = "", val `8`: String = "", val `9`: String = "", val `10`: String = "", val `11`: String = "", val `12`: String = "", |
||||
val `13`: String = "", val `14`: String = "", val `15`: String = "", val `16`: String = "", val `17`: String = "", val `18`: String = "", val `19`: String = "", |
||||
val `20`: String = "", val `21`: String = "", val `22`: String = "", val `23`: String = "", val `24`: String = "", val `25`: String = "", val `26`: String = "", |
||||
val `27`: String = "", val `28`: String = "", val `29`: String = "", val `30`: String = "", val `31`: String = "", val `32`: String = "" |
||||
) |
||||
Loading…
Reference in new issue