|
28 | 28 | import org.springframework.aot.hint.TypeReference; |
29 | 29 |
|
30 | 30 | import static org.assertj.core.api.AssertionsForClassTypes.assertThat; |
| 31 | +import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; |
31 | 32 | import static org.springframework.ai.aot.AiRuntimeHints.findJsonAnnotatedClassesInPackage; |
32 | 33 |
|
33 | 34 | class MistralAiRuntimeHintsTests { |
@@ -174,4 +175,71 @@ void verifyReflectionHintsIncludeConstructors() { |
174 | 175 | assertThat(hasConstructorHints).as("Should register constructor hints for JSON deserialization").isTrue(); |
175 | 176 | } |
176 | 177 |
|
| 178 | + @Test |
| 179 | + void verifyNoExceptionThrownWithEmptyRuntimeHints() { |
| 180 | + RuntimeHints emptyRuntimeHints = new RuntimeHints(); |
| 181 | + MistralAiRuntimeHints mistralAiRuntimeHints = new MistralAiRuntimeHints(); |
| 182 | + |
| 183 | + // Should not throw any exception even with empty runtime hints |
| 184 | + assertThatCode(() -> mistralAiRuntimeHints.registerHints(emptyRuntimeHints, null)).doesNotThrowAnyException(); |
| 185 | + |
| 186 | + assertThat(emptyRuntimeHints.reflection().typeHints().count()).isGreaterThan(0); |
| 187 | + } |
| 188 | + |
| 189 | + @Test |
| 190 | + void verifyProxyHintsAreNotRegistered() { |
| 191 | + RuntimeHints runtimeHints = new RuntimeHints(); |
| 192 | + MistralAiRuntimeHints mistralAiRuntimeHints = new MistralAiRuntimeHints(); |
| 193 | + mistralAiRuntimeHints.registerHints(runtimeHints, null); |
| 194 | + |
| 195 | + // MistralAi should only register reflection hints, not proxy hints |
| 196 | + assertThat(runtimeHints.proxies().jdkProxyHints().count()).isEqualTo(0); |
| 197 | + } |
| 198 | + |
| 199 | + @Test |
| 200 | + void verifySerializationHintsAreNotRegistered() { |
| 201 | + RuntimeHints runtimeHints = new RuntimeHints(); |
| 202 | + MistralAiRuntimeHints mistralAiRuntimeHints = new MistralAiRuntimeHints(); |
| 203 | + mistralAiRuntimeHints.registerHints(runtimeHints, null); |
| 204 | + |
| 205 | + // MistralAi should only register reflection hints, not serialization hints |
| 206 | + assertThat(runtimeHints.serialization().javaSerializationHints().count()).isEqualTo(0); |
| 207 | + } |
| 208 | + |
| 209 | + @Test |
| 210 | + void verifyResponseTypesAreRegistered() { |
| 211 | + RuntimeHints runtimeHints = new RuntimeHints(); |
| 212 | + MistralAiRuntimeHints mistralAiRuntimeHints = new MistralAiRuntimeHints(); |
| 213 | + mistralAiRuntimeHints.registerHints(runtimeHints, null); |
| 214 | + |
| 215 | + Set<TypeReference> registeredTypes = new HashSet<>(); |
| 216 | + runtimeHints.reflection().typeHints().forEach(typeHint -> registeredTypes.add(typeHint.getType())); |
| 217 | + |
| 218 | + // Verify response wrapper types are registered |
| 219 | + assertThat(registeredTypes.stream().anyMatch(tr -> tr.getName().contains("EmbeddingList"))) |
| 220 | + .as("EmbeddingList response type should be registered") |
| 221 | + .isTrue(); |
| 222 | + |
| 223 | + assertThat(registeredTypes.stream().anyMatch(tr -> tr.getName().contains("ChatCompletion"))) |
| 224 | + .as("ChatCompletion response type should be registered") |
| 225 | + .isTrue(); |
| 226 | + } |
| 227 | + |
| 228 | + @Test |
| 229 | + void verifyMultipleInstancesRegisterSameHints() { |
| 230 | + RuntimeHints runtimeHints1 = new RuntimeHints(); |
| 231 | + RuntimeHints runtimeHints2 = new RuntimeHints(); |
| 232 | + |
| 233 | + MistralAiRuntimeHints hints1 = new MistralAiRuntimeHints(); |
| 234 | + MistralAiRuntimeHints hints2 = new MistralAiRuntimeHints(); |
| 235 | + |
| 236 | + hints1.registerHints(runtimeHints1, null); |
| 237 | + hints2.registerHints(runtimeHints2, null); |
| 238 | + |
| 239 | + long count1 = runtimeHints1.reflection().typeHints().count(); |
| 240 | + long count2 = runtimeHints2.reflection().typeHints().count(); |
| 241 | + |
| 242 | + assertThat(count1).isEqualTo(count2); |
| 243 | + } |
| 244 | + |
177 | 245 | } |
0 commit comments