Skip to content

Commit dccbab9

Browse files
committed
tests
1 parent 4934d8f commit dccbab9

10 files changed

+2865
-154
lines changed

src/Custom/Chat/UpdateChatCompletionOptions..cs

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,35 @@
22
using System.ClientModel;
33
using System.ClientModel.Primitives;
44
using System.Collections.Generic;
5+
using System.ComponentModel;
6+
using System.Diagnostics.CodeAnalysis;
7+
using System.Text;
58
using System.Text.Json;
69

710
namespace OpenAI.Chat;
811

912
public class UpdateChatCompletionOptions : JsonModel<UpdateChatCompletionOptions>
1013
{
11-
private protected IDictionary<string, BinaryData> _additionalBinaryDataProperties;
14+
[Experimental("SCME0001")]
15+
private JsonPatch _patch;
1216

13-
public UpdateChatCompletionOptions() { }
17+
public UpdateChatCompletionOptions() : this(null, default) { }
1418

15-
internal UpdateChatCompletionOptions(IDictionary<string, string> metadata, IDictionary<string, BinaryData> additionalBinaryDataProperties)
19+
#pragma warning disable SCME0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
20+
internal UpdateChatCompletionOptions(IDictionary<string, string> metadata, in JsonPatch patch)
1621
{
1722
// Plugin customization: ensure initialization of collections
1823
Metadata = metadata ?? new ChangeTrackingDictionary<string, string>();
19-
_additionalBinaryDataProperties = additionalBinaryDataProperties;
24+
_patch = patch;
2025
}
2126

2227
public string CompletionId { get; set; }
2328

2429
public IDictionary<string, string> Metadata { get; }
2530

26-
internal IDictionary<string, BinaryData> SerializedAdditionalRawData
27-
{
28-
get => _additionalBinaryDataProperties;
29-
set => _additionalBinaryDataProperties = value;
30-
}
31+
[EditorBrowsable(EditorBrowsableState.Never)]
32+
[Experimental("SCME0001")]
33+
public ref JsonPatch Patch => ref _patch;
3134

3235
protected override void WriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
3336
{
@@ -36,7 +39,8 @@ protected override void WriteCore(Utf8JsonWriter writer, ModelReaderWriterOption
3639
{
3740
throw new FormatException($"The model {nameof(UpdateChatCompletionOptions)} does not support writing '{format}' format.");
3841
}
39-
if (_additionalBinaryDataProperties?.ContainsKey("metadata") != true)
42+
writer.WriteStartObject();
43+
if (Optional.IsCollectionDefined(Metadata) && !Patch.Contains("$.metadata"u8))
4044
{
4145
writer.WritePropertyName("metadata"u8);
4246
writer.WriteStartObject();
@@ -52,26 +56,9 @@ protected override void WriteCore(Utf8JsonWriter writer, ModelReaderWriterOption
5256
}
5357
writer.WriteEndObject();
5458
}
55-
// Plugin customization: remove options.Format != "W" check
56-
if (_additionalBinaryDataProperties != null)
57-
{
58-
foreach (var item in _additionalBinaryDataProperties)
59-
{
60-
if (ModelSerializationExtensions.IsSentinelValue(item.Value))
61-
{
62-
continue;
63-
}
64-
writer.WritePropertyName(item.Key);
65-
#if NET6_0_OR_GREATER
66-
writer.WriteRawValue(item.Value);
67-
#else
68-
using (JsonDocument document = JsonDocument.Parse(item.Value))
69-
{
70-
JsonSerializer.Serialize(writer, document.RootElement);
71-
}
72-
#endif
73-
}
74-
}
59+
Patch.WriteTo(writer);
60+
writer.WriteEndObject();
61+
#pragma warning restore SCME0001 // Type is for evaluation purposes only and is subject to change or removal in future updates.
7562
}
7663

7764
protected override UpdateChatCompletionOptions CreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
@@ -85,17 +72,19 @@ protected virtual UpdateChatCompletionOptions JsonModelCreateCore(ref Utf8JsonRe
8572
throw new FormatException($"The model {nameof(UpdateChatCompletionOptions)} does not support reading '{format}' format.");
8673
}
8774
using JsonDocument document = JsonDocument.ParseValue(ref reader);
88-
return DeserializeUpdateChatCompletionOptions(document.RootElement, options);
75+
return DeserializeUpdateChatCompletionOptions(document.RootElement, null, options);
8976
}
9077

91-
internal static UpdateChatCompletionOptions DeserializeUpdateChatCompletionOptions(JsonElement element, ModelReaderWriterOptions options)
78+
internal static UpdateChatCompletionOptions DeserializeUpdateChatCompletionOptions(JsonElement element, BinaryData data, ModelReaderWriterOptions options)
9279
{
9380
if (element.ValueKind == JsonValueKind.Null)
9481
{
9582
return null;
9683
}
9784
IDictionary<string, string> metadata = default;
98-
IDictionary<string, BinaryData> additionalBinaryDataProperties = new ChangeTrackingDictionary<string, BinaryData>();
85+
#pragma warning disable SCME0001 // Type is for evaluation purposes only and is subject to change or removal in future updates.
86+
JsonPatch patch = new JsonPatch(data is null ? ReadOnlyMemory<byte>.Empty : data.ToMemory());
87+
#pragma warning restore SCME0001 // Type is for evaluation purposes only and is subject to change or removal in future updates.
9988
foreach (var prop in element.EnumerateObject())
10089
{
10190
if (prop.NameEquals("metadata"u8))
@@ -115,10 +104,9 @@ internal static UpdateChatCompletionOptions DeserializeUpdateChatCompletionOptio
115104
metadata = dictionary;
116105
continue;
117106
}
118-
// Plugin customization: remove options.Format != "W" check
119-
additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
107+
patch.Set([.. "$."u8, .. Encoding.UTF8.GetBytes(prop.Name)], prop.Value.GetUtf8Bytes());
120108
}
121-
return new UpdateChatCompletionOptions(metadata, additionalBinaryDataProperties);
109+
return new UpdateChatCompletionOptions(metadata, patch);
122110
}
123111

