Skip to content

Commit 22f1d8f

Browse files
alxkmWillam2004
authored andcommitted
test: Enhance test coverage for tool execution components (spring-projects#4268)
* test: Enhance test coverage for tool execution components * style: fix formatting Signed-off-by: Oleksandr Klymenko <[email protected]> Signed-off-by: 家娃 <[email protected]>
1 parent 92a856c commit 22f1d8f

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

spring-ai-model/src/test/java/org/springframework/ai/model/tool/DefaultToolExecutionResultTests.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.ai.model.tool;
1818

1919
import java.util.ArrayList;
20+
import java.util.List;
2021

2122
import org.junit.jupiter.api.Test;
2223

@@ -190,4 +191,34 @@ void whenEqualsAndHashCodeAreConsistent() {
190191
assertThat(result1.hashCode()).isEqualTo(result2.hashCode());
191192
}
192193

194+
@Test
195+
void whenConversationHistoryIsImmutableList() {
196+
List<Message> conversationHistory = List.of(new org.springframework.ai.chat.messages.UserMessage("Hello"),
197+
new org.springframework.ai.chat.messages.UserMessage("Hi!"));
198+
199+
var result = DefaultToolExecutionResult.builder()
200+
.conversationHistory(conversationHistory)
201+
.returnDirect(false)
202+
.build();
203+
204+
assertThat(result.conversationHistory()).hasSize(2);
205+
assertThat(result.conversationHistory()).isEqualTo(conversationHistory);
206+
}
207+
208+
@Test
209+
void whenReturnDirectIsChangedMultipleTimes() {
210+
var conversationHistory = new ArrayList<Message>();
211+
conversationHistory.add(new org.springframework.ai.chat.messages.UserMessage("Test"));
212+
213+
var builder = DefaultToolExecutionResult.builder()
214+
.conversationHistory(conversationHistory)
215+
.returnDirect(true)
216+
.returnDirect(false)
217+
.returnDirect(true);
218+
219+
var result = builder.build();
220+
221+
assertThat(result.returnDirect()).isTrue();
222+
}
223+
193224
}

spring-ai-model/src/test/java/org/springframework/ai/model/tool/ToolExecutionEligibilityPredicateTests.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.ai.model.tool;
1818

19+
import java.util.Collections;
1920
import java.util.List;
2021

2122
import org.junit.jupiter.api.Test;
@@ -75,6 +76,32 @@ void whenTestMethodCalledDirectly() {
7576
assertThat(result).isTrue();
7677
}
7778

