Skip to content

Commit 807b778

Browse files
committed
Update topenAIMessages.m
Adding negative tests to increase code coverage in openAIMessages/validateAssistantWithToolCalls
1 parent fa61f1f commit 807b778

File tree

1 file changed

+175
-128
lines changed

1 file changed

+175
-128
lines changed

tests/topenAIMessages.m

Lines changed: 175 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
% Copyright 2023-2024 The MathWorks, Inc.
55

66
properties(TestParameter)
7-
InvalidInputsUserPrompt = iGetInvalidInputsUserPrompt;
8-
InvalidInputsUserImagesPrompt = iGetInvalidInputsUserImagesPrompt;
9-
InvalidInputsFunctionPrompt = iGetInvalidFunctionPrompt;
10-
InvalidInputsSystemPrompt = iGetInvalidInputsSystemPrompt;
11-
InvalidInputsResponseMessage = iGetInvalidInputsResponseMessage;
12-
InvalidRemoveMessage = iGetInvalidRemoveMessage;
7+
InvalidInputsUserPrompt = iGetInvalidInputsUserPrompt();
8+
InvalidInputsUserImagesPrompt = iGetInvalidInputsUserImagesPrompt();
9+
InvalidInputsFunctionPrompt = iGetInvalidFunctionPrompt();
10+
InvalidInputsSystemPrompt = iGetInvalidInputsSystemPrompt();
11+
InvalidInputsResponseMessage = iGetInvalidInputsResponseMessage();
12+
InvalidRemoveMessage = iGetInvalidRemoveMessage();
13+
InvalidFuncCallsCases = iGetInvalidFuncCallsCases()
1314
ValidTextInput = {"This is okay"; 'this is ok'};
1415
end
1516

@@ -92,6 +93,41 @@ function assistantToolCallMessageIsAdded(testCase)
9293
testCase.verifyEqual(msgs.Messages{1}.tool_calls{1}, toolCallPrompt.tool_calls);
9394
end
9495

96+
function errorsAssistantWithWithoutToolCallId(testCase)
97+
msgs = openAIMessages;
98+
functionName = "functionName";
99+
args = "{""arg1"": 1, ""arg2"": 2, ""arg3"": ""3""}";
100+
funCall = struct("name", functionName, "arguments", args);
101+
toolCall = struct("type", "function", "function", funCall);
102+
toolCallPrompt = struct("role", "assistant", "content", "", "tool_calls", []);
103+
% tool_calls is an array of struct in API response
104+
toolCallPrompt.tool_calls = toolCall;
105+
106+
testCase.verifyError(@()addResponseMessage(msgs, toolCallPrompt), "llms:mustBeAssistantWithIdAndFunction");
107+
end
108+
109+
function errorsAssistantWithToolCallsWithoutNameOrArgs(testCase, InvalidFuncCallsCases)
110+
msgs = openAIMessages;
111+
funCall = InvalidFuncCallsCases.FunCallStruct;
112+
toolCall = struct("id", "123", "type", "function", "function", funCall);
113+
toolCallPrompt = struct("role", "assistant", "content", "", "tool_calls", []);
114+
% tool_calls is an array of struct in API response
115+
toolCallPrompt.tool_calls = toolCall;
116+
117+
testCase.verifyError(@()addResponseMessage(msgs, toolCallPrompt), InvalidFuncCallsCases.Error);
118+
end
119+
120+
function errorsAssistantWithWithNonTextNameAndArguments(testCase)
121+
msgs = openAIMessages;
122+
funCall = struct("name", 1, "arguments", 2);
123+
toolCall = struct("id", "123", "type", "function", "function", funCall);
124+
toolCallPrompt = struct("role", "assistant", "content", "", "tool_calls", []);
125+
% tool_calls is an array of struct in API response
126+
toolCallPrompt.tool_calls = toolCall;
127+
128+
testCase.verifyError(@()addResponseMessage(msgs, toolCallPrompt), "llms:assistantMustHaveTextNameAndArguments");
129+
end
130+
95131
function assistantToolCallMessageWithoutArgsIsAdded(testCase)
96132
msgs = openAIMessages;
97133
functionName = "functionName";
@@ -178,136 +214,147 @@ function invalidInputsResponsePrompt(testCase, InvalidInputsResponseMessage)
178214
end
179215
end
180216

