2121import org .springframework .ai .tool .ToolCallback ;
2222import org .springframework .ai .tool .definition .ToolDefinition ;
2323import org .springframework .aot .hint .RuntimeHints ;
24+ import org .springframework .aot .hint .TypeReference ;
25+
26+ import java .util .HashSet ;
27+ import java .util .Set ;
2428
2529import static org .assertj .core .api .Assertions .assertThat ;
30+ import static org .assertj .core .api .Assertions .assertThatCode ;
2631import static org .springframework .aot .hint .predicate .RuntimeHintsPredicates .reflection ;
2732import static org .springframework .aot .hint .predicate .RuntimeHintsPredicates .resource ;
2833
@@ -42,4 +47,97 @@ void core() {
4247 assertThat (runtimeHints ).matches (reflection ().onType (ToolDefinition .class ));
4348 }
4449
50+ @ Test
51+ void registerHintsWithNullClassLoader () {
52+ var runtimeHints = new RuntimeHints ();
53+ var springAiCore = new SpringAiCoreRuntimeHints ();
54+
55+ // Should not throw exception with null ClassLoader
56+ assertThatCode (() -> springAiCore .registerHints (runtimeHints , null )).doesNotThrowAnyException ();
57+ }
58+
59+ @ Test
60+ void verifyEmbeddingResourceIsRegistered () {
61+ var runtimeHints = new RuntimeHints ();
62+ var springAiCore = new SpringAiCoreRuntimeHints ();
63+ springAiCore .registerHints (runtimeHints , null );
64+
65+ // Verify the specific embedding properties file is registered
66+ assertThat (runtimeHints ).matches (resource ().forResource ("embedding/embedding-model-dimensions.properties" ));
67+ }
68+
69+ @ Test
70+ void verifyToolReflectionHintsAreRegistered () {
71+ var runtimeHints = new RuntimeHints ();
72+ var springAiCore = new SpringAiCoreRuntimeHints ();
73+ springAiCore .registerHints (runtimeHints , null );
74+
75+ Set <TypeReference > registeredTypes = new HashSet <>();
76+ runtimeHints .reflection ().typeHints ().forEach (typeHint -> registeredTypes .add (typeHint .getType ()));
77+
78+ // Verify core tool classes are registered
79+ assertThat (registeredTypes .contains (TypeReference .of (ToolCallback .class ))).isTrue ();
80+ assertThat (registeredTypes .contains (TypeReference .of (ToolDefinition .class ))).isTrue ();
81+ }
82+
83+ @ Test
84+ void verifyResourceAndReflectionHintsSeparately () {
85+ var runtimeHints = new RuntimeHints ();
86+ var springAiCore = new SpringAiCoreRuntimeHints ();
87+ springAiCore .registerHints (runtimeHints , null );
88+
89+ // Test resource hints
90+ assertThat (runtimeHints ).matches (resource ().forResource ("embedding/embedding-model-dimensions.properties" ));
91+
92+ // Test reflection hints
93+ assertThat (runtimeHints ).matches (reflection ().onType (ToolCallback .class ));
94+ assertThat (runtimeHints ).matches (reflection ().onType (ToolDefinition .class ));
95+ }
96+
97+ @ Test
98+ void verifyMultipleRegistrationCallsAreIdempotent () {
99+ var runtimeHints1 = new RuntimeHints ();
100+ var runtimeHints2 = new RuntimeHints ();
101+ var springAiCore = new SpringAiCoreRuntimeHints ();
102+
103+ // Register hints on two separate RuntimeHints instances
104+ springAiCore .registerHints (runtimeHints1 , null );
105+ springAiCore .registerHints (runtimeHints2 , null );
106+
107+ // Both should have the same hints registered
108+ assertThat (runtimeHints1 ).matches (resource ().forResource ("embedding/embedding-model-dimensions.properties" ));
109+ assertThat (runtimeHints2 ).matches (resource ().forResource ("embedding/embedding-model-dimensions.properties" ));
110+
111+ assertThat (runtimeHints1 ).matches (reflection ().onType (ToolCallback .class ));
112+ assertThat (runtimeHints2 ).matches (reflection ().onType (ToolCallback .class ));
113+ }
114+
115+ @ Test
116+ void verifyResourceHintsForIncorrectPaths () {
117+ var runtimeHints = new RuntimeHints ();
118+ var springAiCore = new SpringAiCoreRuntimeHints ();
119+ springAiCore .registerHints (runtimeHints , null );
120+
121+ // Verify the exact resource path is registered
122+ assertThat (runtimeHints ).matches (resource ().forResource ("embedding/embedding-model-dimensions.properties" ));
123+
124+ // Verify that similar but incorrect paths are not matched
125+ assertThat (runtimeHints ).doesNotMatch (resource ().forResource ("embedding-model-dimensions.properties" ));
126+ assertThat (runtimeHints ).doesNotMatch (resource ().forResource ("embedding/model-dimensions.properties" ));
127+ }
128+
129+ @ Test
130+ void ensureBothResourceAndReflectionHintsArePresent () {
131+ var runtimeHints = new RuntimeHints ();
132+ var springAiCore = new SpringAiCoreRuntimeHints ();
133+ springAiCore .registerHints (runtimeHints , null );
134+
135+ // Ensure both resource and reflection hints are registered
136+ boolean hasResourceHints = runtimeHints .resources () != null ;
137+ boolean hasReflectionHints = runtimeHints .reflection ().typeHints ().spliterator ().estimateSize () > 0 ;
138+
139+ assertThat (hasResourceHints ).isTrue ();
140+ assertThat (hasReflectionHints ).isTrue ();
141+ }
142+
45143}
0 commit comments