20
20
import java .util .Set ;
21
21
22
22
import org .junit .jupiter .api .Test ;
23
+ import org .junit .jupiter .api .BeforeEach ;
23
24
24
25
import org .springframework .ai .anthropic .api .AnthropicApi ;
25
26
import org .springframework .aot .hint .RuntimeHints ;
26
27
import org .springframework .aot .hint .TypeReference ;
28
+ import org .springframework .aot .hint .MemberCategory ;
27
29
28
30
import static org .assertj .core .api .AssertionsForClassTypes .assertThat ;
29
31
import static org .springframework .ai .aot .AiRuntimeHints .findJsonAnnotatedClassesInPackage ;
30
32
31
33
class AnthropicRuntimeHintsTests {
32
34
35
+ private RuntimeHints runtimeHints ;
36
+
37
+ private AnthropicRuntimeHints anthropicRuntimeHints ;
38
+
39
+ @ BeforeEach
40
+ void setUp () {
41
+ runtimeHints = new RuntimeHints ();
42
+ anthropicRuntimeHints = new AnthropicRuntimeHints ();
43
+ }
44
+
33
45
@ Test
34
46
void registerHints () {
35
- RuntimeHints runtimeHints = new RuntimeHints ();
36
- AnthropicRuntimeHints anthropicRuntimeHints = new AnthropicRuntimeHints ();
37
47
anthropicRuntimeHints .registerHints (runtimeHints , null );
38
48
39
49
Set <TypeReference > jsonAnnotatedClasses = findJsonAnnotatedClassesInPackage ("org.springframework.ai.anthropic" );
@@ -55,4 +65,84 @@ void registerHints() {
55
65
assertThat (registeredTypes .contains (TypeReference .of (AnthropicApi .AnthropicMessage .class ))).isTrue ();
56
66
}
57
67
68
+ @ Test
69
+ void registerHintsWithNullClassLoader () {
70
+ // Test that registering hints with null ClassLoader works correctly
71
+ anthropicRuntimeHints .registerHints (runtimeHints , null );
72
+
73
+ Set <TypeReference > registeredTypes = new HashSet <>();
74
+ runtimeHints .reflection ().typeHints ().forEach (typeHint -> registeredTypes .add (typeHint .getType ()));
75
+
76
+ assertThat (registeredTypes .size ()).isGreaterThan (0 );
77
+ }
78
+
79
+ @ Test
80
+ void registerHintsWithCustomClassLoader () {
81
+ // Test that registering hints with a custom ClassLoader works correctly
82
+ ClassLoader customClassLoader = Thread .currentThread ().getContextClassLoader ();
83
+ anthropicRuntimeHints .registerHints (runtimeHints , customClassLoader );
84
+
85
+ Set <TypeReference > registeredTypes = new HashSet <>();
86
+ runtimeHints .reflection ().typeHints ().forEach (typeHint -> registeredTypes .add (typeHint .getType ()));
87
+
88
+ assertThat (registeredTypes .size ()).isGreaterThan (0 );
89
+ }
90
+
91
+ @ Test
92
+ void allMemberCategoriesAreRegistered () {
93
+ anthropicRuntimeHints .registerHints (runtimeHints , null );
94
+
95
+ Set <TypeReference > jsonAnnotatedClasses = findJsonAnnotatedClassesInPackage ("org.springframework.ai.anthropic" );
96
+
97
+ // Verify that all MemberCategory values are registered for each type
98
+ runtimeHints .reflection ().typeHints ().forEach (typeHint -> {
99
+ if (jsonAnnotatedClasses .contains (typeHint .getType ())) {
100
+ Set <MemberCategory > expectedCategories = Set .of (MemberCategory .values ());
101
+ Set <MemberCategory > actualCategories = typeHint .getMemberCategories ();
102
+ assertThat (actualCategories .containsAll (expectedCategories )).isTrue ();
103
+ }
104
+ });
105
+ }
106
+
107
+ @ Test
108
+ void emptyRuntimeHintsInitiallyContainsNoTypes () {
109
+ // Verify that fresh RuntimeHints instance contains no reflection hints
110
+ RuntimeHints emptyHints = new RuntimeHints ();
111
+ Set <TypeReference > emptyRegisteredTypes = new HashSet <>();
112
+ emptyHints .reflection ().typeHints ().forEach (typeHint -> emptyRegisteredTypes .add (typeHint .getType ()));
113
+
114
+ assertThat (emptyRegisteredTypes .size ()).isEqualTo (0 );
115
+ }
116
+
117
+ @ Test
118
+ void multipleRegistrationCallsAreIdempotent () {
119
+ // Register hints multiple times and verify no duplicates
120
+ anthropicRuntimeHints .registerHints (runtimeHints , null );
121
+ int firstRegistrationCount = (int ) runtimeHints .reflection ().typeHints ().count ();
122
+
123
+ anthropicRuntimeHints .registerHints (runtimeHints , null );
124
+ int secondRegistrationCount = (int ) runtimeHints .reflection ().typeHints ().count ();
125
+
126
+ assertThat (firstRegistrationCount ).isEqualTo (secondRegistrationCount );
127
+ }
128
+
129
+ @ Test
130
+ void verifyJsonAnnotatedClassesInPackageIsNotEmpty () {
131
+ Set <TypeReference > jsonAnnotatedClasses = findJsonAnnotatedClassesInPackage ("org.springframework.ai.anthropic" );
132
+ assertThat (jsonAnnotatedClasses .isEmpty ()).isFalse ();
133
+ }
134
+
135
+ @ Test
136
+ void verifyEnumTypesAreRegistered () {
137
+ anthropicRuntimeHints .registerHints (runtimeHints , null );
138
+
139
+ Set <TypeReference > registeredTypes = new HashSet <>();
140
+ runtimeHints .reflection ().typeHints ().forEach (typeHint -> registeredTypes .add (typeHint .getType ()));
141
+
142
+ // Verify enum types are properly registered
143
+ assertThat (registeredTypes .contains (TypeReference .of (AnthropicApi .Role .class ))).isTrue ();
144
+ assertThat (registeredTypes .contains (TypeReference .of (AnthropicApi .ThinkingType .class ))).isTrue ();
145
+ assertThat (registeredTypes .contains (TypeReference .of (AnthropicApi .EventType .class ))).isTrue ();
146
+ }
147
+
58
148
}
0 commit comments