Skip to content

Commit 0364636

Browse files
jozkeejeffhandley
authored andcommitted
Add test for optional parameters being required with RequireAllProperties (#6265)
* Add test for optional parameters being required with RequireAllProperties * Test both requireAllProperties values * Use AssertDeepEquals that logs the difference to other tests
1 parent 4f467ce commit 0364636

File tree

1 file changed

+79
-6
lines changed

1 file changed

+79
-6
lines changed

test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Utilities/AIJsonUtilitiesTests.cs

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public static void CreateJsonSchema_DefaultParameters_GeneratesExpectedJsonSchem
159159

160160
JsonElement actual = AIJsonUtilities.CreateJsonSchema(typeof(MyPoco), serializerOptions: JsonContext.Default.Options);
161161

162-
Assert.True(DeepEquals(expected, actual));
162+
AssertDeepEquals(expected, actual);
163163
}
164164

165165
[Fact]
@@ -204,7 +204,7 @@ public static void CreateJsonSchema_OverriddenParameters_GeneratesExpectedJsonSc
204204
serializerOptions: JsonContext.Default.Options,
205205
inferenceOptions: inferenceOptions);
206206

207-
Assert.True(DeepEquals(expected, actual));
207+
AssertDeepEquals(expected, actual);
208208
}
209209

210210
[Fact]
@@ -249,7 +249,7 @@ public static void CreateJsonSchema_UserDefinedTransformer()
249249

250250
JsonElement actual = AIJsonUtilities.CreateJsonSchema(typeof(MyPoco), serializerOptions: JsonContext.Default.Options, inferenceOptions: inferenceOptions);
251251

252-
Assert.True(DeepEquals(expected, actual));
252+
AssertDeepEquals(expected, actual);
253253
}
254254

255255
[Fact]
@@ -277,7 +277,7 @@ public static void CreateJsonSchema_FiltersDisallowedKeywords()
277277

278278
JsonElement actual = AIJsonUtilities.CreateJsonSchema(typeof(PocoWithTypesWithOpenAIUnsupportedKeywords), serializerOptions: JsonContext.Default.Options);
279279

280-
Assert.True(DeepEquals(expected, actual));
280+
AssertDeepEquals(expected, actual);
281281
}
282282

283283
public class PocoWithTypesWithOpenAIUnsupportedKeywords
@@ -301,7 +301,67 @@ public static void CreateFunctionJsonSchema_ReturnsExpectedValue()
301301
Assert.NotNull(func.UnderlyingMethod);
302302

303303
JsonElement resolvedSchema = AIJsonUtilities.CreateFunctionJsonSchema(func.UnderlyingMethod, title: func.Name);
304-
Assert.True(DeepEquals(resolvedSchema, func.JsonSchema));
304+
AssertDeepEquals(resolvedSchema, func.JsonSchema);
305+
}
306+
307+
[Theory]
308+
[InlineData(true)]
309+
[InlineData(false)]
310+
public static void CreateFunctionJsonSchema_OptionalParameters(bool requireAllProperties)
311+
{
312+
string unitJsonSchema = requireAllProperties ? """
313+
{
314+
"description": "The unit to calculate the current temperature to (Default value: \u0022celsius\u0022)",
315+
"type": "string"
316+
}
317+
""" :
318+
"""
319+
{
320+
"description": "The unit to calculate the current temperature to",
321+
"type": "string",
322+
"default": "celsius"
323+
}
324+
""";
325+
326+
string requiredParamsJsonSchema = requireAllProperties ?
327+
"""["city", "unit"]""" :
328+
"""["city"]""";
329+
330+
JsonElement expected = JsonDocument.Parse($$"""
331+
{
332+
"title": "get_weather",
333+
"description": "Gets the current weather for a current location",
334+
"type": "object",
335+
"properties": {
336+
"city": {
337+
"description": "The city to get the weather for",
338+
"type": "string"
339+
},
340+
"unit": {{unitJsonSchema}}
341+
},
342+
"required": {{requiredParamsJsonSchema}}
343+
}
344+
""").RootElement;
345+
346+
AIFunction func = AIFunctionFactory.Create((
347+
[Description("The city to get the weather for")] string city,
348+
[Description("The unit to calculate the current temperature to")] string unit = "celsius") => "sunny",
349+
new AIFunctionFactoryOptions
350+
{
351+
Name = "get_weather",
352+
Description = "Gets the current weather for a current location",
353+
JsonSchemaCreateOptions = new AIJsonSchemaCreateOptions { RequireAllProperties = requireAllProperties }
354+
});
355+
356+
Assert.NotNull(func.UnderlyingMethod);
357+
AssertDeepEquals(expected, func.JsonSchema);
358+
359+
JsonElement resolvedSchema = AIJsonUtilities.CreateFunctionJsonSchema(
360+
func.UnderlyingMethod,
361+
title: func.Name,
362+
description: func.Description,
363+
inferenceOptions: new AIJsonSchemaCreateOptions { RequireAllProperties = requireAllProperties });
364+
AssertDeepEquals(expected, resolvedSchema);
305365
}
306366

307367
[Fact]
@@ -331,7 +391,7 @@ public static void CreateFunctionJsonSchema_TreatsIntegralTypesAsInteger_EvenWit
331391
""").RootElement;
332392

333393
JsonElement actualSchema = property.Value;
334-
Assert.True(DeepEquals(expected, actualSchema));
394+
AssertDeepEquals(expected, actualSchema);
335395
i++;
336396
}
337397
}
@@ -514,4 +574,17 @@ private static bool DeepEquals(JsonElement element1, JsonElement element2)
514574
JsonSerializer.SerializeToNode(element2, AIJsonUtilities.DefaultOptions));
515575
#endif
516576
}
577+
578+
private static void AssertDeepEquals(JsonElement element1, JsonElement element2)
579+
{
580+
#pragma warning disable SA1118 // Parameter should not span multiple lines
581+
Assert.True(DeepEquals(element1, element2), $"""
582+
Elements are not equal.
583+
Expected:
584+
{element1}
585+
Actual:
586+
{element2}
587+
""");
588+
#pragma warning restore SA1118 // Parameter should not span multiple lines
589+
}
517590
}

0 commit comments

Comments
 (0)