79+
@Test
80+
void whenChatResponseHasEmptyGenerations() {
81+
ToolExecutionEligibilityPredicate predicate = new TestToolExecutionEligibilityPredicate();
82+
ChatOptions promptOptions = ChatOptions.builder().build();
83+
ChatResponse emptyResponse = new ChatResponse(Collections.emptyList());
84+
85+
boolean result = predicate.isToolExecutionRequired(promptOptions, emptyResponse);
86+
assertThat(result).isTrue();
87+
}
88+
89+
@Test
90+
void whenChatOptionsHasModel() {
91+
ModelCheckingPredicate predicate = new ModelCheckingPredicate();
92+
93+
ChatOptions optionsWithModel = ChatOptions.builder().model("gpt-4").build();
94+
95+
ChatResponse chatResponse = new ChatResponse(List.of(new Generation(new AssistantMessage("test"))));
96+
97+
boolean result = predicate.isToolExecutionRequired(optionsWithModel, chatResponse);
98+
assertThat(result).isTrue();
99+
100+
ChatOptions optionsWithoutModel = ChatOptions.builder().build();
101+
result = predicate.isToolExecutionRequired(optionsWithoutModel, chatResponse);
102+
assertThat(result).isFalse();
103+
}
104+
78105
/**
79106
* Test implementation of {@link ToolExecutionEligibilityPredicate} that always
80107
* returns true.
@@ -88,4 +115,13 @@ public boolean test(ChatOptions promptOptions, ChatResponse chatResponse) {
88115

89116
}
90117

118+
private static class ModelCheckingPredicate implements ToolExecutionEligibilityPredicate {
119+
120+
@Override
121+
public boolean test(ChatOptions promptOptions, ChatResponse chatResponse) {
122+
return promptOptions.getModel() != null && !promptOptions.getModel().isEmpty();
123+
}
124+
125+
}
126+
91127
}

spring-ai-model/src/test/java/org/springframework/ai/model/tool/ToolExecutionResultTests.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.ai.chat.messages.UserMessage;
2626

2727
import static org.assertj.core.api.Assertions.assertThat;
28+
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
2829

2930
/**
3031
* Unit tests for {@link ToolExecutionResult}.
@@ -80,4 +81,63 @@ void whenMultipleToolCallsThenMultipleGenerations() {
8081
assertThat(generations.get(1).getMetadata().getFinishReason()).isEqualTo(ToolExecutionResult.FINISH_REASON);
8182
}
8283

84+
@Test
85+
void whenEmptyConversationHistoryThenThrowsException() {
86+
var toolExecutionResult = ToolExecutionResult.builder().conversationHistory(List.of()).build();
87+
88+
assertThatThrownBy(() -> ToolExecutionResult.buildGenerations(toolExecutionResult))
89+
.isInstanceOf(ArrayIndexOutOfBoundsException.class);
90+
}
91+
92+
@Test
93+
void whenToolResponseWithEmptyResponseListThenEmptyGenerations() {
94+
var toolExecutionResult = ToolExecutionResult.builder()
95+
.conversationHistory(
96+
List.of(new AssistantMessage("Processing request"), new ToolResponseMessage(List.of())))
97+
.build();
98+
99+
var generations = ToolExecutionResult.buildGenerations(toolExecutionResult);
100+
101+
assertThat(generations).isEmpty();
102+
}
103+
104+
@Test
105+
void whenToolResponseWithNullContentThenGenerationWithNullText() {
106+
var toolExecutionResult = ToolExecutionResult.builder()
107+
.conversationHistory(
108+
List.of(new ToolResponseMessage(List.of(new ToolResponseMessage.ToolResponse("1", "tool", null)))))
109+
.build();
110+
111+
var generations = ToolExecutionResult.buildGenerations(toolExecutionResult);
112+
113+
assertThat(generations).hasSize(1);
114+
assertThat(generations.get(0).getOutput().getText()).isNull();
115+
}
116+
117+
@Test
118+
void whenToolResponseWithEmptyStringContentThenGenerationWithEmptyText() {
119+
var toolExecutionResult = ToolExecutionResult.builder()
120+
.conversationHistory(
121+
List.of(new ToolResponseMessage(List.of(new ToolResponseMessage.ToolResponse("1", "tool", "")))))
122+
.build();
123+
124+
var generations = ToolExecutionResult.buildGenerations(toolExecutionResult);
125+
126+
assertThat(generations).hasSize(1);
127+
assertThat(generations.get(0).getOutput().getText()).isEmpty();
128+
assertThat((String) generations.get(0).getMetadata().get(ToolExecutionResult.METADATA_TOOL_NAME))
129+
.isEqualTo("tool");
130+
}
131+
132+
@Test
133+
void whenBuilderCalledWithoutConversationHistoryThenThrowsException() {
134+
var toolExecutionResult = ToolExecutionResult.builder().build();
135+
136+
assertThatThrownBy(() -> ToolExecutionResult.buildGenerations(toolExecutionResult))
137+
.isInstanceOf(ArrayIndexOutOfBoundsException.class);
138+
139+
assertThat(toolExecutionResult.conversationHistory()).isNotNull();
140+
assertThat(toolExecutionResult.conversationHistory()).isEmpty();
141+
}
142+
83143
}

0 commit comments

Comments
 (0)