Refactor StTemplateRenderer: rename supportStFunctions to validateStF… · spring-projects/spring-ai@0e15197 (original) (raw)

``

1

`+

/*

`

``

2

`+

`

``

3

`+

`

``

4

`+

`

``

5

`+

`

``

6

`+

`

``

7

`+

`

``

8

`+

`

``

9

`+

`

``

10

`+

`

``

11

`+

`

``

12

`+

`

``

13

`+

`

``

14

`+

`

``

15

`+

*/

`

``

16

+

``

17

`+

package org.springframework.ai.template.st;

`

``

18

+

``

19

`+

import static org.assertj.core.api.Assertions.assertThat;

`

``

20

+

``

21

`+

import java.util.HashMap;

`

``

22

`+

import java.util.Map;

`

``

23

+

``

24

`+

import org.junit.jupiter.api.Disabled;

`

``

25

`+

import org.junit.jupiter.api.Test;

`

``

26

`+

import org.springframework.ai.template.ValidationMode;

`

``

27

+

``

28

`+

/**

`

``

29

`+

`

``

30

`+

*/

`

``

31

`+

class StTemplateRendererEdgeTests {

`

``

32

+

``

33

`+

/**

`

``

34

`+

`

``

35

`+

*/

`

``

36

`+

@Test

`

``

37

`+

void shouldHandleMultipleBuiltInFunctionsAndVariables() {

`

``

38

`+

StTemplateRenderer renderer = StTemplateRenderer.builder().build();

`

``

39

`+

Map<String, Object> variables = new HashMap<>();

`

``

40

`+

variables.put("list", java.util.Arrays.asList("a", "b", "c"));

`

``

41

`+

variables.put("name", "Mark");

`

``

42

`+

String template = "{name}: {first(list)}, {last(list)}";

`

``

43

`+

String result = renderer.apply(template, variables);

`

``

44

`+

assertThat(result).isEqualTo("Mark: a, c");

`

``

45

`+

}

`

``

46

+

``

47

`+

/**

`

``

48

`+

`

``

49

`+

`

``

50

`+

*/

`

``

51

`+

@Test

`

``

52

`+

void shouldSupportValidNestedFunctionExpressionInST4() {

`

``

53

`+

Map<String, Object> variables = new HashMap<>();

`

``

54

`+

variables.put("words", java.util.Arrays.asList("hello", "WORLD"));

`

``

55

`+

String template = "{first(words)} {last(words)} {length(words)}";

`

``

56

`+

StTemplateRenderer defaultRenderer = StTemplateRenderer.builder().build();

`

``

57

`+

String defaultResult = defaultRenderer.apply(template, variables);

`

``

58

`+

assertThat(defaultResult).isEqualTo("hello WORLD 2");

`

``

59

`+

}

`

``

60

+

``

61

`+

/**

`

``

62

`+

`

``

63

`+

*/

`

``

64

`+

@Test

`

``

65

`+

void shouldHandleNestedBuiltInFunctions() {

`

``

66

`+

Map<String, Object> variables = new HashMap<>();

`

``

67

`+

variables.put("words", java.util.Arrays.asList("hello", "WORLD"));

`

``

68

`+

String template = "{first(words)} {last(words)} {length(words)}";

`

``

69

`+

StTemplateRenderer renderer = StTemplateRenderer.builder().validateStFunctions().build();

`

``

70

`+

String result = renderer.apply(template, variables);

`

``

71

`+

assertThat(result).isEqualTo("hello WORLD 2");

`

``

72

`+

}

`

``

73

+

``

74

`+

/**

`

``

75

`+

`

``

76

`+

*/

`

``

77

`+

@Test

`

``

78

`+

@Disabled("It is very hard to validate the template expression when using property style access of built-in functions ")

`

``

79

`+

void shouldSupportBuiltInFunctionsAsProperties() {

`

``

80

`+

Map<String, Object> variables = new HashMap<>();

`

``

81

`+

variables.put("words", java.util.Arrays.asList("hello", "WORLD"));

`

``

82

`+

String template = "{words.first} {words.last} {words.length}";

`

``

83

`+

StTemplateRenderer renderer = StTemplateRenderer.builder().build();

`

``

84

`+

String result = renderer.apply(template, variables);

`

``

85

`+

assertThat(result).isEqualTo("hello WORLD 2");

`

``

86

`+

}

`

``

87

+

``

88

`+

/**

`

``

89

`+

`

``

90

`+

*/

`

``

91

`+

@Test

`

``

92

`+

void shouldNotReportBuiltInFunctionsAsMissingVariablesInThrowMode() {

`

``

93

`+

StTemplateRenderer renderer = StTemplateRenderer.builder().validationMode(ValidationMode.THROW).build();

`

``

94

`+

Map<String, Object> variables = new HashMap<>();

`

``

95

`+

variables.put("memory", "abc");

`

``

96

`+

String template = "{if(strlen(memory))}ok{endif}";

`

``

97

`+

String result = renderer.apply(template, variables);

`

``

98

`+

assertThat(result).isEqualTo("ok");

`

``

99

`+

}

`

