Apply consistent RuntimeHints defaults
This commit harmonizes the registration of an executable so that the default method and the method that takes an empty customizer produces the same hint. The same applies to the readable flag of a field hint. Rather than returning a list of executable modes, the "highest" mode is retained. See gh-29011
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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
|
||||
*
|
||||
* https://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.aot.hint;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ExecutableMode}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class ExecutableModeTests {
|
||||
|
||||
@Test
|
||||
void invokeIncludesNullMode() {
|
||||
assertThat(ExecutableMode.INVOKE.includes(null)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void invokeIncludesIntrospect() {
|
||||
assertThat(ExecutableMode.INVOKE.includes(ExecutableMode.INTROSPECT)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void invokeIncludesIncludes() {
|
||||
assertThat(ExecutableMode.INVOKE.includes(ExecutableMode.INVOKE)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void introspectIncludesNullMode() {
|
||||
assertThat(ExecutableMode.INTROSPECT.includes(null)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void introspectIncludesIntrospect() {
|
||||
assertThat(ExecutableMode.INTROSPECT.includes(ExecutableMode.INTROSPECT)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void introspectDoesNotIncludeInvoke() {
|
||||
assertThat(ExecutableMode.INTROSPECT.includes(ExecutableMode.INVOKE)).isFalse();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -121,14 +121,46 @@ class ReflectionHintsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerField() {
|
||||
void registerFieldAllowsWriteByDefault() {
|
||||
Field field = ReflectionUtils.findField(TestType.class, "field");
|
||||
assertThat(field).isNotNull();
|
||||
this.reflectionHints.registerField(field);
|
||||
assertTestTypeFieldHint(fieldHint -> {
|
||||
assertThat(fieldHint.getName()).isEqualTo("field");
|
||||
assertThat(fieldHint.isAllowWrite()).isTrue();
|
||||
assertThat(fieldHint.isAllowUnsafeAccess()).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerFieldWithEmptyCustomizerAppliesConsistentDefault() {
|
||||
Field field = ReflectionUtils.findField(TestType.class, "field");
|
||||
assertThat(field).isNotNull();
|
||||
this.reflectionHints.registerField(field, fieldHint -> {});
|
||||
assertTestTypeFieldHint(fieldHint -> {
|
||||
assertThat(fieldHint.getName()).isEqualTo("field");
|
||||
assertThat(fieldHint.isAllowWrite()).isTrue();
|
||||
assertThat(fieldHint.isAllowUnsafeAccess()).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerFieldWithCustomizerAppliesCustomization() {
|
||||
Field field = ReflectionUtils.findField(TestType.class, "field");
|
||||
assertThat(field).isNotNull();
|
||||
this.reflectionHints.registerField(field, fieldHint ->
|
||||
fieldHint.allowWrite(false).allowUnsafeAccess(true));
|
||||
assertTestTypeFieldHint(fieldHint -> {
|
||||
assertThat(fieldHint.getName()).isEqualTo("field");
|
||||
assertThat(fieldHint.isAllowWrite()).isFalse();
|
||||
assertThat(fieldHint.isAllowUnsafeAccess()).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
private void assertTestTypeFieldHint(Consumer<FieldHint> fieldHint) {
|
||||
assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(typeHint -> {
|
||||
assertThat(typeHint.getType().getCanonicalName()).isEqualTo(TestType.class.getCanonicalName());
|
||||
assertThat(typeHint.fields()).singleElement().satisfies(fieldHint ->
|
||||
assertThat(fieldHint.getName()).isEqualTo("field"));
|
||||
assertThat(typeHint.fields()).singleElement().satisfies(fieldHint);
|
||||
assertThat(typeHint.constructors()).isEmpty();
|
||||
assertThat(typeHint.methods()).isEmpty();
|
||||
assertThat(typeHint.getMemberCategories()).isEmpty();
|
||||
@@ -138,14 +170,38 @@ class ReflectionHintsTests {
|
||||
@Test
|
||||
void registerConstructor() {
|
||||
this.reflectionHints.registerConstructor(TestType.class.getDeclaredConstructors()[0]);
|
||||
assertTestTypeConstructorHint(constructorHint -> {
|
||||
assertThat(constructorHint.getParameterTypes()).isEmpty();
|
||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerConstructorWithEmptyCustomizerAppliesConsistentDefault() {
|
||||
this.reflectionHints.registerConstructor(TestType.class.getDeclaredConstructors()[0],
|
||||
constructorHint -> {});
|
||||
assertTestTypeConstructorHint(constructorHint -> {
|
||||
assertThat(constructorHint.getParameterTypes()).isEmpty();
|
||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerConstructorWithCustomizerAppliesCustomization() {
|
||||
this.reflectionHints.registerConstructor(TestType.class.getDeclaredConstructors()[0],
|
||||
constructorHint -> constructorHint.withMode(ExecutableMode.INTROSPECT));
|
||||
assertTestTypeConstructorHint(constructorHint -> {
|
||||
assertThat(constructorHint.getParameterTypes()).isEmpty();
|
||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INTROSPECT);
|
||||
});
|
||||
}
|
||||
|
||||
private void assertTestTypeConstructorHint(Consumer<ExecutableHint> constructorHint) {
|
||||
assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(typeHint -> {
|
||||
assertThat(typeHint.getMemberCategories()).isEmpty();
|
||||
assertThat(typeHint.getType().getCanonicalName()).isEqualTo(TestType.class.getCanonicalName());
|
||||
assertThat(typeHint.fields()).isEmpty();
|
||||
assertThat(typeHint.constructors()).singleElement().satisfies(constructorHint -> {
|
||||
assertThat(constructorHint.getParameterTypes()).isEmpty();
|
||||
assertThat(constructorHint.getModes()).containsOnly(ExecutableMode.INVOKE);
|
||||
});
|
||||
assertThat(typeHint.constructors()).singleElement().satisfies(constructorHint);
|
||||
assertThat(typeHint.methods()).isEmpty();
|
||||
assertThat(typeHint.getMemberCategories()).isEmpty();
|
||||
});
|
||||
@@ -156,15 +212,44 @@ class ReflectionHintsTests {
|
||||
Method method = ReflectionUtils.findMethod(TestType.class, "setName", String.class);
|
||||
assertThat(method).isNotNull();
|
||||
this.reflectionHints.registerMethod(method);
|
||||
assertTestTypeMethodHints(methodHint -> {
|
||||
assertThat(methodHint.getName()).isEqualTo("setName");
|
||||
assertThat(methodHint.getParameterTypes()).containsOnly(TypeReference.of(String.class));
|
||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerMethodWithEmptyCustomizerAppliesConsistentDefault() {
|
||||
Method method = ReflectionUtils.findMethod(TestType.class, "setName", String.class);
|
||||
assertThat(method).isNotNull();
|
||||
this.reflectionHints.registerMethod(method, methodHint -> {});
|
||||
assertTestTypeMethodHints(methodHint -> {
|
||||
assertThat(methodHint.getName()).isEqualTo("setName");
|
||||
assertThat(methodHint.getParameterTypes()).containsOnly(TypeReference.of(String.class));
|
||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerMethodWithCustomizerAppliesCustomization() {
|
||||
Method method = ReflectionUtils.findMethod(TestType.class, "setName", String.class);
|
||||
assertThat(method).isNotNull();
|
||||
this.reflectionHints.registerMethod(method, methodHint ->
|
||||
methodHint.withMode(ExecutableMode.INTROSPECT));
|
||||
assertTestTypeMethodHints(methodHint -> {
|
||||
assertThat(methodHint.getName()).isEqualTo("setName");
|
||||
assertThat(methodHint.getParameterTypes()).containsOnly(TypeReference.of(String.class));
|
||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INTROSPECT);
|
||||
});
|
||||
}
|
||||
|
||||
private void assertTestTypeMethodHints(Consumer<ExecutableHint> methodHint) {
|
||||
assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(typeHint -> {
|
||||
assertThat(typeHint.getType().getCanonicalName()).isEqualTo(TestType.class.getCanonicalName());
|
||||
assertThat(typeHint.fields()).isEmpty();
|
||||
assertThat(typeHint.constructors()).isEmpty();
|
||||
assertThat(typeHint.methods()).singleElement().satisfies(methodHint -> {
|
||||
assertThat(methodHint.getName()).isEqualTo("setName");
|
||||
assertThat(methodHint.getParameterTypes()).containsOnly(TypeReference.of(String.class));
|
||||
assertThat(methodHint.getModes()).containsOnly(ExecutableMode.INVOKE);
|
||||
});
|
||||
assertThat(typeHint.methods()).singleElement().satisfies(methodHint);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -87,12 +87,25 @@ class TypeHintTests {
|
||||
constructorHint -> constructorHint.withMode(ExecutableMode.INVOKE)).build();
|
||||
assertThat(hint.constructors()).singleElement().satisfies(constructorHint -> {
|
||||
assertThat(constructorHint.getParameterTypes()).containsOnlyOnceElementsOf(parameterTypes);
|
||||
assertThat(constructorHint.getModes()).containsOnly(ExecutableMode.INVOKE);
|
||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void createConstructorReuseBuilder() {
|
||||
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
|
||||
Builder builder = TypeHint.of(TypeReference.of(String.class)).withConstructor(parameterTypes,
|
||||
constructorHint -> constructorHint.withMode(ExecutableMode.INTROSPECT));
|
||||
TypeHint hint = builder.withConstructor(parameterTypes, constructorHint ->
|
||||
constructorHint.withMode(ExecutableMode.INVOKE)).build();
|
||||
assertThat(hint.constructors()).singleElement().satisfies(constructorHint -> {
|
||||
assertThat(constructorHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void createConstructorReuseBuilderAndApplyExecutableModePrecedence() {
|
||||
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
|
||||
Builder builder = TypeHint.of(TypeReference.of(String.class)).withConstructor(parameterTypes,
|
||||
constructorHint -> constructorHint.withMode(ExecutableMode.INVOKE));
|
||||
@@ -100,7 +113,7 @@ class TypeHintTests {
|
||||
constructorHint.withMode(ExecutableMode.INTROSPECT)).build();
|
||||
assertThat(hint.constructors()).singleElement().satisfies(constructorHint -> {
|
||||
assertThat(constructorHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
||||
assertThat(constructorHint.getModes()).containsOnly(ExecutableMode.INVOKE, ExecutableMode.INTROSPECT);
|
||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -112,7 +125,7 @@ class TypeHintTests {
|
||||
assertThat(hint.methods()).singleElement().satisfies(methodHint -> {
|
||||
assertThat(methodHint.getName()).isEqualTo("valueOf");
|
||||
assertThat(methodHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
||||
assertThat(methodHint.getModes()).containsOnly(ExecutableMode.INVOKE);
|
||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -120,13 +133,27 @@ class TypeHintTests {
|
||||
void createWithMethodReuseBuilder() {
|
||||
List<TypeReference> parameterTypes = TypeReference.listOf(char[].class);
|
||||
Builder builder = TypeHint.of(TypeReference.of(String.class)).withMethod("valueOf", parameterTypes,
|
||||
methodHint -> methodHint.withMode(ExecutableMode.INVOKE));
|
||||
methodHint -> methodHint.withMode(ExecutableMode.INTROSPECT));
|
||||
TypeHint hint = builder.withMethod("valueOf", parameterTypes,
|
||||
methodHint -> methodHint.setModes(ExecutableMode.INTROSPECT)).build();
|
||||
methodHint -> methodHint.withMode(ExecutableMode.INVOKE)).build();
|
||||
assertThat(hint.methods()).singleElement().satisfies(methodHint -> {
|
||||
assertThat(methodHint.getName()).isEqualTo("valueOf");
|
||||
assertThat(methodHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
||||
assertThat(methodHint.getModes()).containsOnly(ExecutableMode.INTROSPECT);
|
||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWithMethodReuseBuilderAndApplyExecutableModePrecedence() {
|
||||
List<TypeReference> parameterTypes = TypeReference.listOf(char[].class);
|
||||
Builder builder = TypeHint.of(TypeReference.of(String.class)).withMethod("valueOf", parameterTypes,
|
||||
methodHint -> methodHint.withMode(ExecutableMode.INVOKE));
|
||||
TypeHint hint = builder.withMethod("valueOf", parameterTypes,
|
||||
methodHint -> methodHint.withMode(ExecutableMode.INTROSPECT)).build();
|
||||
assertThat(hint.methods()).singleElement().satisfies(methodHint -> {
|
||||
assertThat(methodHint.getName()).isEqualTo("valueOf");
|
||||
assertThat(methodHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ class SimpleReflectiveProcessorTests {
|
||||
assertThat(typeHint.getMemberCategories()).isEmpty();
|
||||
assertThat(typeHint.constructors()).singleElement().satisfies(constructorHint -> {
|
||||
assertThat(constructorHint.getName()).isEqualTo("<init>");
|
||||
assertThat(constructorHint.getModes()).containsExactly(ExecutableMode.INVOKE);
|
||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||
assertThat(constructorHint.getParameterTypes()).containsExactly(TypeReference.of(String.class));
|
||||
});
|
||||
assertThat(typeHint.fields()).isEmpty();
|
||||
@@ -93,7 +93,7 @@ class SimpleReflectiveProcessorTests {
|
||||
assertThat(typeHint.fields()).isEmpty();
|
||||
assertThat(typeHint.methods()).singleElement().satisfies(methodHint -> {
|
||||
assertThat(methodHint.getName()).isEqualTo("setName");
|
||||
assertThat(methodHint.getModes()).containsExactly(ExecutableMode.INVOKE);
|
||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||
assertThat(methodHint.getParameterTypes()).containsExactly(TypeReference.of(String.class));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -192,7 +192,8 @@ class ReflectionHintsPredicatesTests {
|
||||
@Test
|
||||
void constructorInvocationDoesNotMatchConstructorHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.
|
||||
withConstructor(Collections.emptyList(), constructorHint -> {}));
|
||||
withConstructor(Collections.emptyList(), constructorHint ->
|
||||
constructorHint.withMode(ExecutableMode.INTROSPECT)));
|
||||
assertPredicateDoesNotMatch(reflection.onConstructor(publicConstructor).invoke());
|
||||
}
|
||||
|
||||
@@ -270,7 +271,8 @@ class ReflectionHintsPredicatesTests {
|
||||
@Test
|
||||
void privateConstructorInvocationDoesNotMatchConstructorHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
|
||||
typeHint.withConstructor(TypeReference.listOf(String.class), constructorHint -> {}));
|
||||
typeHint.withConstructor(TypeReference.listOf(String.class), constructorHint ->
|
||||
constructorHint.withMode(ExecutableMode.INTROSPECT)));
|
||||
assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).invoke());
|
||||
}
|
||||
|
||||
@@ -348,14 +350,15 @@ class ReflectionHintsPredicatesTests {
|
||||
|
||||
@Test
|
||||
void methodInvocationDoesNotMatchMethodHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMethod("publicMethod", Collections.emptyList(), methodHint -> {
|
||||
}));
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMethod("publicMethod", Collections.emptyList(),
|
||||
methodHint -> methodHint.withMode(ExecutableMode.INTROSPECT)));
|
||||
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "publicMethod").invoke());
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodInvocationMatchesMethodInvocationHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMethod("publicMethod", Collections.emptyList(), methodHint -> methodHint.withMode(ExecutableMode.INVOKE)));
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMethod("publicMethod", Collections.emptyList(),
|
||||
methodHint -> methodHint.withMode(ExecutableMode.INVOKE)));
|
||||
assertPredicateMatches(reflection.onMethod(SampleClass.class, "publicMethod").invoke());
|
||||
}
|
||||
|
||||
@@ -416,8 +419,8 @@ class ReflectionHintsPredicatesTests {
|
||||
|
||||
@Test
|
||||
void privateMethodInvocationDoesNotMatchMethodHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMethod("privateMethod", Collections.emptyList(), methodHint -> {
|
||||
}));
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMethod("privateMethod", Collections.emptyList(),
|
||||
methodHint -> methodHint.withMode(ExecutableMode.INTROSPECT)));
|
||||
assertPredicateDoesNotMatch(reflection.onMethod(SampleClass.class, "privateMethod").invoke());
|
||||
}
|
||||
|
||||
@@ -470,8 +473,8 @@ class ReflectionHintsPredicatesTests {
|
||||
|
||||
@Test
|
||||
void fieldWriteReflectionDoesNotMatchFieldHint() {
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("publicField", fieldHint -> {
|
||||
}));
|
||||
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("publicField",
|
||||
fieldHint -> fieldHint.allowWrite(false)));
|
||||
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "publicField").allowWrite());
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ public class FileNativeConfigurationWriterTests {
|
||||
MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS,
|
||||
MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS,
|
||||
MemberCategory.PUBLIC_CLASSES, MemberCategory.DECLARED_CLASSES)
|
||||
.withField("DEFAULT_CHARSET", fieldBuilder -> {})
|
||||
.withField("DEFAULT_CHARSET", fieldBuilder -> fieldBuilder.allowWrite(false))
|
||||
.withField("defaultCharset", fieldBuilder -> {
|
||||
fieldBuilder.allowWrite(true);
|
||||
fieldBuilder.allowUnsafeAccess(true);
|
||||
|
||||
@@ -58,7 +58,7 @@ public class ReflectionHintsWriterTests {
|
||||
MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS,
|
||||
MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS,
|
||||
MemberCategory.PUBLIC_CLASSES, MemberCategory.DECLARED_CLASSES)
|
||||
.withField("DEFAULT_CHARSET", fieldBuilder -> {})
|
||||
.withField("DEFAULT_CHARSET", fieldBuilder -> fieldBuilder.allowWrite(false))
|
||||
.withField("defaultCharset", fieldBuilder -> {
|
||||
fieldBuilder.allowWrite(true);
|
||||
fieldBuilder.allowUnsafeAccess(true);
|
||||
@@ -185,7 +185,7 @@ public class ReflectionHintsWriterTests {
|
||||
hints.registerType(Integer.class, builder -> builder.withMethod("parseInt",
|
||||
TypeReference.listOf(String.class), b -> b.withMode(ExecutableMode.INVOKE)));
|
||||
hints.registerType(Integer.class, builder -> builder.withMethod("parseInt",
|
||||
TypeReference.listOf(String.class), b -> b.withMode(ExecutableMode.INTROSPECT)));
|
||||
TypeReference.listOf(String.class, int.class), b -> b.withMode(ExecutableMode.INTROSPECT)));
|
||||
|
||||
assertEquals("""
|
||||
[
|
||||
@@ -194,7 +194,7 @@ public class ReflectionHintsWriterTests {
|
||||
"queriedMethods": [
|
||||
{
|
||||
"name": "parseInt",
|
||||
"parameterTypes": ["java.lang.String"]
|
||||
"parameterTypes": ["java.lang.String", "int"]
|
||||
}
|
||||
],
|
||||
"methods": [
|
||||
|
||||
Reference in New Issue
Block a user