@@ -297,4 +297,60 @@ void shouldRenderTemplateWithBuiltInFunctions() {
297
297
assertThat (result ).isEqualTo ("Hello!" );
298
298
}
299
299
300
+ /**
301
+ * Tests that property access syntax like {test.name} is correctly handled. The
302
+ * top-level variable 'test' should be identified as required, but 'name' should not.
303
+ */
304
+ @ Test
305
+ void shouldHandlePropertyAccessSyntax () {
306
+ StTemplateRenderer renderer = StTemplateRenderer .builder ().build ();
307
+ Map <String , Object > variables = new HashMap <>();
308
+ variables .put ("test" , Map .of ("name" , "Spring AI" ));
309
+
310
+ String result = renderer .apply ("Hello {test.name}!" , variables );
311
+
312
+ assertThat (result ).isEqualTo ("Hello Spring AI!" );
313
+ }
314
+
315
+ /**
316
+ * Tests that deep property access syntax like {test.tom.name} is correctly handled.
317
+ * Only the top-level variable 'test' should be identified as required.
318
+ */
319
+ @ Test
320
+ void shouldHandleDeepPropertyAccessSyntax () {
321
+ StTemplateRenderer renderer = StTemplateRenderer .builder ().build ();
322
+ Map <String , Object > variables = new HashMap <>();
323
+ variables .put ("test" , Map .of ("tom" , Map .of ("name" , "Spring AI" )));
324
+
325
+ String result = renderer .apply ("Hello {test.tom.name}!" , variables );
326
+
327
+ assertThat (result ).isEqualTo ("Hello Spring AI!" );
328
+ }
329
+
330
+ /**
331
+ * Tests validation behavior with property access syntax. Should only require the
332
+ * top-level variable, not the property names.
333
+ */
334
+ @ Test
335
+ void shouldValidatePropertyAccessCorrectly () {
336
+ StTemplateRenderer renderer = StTemplateRenderer .builder ().build ();
337
+ Map <String , Object > variables = new HashMap <>();
338
+ // Only provide the top-level variable, not the properties
339
+ variables .put ("user" , Map .of ("profile" , Map .of ("name" , "John" )));
340
+
341
+ // This should work fine since we provide the required top-level variable
342
+ String result = renderer .apply ("Hello {user.profile.name}!" , variables );
343
+ assertThat (result ).isEqualTo ("Hello John!" );
344
+
345
+ // Test with missing top-level variable - should throw exception
346
+ Map <String , Object > missingVariables = new HashMap <>();
347
+ // Wrong: providing nested variable instead of top-level
348
+ missingVariables .put ("profile" , Map .of ("name" , "John" ));
349
+
350
+ assertThatThrownBy (() -> renderer .apply ("Hello {user.profile.name}!" , missingVariables ))
351
+ .isInstanceOf (IllegalStateException .class )
352
+ .hasMessageContaining (
353
+ "Not all variables were replaced in the template. Missing variable names are: [user]" );
354
+ }
355
+
300
356
}
0 commit comments