``

100

+

``

101

`+

/**

`

``

102

`+

`

``

103

`+

*/

`

``

104

`+

@Test

`

``

105

`+

void shouldNotReportBuiltInFunctionsAsMissingVariablesInWarnMode() {

`

``

106

`+

StTemplateRenderer renderer = StTemplateRenderer.builder().validationMode(ValidationMode.WARN).build();

`

``

107

`+

Map<String, Object> variables = new HashMap<>();

`

``

108

`+

variables.put("memory", "abc");

`

``

109

`+

String template = "{if(strlen(memory))}ok{endif}";

`

``

110

`+

String result = renderer.apply(template, variables);

`

``

111

`+

assertThat(result).isEqualTo("ok");

`

``

112

`+

}

`

``

113

+

``

114

`+

/**

`

``

115

`+

`

``

116

`+

*/

`

``

117

`+

@Test

`

``

118

`+

void shouldHandleVariableNamesSimilarToBuiltInFunctions() {

`

``

119

`+

StTemplateRenderer renderer = StTemplateRenderer.builder().build();

`

``

120

`+

Map<String, Object> variables = new HashMap<>();

`

``

121

`+

variables.put("lengthy", "foo");

`

``

122

`+

variables.put("firstName", "bar");

`

``

123

`+

String template = "{lengthy} {firstName}";

`

``

124

`+

String result = renderer.apply(template, variables);

`

``

125

`+

assertThat(result).isEqualTo("foo bar");

`

``

126

`+

}

`

``

127

+

``

128

`+

// --- Built-in Function Handling Tests END ---

`

``

129

+

``

130

`+

@Test

`

``

131

`+

void shouldRenderEscapedDelimiters() {

`

``

132

`+

StTemplateRenderer renderer = StTemplateRenderer.builder().build();

`

``

133

`+

Map<String, Object> variables = new HashMap<>();

`

``

134

`+

variables.put("x", "y");

`

``

135

`+

String template = "{x} \{foo\}";

`

``

136

`+

String result = renderer.apply(template, variables);

`

``

137

`+

assertThat(result).isEqualTo("y {foo}");

`

``

138

`+

}

`

``

139

+

``

140

`+

@Test

`

``

141

`+

void shouldRenderStaticTextTemplate() {

`

``

142

`+

StTemplateRenderer renderer = StTemplateRenderer.builder().build();

`

``

143

`+

Map<String, Object> variables = new HashMap<>();

`

``

144

`+

String template = "Just static text.";

`

``

145

`+

String result = renderer.apply(template, variables);

`

``

146

`+

assertThat(result).isEqualTo("Just static text.");

`

``

147

`+

}

`

``

148

+

``

149

`+

// Duplicate removed: shouldHandleVariableNamesSimilarToBuiltInFunctions

`

``

150

`+

// (now grouped at the top of the class)

`

``

151

+

``

152

`+

@Test

`

``

153

`+

void shouldHandleLargeNumberOfVariables() {

`

``

154

`+

StTemplateRenderer renderer = StTemplateRenderer.builder().build();

`

``

155

`+

Map<String, Object> variables = new HashMap<>();

`

``

156

`+

StringBuilder template = new StringBuilder();

`

``

157

`+

for (int i = 0; i < 100; i++) {

`

``

158

`+

String key = "var" + i;

`

``

159

`+

variables.put(key, i);

`

``

160

`+

template.append("{" + key + "} ");

`

``

161

`+

}

`

``

162

`+

String result = renderer.apply(template.toString().trim(), variables);

`

``

163

`+

StringBuilder expected = new StringBuilder();

`

``

164

`+

for (int i = 0; i < 100; i++) {

`

``

165

`+

expected.append(i).append(" ");

`

``

166

`+

}

`

``

167

`+

assertThat(result).isEqualTo(expected.toString().trim());

`

``

168

`+

}

`

``

169

+

``

170

`+

@Test

`

``

171

`+

void shouldRenderUnicodeAndSpecialCharacters() {

`

``

172

`+

StTemplateRenderer renderer = StTemplateRenderer.builder().build();

`

``

173

`+

Map<String, Object> variables = new HashMap<>();

`

``

174

`+

variables.put("emoji", "😀");

`

``

175

`+

variables.put("accented", "Café");

`

``

176

`+

String template = "{emoji} {accented}";

`

``

177

`+

String result = renderer.apply(template, variables);

`

``

178

`+

assertThat(result).isEqualTo("😀 Café");

`

``

179

`+

}

`

``

180

+

``

181

`+

@Test

`

``

182

`+

void shouldRenderNullVariableValuesAsBlank() {

`

``

183

`+

StTemplateRenderer renderer = StTemplateRenderer.builder().build();

`

``

184

`+

Map<String, Object> variables = new HashMap<>();

`

``

185

`+

variables.put("foo", null);

`

``

186

`+

String template = "Value: {foo}";

`

``

187

`+

String result = renderer.apply(template, variables);

`

``

188

`+

assertThat(result).isEqualTo("Value: ");

`

``

189

`+

}

`

``

190

+

``

191

`+

}

`