181-
function invalidInputsSystemPrompt = iGetInvalidInputsSystemPrompt
182-
invalidInputsSystemPrompt = struct( ...
183-
"NonStringInputName", ...
184-
struct("Input", {{123, "content"}}, ...
185-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
186-
...
187-
"NonStringInputContent", ...
188-
struct("Input", {{"name", 123}}, ...
189-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
190-
...
191-
"EmptytName", ...
192-
struct("Input", {{"", "content"}}, ...
193-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
194-
...
195-
"EmptytContent", ...
196-
struct("Input", {{"name", ""}}, ...
197-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
198-
...
199-
"NonScalarInputName", ...
200-
struct("Input", {{["name1" "name2"], "content"}}, ...
201-
"Error", "MATLAB:validators:mustBeTextScalar"),...
202-
...
203-
"NonScalarInputContent", ...
204-
struct("Input", {{"name", ["content1", "content2"]}}, ...
205-
"Error", "MATLAB:validators:mustBeTextScalar"));
217+
function invalidInputsSystemPrompt = iGetInvalidInputsSystemPrompt()
218+
invalidInputsSystemPrompt = struct( ...
219+
"NonStringInputName", ...
220+
struct("Input", {{123, "content"}}, ...
221+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
222+
...
223+
"NonStringInputContent", ...
224+
struct("Input", {{"name", 123}}, ...
225+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
226+
...
227+
"EmptytName", ...
228+
struct("Input", {{"", "content"}}, ...
229+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
230+
...
231+
"EmptytContent", ...
232+
struct("Input", {{"name", ""}}, ...
233+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
234+
...
235+
"NonScalarInputName", ...
236+
struct("Input", {{["name1" "name2"], "content"}}, ...
237+
"Error", "MATLAB:validators:mustBeTextScalar"),...
238+
...
239+
"NonScalarInputContent", ...
240+
struct("Input", {{"name", ["content1", "content2"]}}, ...
241+
"Error", "MATLAB:validators:mustBeTextScalar"));
242+
end
243+
244+
function invalidInputsUserPrompt = iGetInvalidInputsUserPrompt()
245+
invalidInputsUserPrompt = struct( ...
246+
"NonStringInput", ...
247+
struct("Input", {{123}}, ...
248+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
249+
...
250+
"NonScalarInput", ...
251+
struct("Input", {{["prompt1" "prompt2"]}}, ...
252+
"Error", "MATLAB:validators:mustBeTextScalar"), ...
253+
...
254+
"EmptyInput", ...
255+
struct("Input", {{""}}, ...
256+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"));
206257
end
207258

208-
function invalidInputsUserPrompt = iGetInvalidInputsUserPrompt
209-
invalidInputsUserPrompt = struct( ...
210-
"NonStringInput", ...
211-
struct("Input", {{123}}, ...
212-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
213-
...
214-
"NonScalarInput", ...
215-
struct("Input", {{["prompt1" "prompt2"]}}, ...
216-
"Error", "MATLAB:validators:mustBeTextScalar"), ...
217-
...
218-
"EmptyInput", ...
219-
struct("Input", {{""}}, ...
220-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"));
259+
function invalidInputsUserImagesPrompt = iGetInvalidInputsUserImagesPrompt()
260+
invalidInputsUserImagesPrompt = struct( ...
261+
"NonStringInput", ...
262+
struct("Input", {{123, "peppers.png"}}, ...
263+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
264+
...
265+
"NonScalarInput", ...
266+
struct("Input", {{["prompt1" "prompt2"], "peppers.png"}}, ...
267+
"Error", "MATLAB:validators:mustBeTextScalar"), ...
268+
...
269+
"EmptyInput", ...
270+
struct("Input", {{"", "peppers.png"}}, ...
271+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
272+
...
273+
"NonTextImage", ...
274+
struct("Input", {{"prompt", 123}}, ...
275+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"),...
276+
...
277+
"EmptyImageName", ...
278+
struct("Input", {{"prompt", 123}}, ...
279+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"),...
280+
...
281+
"InvalidDetail", ...
282+
struct("Input", {{"prompt", "peppers.png", "Detail", "invalid"}}, ...
283+
"Error", "MATLAB:validators:mustBeMember"));
221284
end
222285

223-
function invalidInputsUserImagesPrompt = iGetInvalidInputsUserImagesPrompt
224-
invalidInputsUserImagesPrompt = struct( ...
225-
"NonStringInput", ...
226-
struct("Input", {{123, "peppers.png"}}, ...
227-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
228-
...
229-
"NonScalarInput", ...
230-
struct("Input", {{["prompt1" "prompt2"], "peppers.png"}}, ...
231-
"Error", "MATLAB:validators:mustBeTextScalar"), ...
232-
...
233-
"EmptyInput", ...
234-
struct("Input", {{"", "peppers.png"}}, ...
235-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
236-
...
237-
"NonTextImage", ...
238-
struct("Input", {{"prompt", 123}}, ...
239-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"),...
240-
...
241-
"EmptyImageName", ...
242-
struct("Input", {{"prompt", 123}}, ...
243-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"),...
244-
...
245-
"InvalidDetail", ...
246-
struct("Input", {{"prompt", "peppers.png", "Detail", "invalid"}}, ...
247-
"Error", "MATLAB:validators:mustBeMember"));
286+
function invalidFunctionPrompt = iGetInvalidFunctionPrompt()
287+
invalidFunctionPrompt = struct( ...
288+
"NonStringInputName", ...
289+
struct("Input", {{"123", 123, "content"}}, ...
290+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
291+
...
292+
"NonStringInputContent", ...
293+
struct("Input", {{"123", "name", 123}}, ...
294+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
295+
...
296+
"EmptytName", ...
297+
struct("Input", {{"123", "", "content"}}, ...
298+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
299+
...
300+
"EmptytContent", ...
301+
struct("Input", {{"123", "name", ""}}, ...
302+
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
303+
...
304+
"NonScalarInputName", ...
305+
struct("Input", {{"123", ["name1" "name2"], "content"}}, ...
306+
"Error", "MATLAB:validators:mustBeTextScalar"),...
307+
...
308+
"NonScalarInputContent", ...
309+
struct("Input", {{"123","name", ["content1", "content2"]}}, ...
310+
"Error", "MATLAB:validators:mustBeTextScalar"));
248311
end
249312

250-
function invalidFunctionPrompt = iGetInvalidFunctionPrompt
251-
invalidFunctionPrompt = struct( ...
252-
"NonStringInputName", ...
253-
struct("Input", {{"123", 123, "content"}}, ...
254-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
255-
...
256-
"NonStringInputContent", ...
257-
struct("Input", {{"123", "name", 123}}, ...
258-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
259-
...
260-
"EmptytName", ...
261-
struct("Input", {{"123", "", "content"}}, ...
262-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
263-
...
264-
"EmptytContent", ...
265-
struct("Input", {{"123", "name", ""}}, ...
266-
"Error", "MATLAB:validators:mustBeNonzeroLengthText"), ...
267-
...
268-
"NonScalarInputName", ...
269-
struct("Input", {{"123", ["name1" "name2"], "content"}}, ...
270-
"Error", "MATLAB:validators:mustBeTextScalar"),...
271-
...
272-
"NonScalarInputContent", ...
273-
struct("Input", {{"123","name", ["content1", "content2"]}}, ...
274-
"Error", "MATLAB:validators:mustBeTextScalar"));
313+
function invalidRemoveMessage = iGetInvalidRemoveMessage()
314+
invalidRemoveMessage = struct( ...
315+
"NonInteger", ...
316+
struct("Input", {{0.5}}, ...
317+
"Error", "MATLAB:validators:mustBeInteger"), ...
318+
...
319+
"NonPositive", ...
320+
struct("Input", {{0}}, ...
321+
"Error", "MATLAB:validators:mustBePositive"), ...
322+
...
323+
"NonScalarInput", ...
324+
struct("Input", {{[1 2]}}, ...
325+
"Error", "MATLAB:validation:IncompatibleSize"));
275326
end
276327

277-
function invalidRemoveMessage = iGetInvalidRemoveMessage
278-
invalidRemoveMessage = struct( ...
279-
"NonInteger", ...
280-
struct("Input", {{0.5}}, ...
281-
"Error", "MATLAB:validators:mustBeInteger"), ...
282-
...
283-
"NonPositive", ...
284-
struct("Input", {{0}}, ...
285-
"Error", "MATLAB:validators:mustBePositive"), ...
286-
...
287-
"NonScalarInput", ...
288-
struct("Input", {{[1 2]}}, ...
289-
"Error", "MATLAB:validation:IncompatibleSize"));
328+
function invalidInputsResponseMessage = iGetInvalidInputsResponseMessage()
329+
invalidInputsResponseMessage = struct( ...
330+
"NonStructInput", ...
331+
struct("Input", {{123}},...
332+
"Error", "MATLAB:validation:UnableToConvert"),...
333+
...
334+
"NonExistentRole", ...
335+
struct("Input", {{struct("role", "123", "content", "123")}},...
336+
"Error", "llms:mustBeAssistantCall"),...
337+
...
338+
"NonExistentContent", ...
339+
struct("Input", {{struct("role", "assistant")}},...
340+
"Error", "llms:mustBeAssistantCall"),...
341+
...
342+
"EmptyContent", ...
343+
struct("Input", {{struct("role", "assistant", "content", "")}},...
344+
"Error", "llms:mustBeAssistantWithContent"),...
345+
...
346+
"NonScalarContent", ...
347+
struct("Input", {{struct("role", "assistant", "content", ["a", "b"])}},...
348+
"Error", "llms:mustBeAssistantWithContent"));
290349
end
291350

292-
function invalidInputsResponseMessage = iGetInvalidInputsResponseMessage
293-
invalidInputsResponseMessage = struct( ...
294-
"NonStructInput", ...
295-
struct("Input", {{123}},...
296-
"Error", "MATLAB:validation:UnableToConvert"),...
297-
...
298-
"NonExistentRole", ...
299-
struct("Input", {{struct("role", "123", "content", "123")}},...
300-
"Error", "llms:mustBeAssistantCall"),...
301-
...
302-
"NonExistentContent", ...
303-
struct("Input", {{struct("role", "assistant")}},...
304-
"Error", "llms:mustBeAssistantCall"),...
305-
...
306-
"EmptyContent", ...
307-
struct("Input", {{struct("role", "assistant", "content", "")}},...
308-
"Error", "llms:mustBeAssistantWithContent"),...
309-
...
310-
"NonScalarContent", ...
311-
struct("Input", {{struct("role", "assistant", "content", ["a", "b"])}},...
312-
"Error", "llms:mustBeAssistantWithContent"));
351+
function invalidFuncCallsCases = iGetInvalidFuncCallsCases()
352+
invalidFuncCallsCases = struct( ...
353+
"NoArguments", ...
354+
struct("FunCallStruct", struct("name", "functionName"),...
355+
"Error", "llms:mustBeAssistantWithNameAndArguments"),...
356+
...
357+
"NoName", ...
358+
struct("FunCallStruct", struct("arguments", "{""arg1"": 1, ""arg2"": 2, ""arg3"": ""3""}"), ...
359+
"Error", "llms:mustBeAssistantWithNameAndArguments"));
313360
end

0 commit comments

Comments
 (0)