124112
public static implicit operator BinaryContent(UpdateChatCompletionOptions options)

tests/Chat/ChatStoreTests.cs

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public async Task GetChatCompletionsWithPagination()
6868
completionIds.Add(completion.Id);
6969
}
7070

71-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be stored
71+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be stored
7272

7373
// Test pagination with limit
7474
ChatCompletionCollectionOptions paginationOptions = new()
@@ -125,20 +125,20 @@ public async Task GetChatCompletionsWithPagination_PM()
125125
completionIds.Add(completion.Id);
126126
}
127127

128-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be stored
128+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be stored
129129

130130
// Test pagination with limit
131131
ChatCompletionCollectionOptions paginationOptions = new()
132132
{
133-
PageSizeLimit = 2
133+
PageSizeLimit = 2,
134134
};
135135

136136
int totalCount = 0;
137137
string lastId = null;
138138

139-
// await foreach (var fetchedCompletion in client.GetChatCompletionsAsync(after: null, limit: 2, order: null, metadata: null))
140139
var getOptions = GetChatCompletionsOptions.Create(client);
141140
getOptions.Limit = 2;
141+
getOptions.Model = "gpt-4o-mini-2024-07-18";
142142
ChatCompletionList result;
143143
do
144144
{
@@ -150,11 +150,9 @@ public async Task GetChatCompletionsWithPagination_PM()
150150
lastId = fetchedCompletion.Id;
151151
Assert.That(fetchedCompletion.Id, Is.Not.Null.And.Not.Empty);
152152
Assert.That(fetchedCompletion.Choices[0].Message.Content, Is.Not.Null);
153-
154-
if (totalCount >= 2) break; // Stop after getting 2 items
155153
}
156154

157-
} while (result.HasMore);
155+
} while (result.HasMore && totalCount < 2);
158156

159157

160158
Assert.That(totalCount, Is.EqualTo(2));
@@ -193,7 +191,7 @@ public async Task GetChatCompletionsWithPagination_PMwRequestOptions()
193191
completionIds.Add(completion.Id);
194192
}
195193

196-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be stored
194+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be stored
197195

198196
// Test pagination with limit
199197
ChatCompletionCollectionOptions paginationOptions = new()
@@ -205,6 +203,7 @@ public async Task GetChatCompletionsWithPagination_PMwRequestOptions()
205203
string lastId = null;
206204
var getOptions = GetChatCompletionsOptions.Create(client);
207205
getOptions.Limit = 2;
206+
getOptions.Model = "gpt-4o-mini-2024-07-18";
208207

209208
AsyncCollectionResult foo = client.GetChatCompletionsAsync(getOptions, requestOptions: new RequestOptions());
210209

@@ -258,7 +257,7 @@ public async Task GetChatCompletionsWithAfterIdPagination()
258257
completionIds.Add(completion.Id);
259258
}
260259

261-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be stored
260+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be stored
262261

