Skip to content

Commit 00ffc7e

Browse files
committed
Add unit tests for OpenAiStreamFunctionCallingHelper
Signed-off-by: Emmanuel Essien-nta <[email protected]>
1 parent 3919204 commit 00ffc7e

File tree

2 files changed

+166
-0
lines changed

2 files changed

+166
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@ shell.log
4545

4646
**/.claude/settings.local.json
4747
.devcontainer
48+
/models/spring-ai-openai/nbproject/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*
2+
* Copyright 2023-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.openai.api;
18+
19+
import java.util.Arrays;
20+
import java.util.Collections;
21+
import java.util.List;
22+
import java.util.function.Consumer;
23+
import static org.assertj.core.api.Assertions.assertThat;
24+
import org.junit.jupiter.api.Test;
25+
import org.mockito.Mockito;
26+
27+
/**
28+
* Unit tests for {@link OpenAiStreamFunctionCallingHelper}
29+
*
30+
* @author Emmanuel Essiennta
31+
*/
32+
public class OpenAiStreamFunctionCallingHelperTest {
33+
34+
private final OpenAiStreamFunctionCallingHelper helper = new OpenAiStreamFunctionCallingHelper();
35+
36+
@Test
37+
public void merge_whenInputIsValid() {
38+
var expectedResult = new OpenAiApi.ChatCompletionChunk("id", Collections.emptyList(),
39+
System.currentTimeMillis(), "model", "serviceTier", "fingerPrint", "object", null);
40+
var previous = new OpenAiApi.ChatCompletionChunk(null, null, expectedResult.created(), expectedResult.model(),
41+
expectedResult.serviceTier(), null, null, null);
42+
var current = new OpenAiApi.ChatCompletionChunk(expectedResult.id(), null, null, null, null,
43+
expectedResult.systemFingerprint(), expectedResult.object(), expectedResult.usage());
44+
45+
var result = helper.merge(previous, current);
46+
assertThat(result).isEqualTo(expectedResult);
47+
}
48+
49+
@Test
50+
public void isStreamingToolFunctionCall_whenChatCompletionChunkIsNull() {
51+
assertThat(helper.isStreamingToolFunctionCall(null)).isFalse();
52+
}
53+
54+
@Test
55+
public void isStreamingToolFunctionCall_whenChatCompletionChunkChoicesIsEmpty() {
56+
var chunk = new OpenAiApi.ChatCompletionChunk(null, Collections.emptyList(), null, null, null, null, null,
57+
null);
58+
assertThat(helper.isStreamingToolFunctionCall(chunk)).isFalse();
59+
}
60+
61+
@Test
62+
public void isStreamingToolFunctionCall_whenChatCompletionChunkFirstChoiceIsNull() {
63+
var choice = (org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice) null;
64+
var chunk = new OpenAiApi.ChatCompletionChunk(null, Arrays.asList(choice), null, null, null, null, null, null);
65+
assertThat(helper.isStreamingToolFunctionCall(chunk)).isFalse();
66+
}
67+
68+
@Test
69+
public void isStreamingToolFunctionCall_whenChatCompletionChunkFirstChoiceDeltaIsNull() {
70+
var choice = new org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice(null, null, null,
71+
Mockito.mock(OpenAiApi.LogProbs.class));
72+
var chunk = new OpenAiApi.ChatCompletionChunk(null, Arrays.asList(choice, null), null, null, null, null, null,
73+
null);
74+
assertThat(helper.isStreamingToolFunctionCall(chunk)).isFalse();
75+
}
76+
77+
@Test
78+
public void isStreamingToolFunctionCall_whenChatCompletionChunkFirstChoiceDeltaToolCallsIsNullOrEmpty() {
79+
var assertion = (Consumer<OpenAiApi.ChatCompletionMessage>) (OpenAiApi.ChatCompletionMessage delta) -> {
80+
var choice = new org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice(null, null,
81+
delta, Mockito.mock(OpenAiApi.LogProbs.class));
82+
var chunk = new OpenAiApi.ChatCompletionChunk(null, List.of(choice), null, null, null, null, null, null);
83+
assertThat(helper.isStreamingToolFunctionCall(chunk)).isFalse();
84+
};
85+
// Test for null.
86+
assertion.accept(new OpenAiApi.ChatCompletionMessage(null, null));
87+
// Test for empty.
88+
assertion.accept(
89+
new OpenAiApi.ChatCompletionMessage(null, null, null, null, Collections.emptyList(), null, null, null));
90+
}
91+
92+
@Test
93+
public void isStreamingToolFunctionCall_whenChatCompletionChunkFirstChoiceDeltaToolCallsIsNonEmpty() {
94+
var assertion = (Consumer<OpenAiApi.ChatCompletionMessage>) (OpenAiApi.ChatCompletionMessage delta) -> {
95+
var choice = new org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice(null, null,
96+
delta, null);
97+
var chunk = new OpenAiApi.ChatCompletionChunk(null, List.of(choice), null, null, null, null, null, null);
98+
assertThat(helper.isStreamingToolFunctionCall(chunk)).isTrue();
99+
};
100+
assertion.accept(new OpenAiApi.ChatCompletionMessage(null, null, null, null,
101+
List.of(Mockito.mock(org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage.ToolCall.class)),
102+
null, null, null));
103+
}
104+
105+
@Test
106+
public void isStreamingToolFunctionCallFinish_whenChatCompletionChunkIsNull() {
107+
assertThat(helper.isStreamingToolFunctionCallFinish(null)).isFalse();
108+
}
109+
110+
@Test
111+
public void isStreamingToolFunctionCallFinish_whenChatCompletionChunkChoicesIsEmpty() {
112+
var chunk = new OpenAiApi.ChatCompletionChunk(null, Collections.emptyList(), null, null, null, null, null,
113+
null);
114+
assertThat(helper.isStreamingToolFunctionCallFinish(chunk)).isFalse();
115+
}
116+
117+
@Test
118+
public void isStreamingToolFunctionCallFinish_whenChatCompletionChunkFirstChoiceIsNull() {
119+
var choice = (org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice) null;
120+
var chunk = new OpenAiApi.ChatCompletionChunk(null, Arrays.asList(choice), null, null, null, null, null, null);
121+
assertThat(helper.isStreamingToolFunctionCallFinish(chunk)).isFalse();
122+
}
123+
124+
@Test
125+
public void isStreamingToolFunctionCallFinish_whenChatCompletionChunkFirstChoiceDeltaIsNull() {
126+
var choice = new org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice(null, null, null,
127+
Mockito.mock(OpenAiApi.LogProbs.class));
128+
var chunk = new OpenAiApi.ChatCompletionChunk(null, Arrays.asList(choice, null), null, null, null, null, null,
129+
null);
130+
assertThat(helper.isStreamingToolFunctionCallFinish(chunk)).isFalse();
131+
}
132+
133+
@Test
134+
public void isStreamingToolFunctionCallFinish_whenChatCompletionChunkFirstChoiceIsNotToolCalls() {
135+
var choice = new org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice(null, null,
136+
new OpenAiApi.ChatCompletionMessage(null, null), Mockito.mock(OpenAiApi.LogProbs.class));
137+
var chunk = new OpenAiApi.ChatCompletionChunk(null, List.of(choice), null, null, null, null, null, null);
138+
assertThat(helper.isStreamingToolFunctionCallFinish(chunk)).isFalse();
139+
}
140+
141+
@Test
142+
public void isStreamingToolFunctionCallFinish_whenChatCompletionChunkFirstChoiceIsToolCalls() {
143+
var choice = new org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice(
144+
OpenAiApi.ChatCompletionFinishReason.TOOL_CALLS, null, new OpenAiApi.ChatCompletionMessage(null, null),
145+
Mockito.mock(OpenAiApi.LogProbs.class));
146+
var chunk = new OpenAiApi.ChatCompletionChunk(null, List.of(choice), null, null, null, null, null, null);
147+
assertThat(helper.isStreamingToolFunctionCallFinish(chunk)).isTrue();
148+
}
149+
150+
@Test
151+
public void chunkToChatCompletion_whenInputIsValid() {
152+
var choice1 = new org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice(
153+
OpenAiApi.ChatCompletionFinishReason.TOOL_CALLS, 1, new OpenAiApi.ChatCompletionMessage(null, null),
154+
Mockito.mock(OpenAiApi.LogProbs.class));
155+
var choice2 = new org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk.ChunkChoice(
156+
OpenAiApi.ChatCompletionFinishReason.TOOL_CALLS, 2, new OpenAiApi.ChatCompletionMessage(null, null),
157+
Mockito.mock(OpenAiApi.LogProbs.class));
158+
var chunk = new OpenAiApi.ChatCompletionChunk(null, List.of(choice1, choice2), null, null, null, null, null,
159+
null);
160+
OpenAiApi.ChatCompletion result = helper.chunkToChatCompletion(chunk);
161+
assertThat(result.object()).isEqualTo("chat.completion");
162+
assertThat(result.choices()).hasSize(2);
163+
}
164+
165+
}

0 commit comments

Comments
 (0)