263262
// Get first completion to use as afterId
264263
string afterId = null;
@@ -317,10 +316,10 @@ public async Task GetChatCompletionsWithOrderFiltering()
317316
createOptions);
318317

319318
completionIds.Add(completion.Id);
320-
await Task.Delay(1000); // Ensure different timestamps
319+
await DelayIfNotInPlaybackAsync(1000); // Ensure different timestamps
321320
}
322321

323-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be stored
322+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be stored
324323

325324
// Test ascending order
326325
ChatCompletionCollectionOptions ascOptions = new()
@@ -403,7 +402,7 @@ public async Task GetChatCompletionsWithMetadataFiltering()
403402
options2);
404403
completionIds.Add(otherCompletion.Id);
405404

406-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be stored
405+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be stored
407406

408407
// Filter by specific metadata
409408
ChatCompletionCollectionOptions filterOptions = new()
@@ -451,7 +450,7 @@ public async Task GetChatCompletionsWithModelFiltering()
451450
["Model filter test: Say 'Hello'"],
452451
createOptions);
453452

454-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be stored
453+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be stored
455454

456455
// Filter by the model used by the test client
457456
ChatCompletionCollectionOptions filterOptions = new()
@@ -494,7 +493,7 @@ public async Task GetChatCompletionsWithEmptyOptions()
494493
["Empty options test: Say 'Hello'"],
495494
createOptions);
496495

497-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be stored
496+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be stored
498497

499498
// Test with default/empty options
500499
int count = 0;
@@ -538,7 +537,7 @@ public async Task GetChatCompletionsWithCombinedFilters()
538537
["Combined filters test: Say 'Combined test'"],
539538
createOptions);
540539

541-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be stored
540+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be stored
542541

543542
// Test with combined filters
544543
ChatCompletionCollectionOptions combinedOptions = new()
@@ -595,7 +594,7 @@ await TestHelpers.RetryWithExponentialBackoffAsync(async () =>
595594
Assert.That(deletionResult.Deleted, Is.True);
596595
});
597596

598-
await Task.Delay(s_delayInMilliseconds);
597+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds);
599598

600599
Assert.ThrowsAsync<ClientResultException>(async () =>
601600
{
@@ -661,7 +660,7 @@ public async Task UpdateChatCompletionWorks_PM()
661660
[new UserChatMessage("Say `this is a test`.")],
662661
initialOptions);
663662

664-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be stored
663+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be stored
665664

666665
var updateOptions = new UpdateChatCompletionOptions()
667666
{
@@ -672,15 +671,15 @@ [new UserChatMessage("Say `this is a test`.")],
672671

673672
ChatCompletionResult updated = await client.UpdateChatCompletionAsync(updateOptions);
674673

675-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be updated
674+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be updated
676675

677676
Assert.That(updated, Is.Not.Null);
678677
Assert.That(updated.Id, Is.EqualTo(chatCompletion.Id));
679678

680679
ChatCompletionDeletionResult deletionResult = await client.DeleteChatCompletionAsync(chatCompletion.Id);
681680
Assert.That(deletionResult.Deleted, Is.True);
682681

683-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be deleted
682+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be deleted
684683

685684
Assert.ThrowsAsync<ClientResultException>(async () =>
686685
{
@@ -704,7 +703,7 @@ public async Task GetChatCompletionsValidatesCollectionEnumeration()
704703
["Enumeration test: Say 'Test enumeration'"],
705704
createOptions);
706705

707-
await Task.Delay(5000); // Wait for completion to be stored
706+
await DelayIfNotInPlaybackAsync(5000); // Wait for completion to be stored
708707

709708
// Test that we can enumerate multiple times
710709
ChatCompletionCollectionOptions collectionOptions = new()
@@ -758,7 +757,7 @@ public async Task GetChatCompletionsHandlesLargeLimits()
758757
["Large limit test: Say 'Testing large limits'"],
759758
createOptions);
760759

761-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be stored
760+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be stored
762761

763762
// Test with a large page size limit
764763
ChatCompletionCollectionOptions largeOptions = new()
@@ -799,7 +798,7 @@ public async Task GetChatCompletionsWithMinimalLimits()
799798
["Minimal limit test: Say 'Testing minimal limits'"],
800799
createOptions);
801800

802-
await Task.Delay(s_delayInMilliseconds); // Wait for completions to be stored
801+
await DelayIfNotInPlaybackAsync(s_delayInMilliseconds); // Wait for completions to be stored
803802

804803
// Test with minimal page size
805804
ChatCompletionCollectionOptions minimalOptions = new()

0 commit comments

Comments
 (0)