Skip to content

.Net: Consolidate some code used in unit tests #6292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ public void ValidateRequiredArguments()
public async Task ValidateChatMessageRequestAsync()
{
// Arrange
var response = this.GetTestData("chat_completions_response.json");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", response);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-small-latest", this.HttpClient, "key");
var client = this.CreateMistralClient("mistral-small-latest", "https://api.mistral.ai/v1/chat/completions", "chat_completions_response.json");

var chatHistory = new ChatHistory
{
Expand All @@ -56,7 +53,7 @@ public async Task ValidateChatMessageRequestAsync()
await client.GetChatMessageContentsAsync(chatHistory, default, executionSettings);

// Assert
var request = this.DelegatingHandler.RequestContent;
var request = this.DelegatingHandler!.RequestContent;
Assert.NotNull(request);
var chatRequest = JsonSerializer.Deserialize<ChatCompletionRequest>(request);
Assert.NotNull(chatRequest);
Expand All @@ -72,10 +69,7 @@ public async Task ValidateChatMessageRequestAsync()
public async Task ValidateGetChatMessageContentsAsync()
{
// Arrange
var content = this.GetTestData("chat_completions_response.json");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", content);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-tiny", this.HttpClient, "key");
var client = this.CreateMistralClient("mistral-tiny", "https://api.mistral.ai/v1/chat/completions", "chat_completions_response.json");

// Act
var chatHistory = new ChatHistory
Expand All @@ -98,10 +92,7 @@ public async Task ValidateGetChatMessageContentsAsync()
public async Task ValidateGenerateEmbeddingsAsync()
{
// Arrange
var content = this.GetTestData("embeddings_response.json");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/embeddings", content);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-tiny", this.HttpClient, "key");
var client = this.CreateMistralClient("mistral-tiny", "https://api.mistral.ai/v1/embeddings", "embeddings_response.json");

// Act
List<string> data = ["Hello", "world"];
Expand All @@ -118,10 +109,7 @@ public async Task ValidateGenerateEmbeddingsAsync()
public async Task ValidateGetStreamingChatMessageContentsAsync()
{
// Arrange
var content = this.GetTestResponseAsBytes("chat_completions_streaming_response.txt");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", content);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-tiny", this.HttpClient, "key");
var client = this.CreateMistralClientStreaming("mistral-tiny", "https://api.mistral.ai/v1/chat/completions", "chat_completions_streaming_response.txt");

var chatHistory = new ChatHistory
{
Expand Down Expand Up @@ -153,10 +141,7 @@ public async Task ValidateGetStreamingChatMessageContentsAsync()
public async Task ValidateChatHistoryFirstSystemOrUserMessageAsync()
{
// Arrange
var content = this.GetTestResponseAsBytes("chat_completions_streaming_response.txt");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", content);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-tiny", this.HttpClient, "key");
var client = this.CreateMistralClient("mistral-tiny", "https://api.mistral.ai/v1/chat/completions", "chat_completions_streaming_response.txt");

// First message in chat history must be a user or system message
var chatHistory = new ChatHistory
Expand All @@ -172,10 +157,7 @@ public async Task ValidateChatHistoryFirstSystemOrUserMessageAsync()
public async Task ValidateEmptyChatHistoryAsync()
{
// Arrange
var content = this.GetTestResponseAsBytes("chat_completions_streaming_response.txt");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", content);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-tiny", this.HttpClient, "key");
var client = this.CreateMistralClient("mistral-tiny", "https://api.mistral.ai/v1/chat/completions", "chat_completions_streaming_response.txt");
var chatHistory = new ChatHistory();

// Act & Assert
Expand All @@ -186,10 +168,7 @@ public async Task ValidateEmptyChatHistoryAsync()
public async Task ValidateChatMessageRequestWithToolsAsync()
{
// Arrange
var response = this.GetTestData("function_call_response.json");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", response);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-small-latest", this.HttpClient, "key");
var client = this.CreateMistralClient("mistral-tiny", "https://api.mistral.ai/v1/chat/completions", "function_call_response.json");

var chatHistory = new ChatHistory
{
Expand All @@ -205,7 +184,7 @@ public async Task ValidateChatMessageRequestWithToolsAsync()
await client.GetChatMessageContentsAsync(chatHistory, default, executionSettings, kernel);

// Assert
var request = this.DelegatingHandler.RequestContent;
var request = this.DelegatingHandler!.RequestContent;
Assert.NotNull(request);
var chatRequest = JsonSerializer.Deserialize<ChatCompletionRequest>(request);
Assert.NotNull(chatRequest);
Expand All @@ -221,10 +200,7 @@ public async Task ValidateChatMessageRequestWithToolsAsync()
public async Task ValidateGetStreamingChatMessageContentsWithToolsAsync()
{
// Arrange
var content = this.GetTestResponseAsBytes("chat_completions_streaming_function_call_response.txt");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", content);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-tiny", this.HttpClient, "key");
var client = this.CreateMistralClientStreaming("mistral-tiny", "https://api.mistral.ai/v1/chat/completions", "chat_completions_streaming_function_call_response.txt");

var chatHistory = new ChatHistory
{
Expand All @@ -246,7 +222,7 @@ public async Task ValidateGetStreamingChatMessageContentsWithToolsAsync()
// Assert
Assert.NotNull(response);
Assert.Equal(12, chunks.Count); // Test will loop until maximum use attempts is reached
var request = this.DelegatingHandler.RequestContent;
var request = this.DelegatingHandler!.RequestContent;
Assert.NotNull(request);
var chatRequest = JsonSerializer.Deserialize<ChatCompletionRequest>(request);
Assert.NotNull(chatRequest);
Expand All @@ -262,11 +238,11 @@ public async Task ValidateGetStreamingChatMessageContentsWithToolsAsync()
public async Task ValidateGetChatMessageContentsWithFunctionCallAsync()
{
// Arrange
var functionCallContent = this.GetTestData("chat_completions_function_call_response.json");
var functionCalledContent = this.GetTestData("chat_completions_function_called_response.json");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", functionCallContent, functionCalledContent);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-large-latest", this.HttpClient, "key");
var client = this.CreateMistralClient(
"mistral-large-latest",
"https://api.mistral.ai/v1/chat/completions",
"chat_completions_function_call_response.json",
"chat_completions_function_called_response.json");

var kernel = new Kernel();
kernel.Plugins.AddFromType<WeatherPlugin>();
Expand All @@ -284,18 +260,15 @@ public async Task ValidateGetChatMessageContentsWithFunctionCallAsync()
Assert.Single(response);
Assert.Equal("The weather in Paris is mostly cloudy with a temperature of 12°C. The wind speed is 11 KMPH and the humidity is at 48%.", response[0].Content);
Assert.Equal("mistral-large-latest", response[0].ModelId);
Assert.Equal(2, this.DelegatingHandler.SendAsyncCallCount);
Assert.Equal(2, this.DelegatingHandler!.SendAsyncCallCount);
Assert.Equal(3, chatHistory.Count);
}

[Fact]
public async Task ValidateGetChatMessageContentsWithFunctionCallNoneAsync()
{
// Arrange
var content = this.GetTestData("chat_completions_function_call_none_response.json");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", content);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-large-latest", this.HttpClient, "key");
var client = this.CreateMistralClient("mistral-large-latest", "https://api.mistral.ai/v1/chat/completions", "chat_completions_function_call_none_response.json");

var kernel = new Kernel();
kernel.Plugins.AddFromType<WeatherPlugin>();
Expand All @@ -319,11 +292,11 @@ public async Task ValidateGetChatMessageContentsWithFunctionCallNoneAsync()
public async Task ValidateGetChatMessageContentsWithFunctionCallRequiredAsync()
{
// Arrange
var functionCallContent = this.GetTestData("chat_completions_function_call_response.json");
var functionCalledContent = this.GetTestData("chat_completions_function_called_response.json");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", functionCallContent, functionCalledContent);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-large-latest", this.HttpClient, "key");
var client = this.CreateMistralClient(
"mistral-large-latest",
"https://api.mistral.ai/v1/chat/completions",
"chat_completions_function_call_response.json",
"chat_completions_function_called_response.json");

var kernel = new Kernel();
var plugin = kernel.Plugins.AddFromType<WeatherPlugin>();
Expand All @@ -341,19 +314,19 @@ public async Task ValidateGetChatMessageContentsWithFunctionCallRequiredAsync()
Assert.Single(response);
Assert.Equal("The weather in Paris is mostly cloudy with a temperature of 12°C. The wind speed is 11 KMPH and the humidity is at 48%.", response[0].Content);
Assert.Equal("mistral-large-latest", response[0].ModelId);
Assert.Equal(2, this.DelegatingHandler.SendAsyncCallCount);
Assert.Equal(2, this.DelegatingHandler!.SendAsyncCallCount);
Assert.Equal(3, chatHistory.Count);
}

[Fact]
public async Task ValidateGetChatMessageContentsWithFunctionInvocationFilterAsync()
{
// Arrange
var functionCallContent = this.GetTestData("chat_completions_function_call_response.json");
var functionCalledContent = this.GetTestData("chat_completions_function_called_response.json");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", functionCallContent, functionCalledContent);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-large-latest", this.HttpClient, "key");
var client = this.CreateMistralClient(
"mistral-large-latest",
"https://api.mistral.ai/v1/chat/completions",
"chat_completions_function_call_response.json",
"chat_completions_function_called_response.json");

var kernel = new Kernel();
kernel.Plugins.AddFromType<WeatherPlugin>();
Expand All @@ -379,7 +352,7 @@ public async Task ValidateGetChatMessageContentsWithFunctionInvocationFilterAsyn
Assert.Single(response);
Assert.Equal("The weather in Paris is mostly cloudy with a temperature of 12°C. The wind speed is 11 KMPH and the humidity is at 48%.", response[0].Content);
Assert.Equal("mistral-large-latest", response[0].ModelId);
Assert.Equal(2, this.DelegatingHandler.SendAsyncCallCount);
Assert.Equal(2, this.DelegatingHandler!.SendAsyncCallCount);
Assert.Equal(3, chatHistory.Count);
Assert.Contains("GetWeather", invokedFunctions);
}
Expand All @@ -388,11 +361,11 @@ public async Task ValidateGetChatMessageContentsWithFunctionInvocationFilterAsyn
public async Task ValidateGetChatMessageContentsWithAutoFunctionInvocationFilterTerminateAsync()
{
// Arrange
var functionCallContent = this.GetTestData("chat_completions_function_call_response.json");
var functionCalledContent = this.GetTestData("chat_completions_function_called_response.json");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", functionCallContent, functionCalledContent);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient("mistral-large-latest", this.HttpClient, "key");
var client = this.CreateMistralClient(
"mistral-large-latest",
"https://api.mistral.ai/v1/chat/completions",
"chat_completions_function_call_response.json",
"chat_completions_function_called_response.json");

var kernel = new Kernel();
kernel.Plugins.AddFromType<WeatherPlugin>();
Expand All @@ -419,7 +392,7 @@ public async Task ValidateGetChatMessageContentsWithAutoFunctionInvocationFilter
Assert.Single(response);
Assert.Equal("12°C\nWind: 11 KMPH\nHumidity: 48%\nMostly cloudy", response[0].Content);
Assert.Null(response[0].ModelId);
Assert.Equal(1, this.DelegatingHandler.SendAsyncCallCount);
Assert.Equal(1, this.DelegatingHandler!.SendAsyncCallCount);
Assert.Equal(3, chatHistory.Count);
Assert.Contains("GetWeather", invokedFunctions);
}
Expand Down Expand Up @@ -539,4 +512,22 @@ private sealed class FakeAutoFunctionFilter(
public Task OnAutoFunctionInvocationAsync(AutoFunctionInvocationContext context, Func<AutoFunctionInvocationContext, Task> next) =>
this._onAutoFunctionInvocation?.Invoke(context, next) ?? Task.CompletedTask;
}

private MistralClient CreateMistralClient(string modelId, string requestUri, params string[] responseData)
{
var responses = responseData.Select(this.GetTestResponseAsString).ToArray();
this.DelegatingHandler = new AssertingDelegatingHandler(requestUri, responses);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient(modelId, this.HttpClient, "key");
return client;
}

private MistralClient CreateMistralClientStreaming(string modelId, string requestUri, params string[] responseData)
{
var responses = responseData.Select(this.GetTestResponseAsBytes).ToArray();
this.DelegatingHandler = new AssertingDelegatingHandler(requestUri, responses);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var client = new MistralClient(modelId, this.HttpClient, "key");
return client;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public abstract class MistralTestBase : IDisposable
protected AssertingDelegatingHandler? DelegatingHandler { get; set; }
protected HttpClient? HttpClient { get; set; }

protected string GetTestData(string fileName)
protected string GetTestResponseAsString(string fileName)
{
return File.ReadAllText($"./TestData/{fileName}");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public sealed class MistralAIChatCompletionServiceTests : MistralTestBase
public async Task ValidateGetChatMessageContentsAsync()
{
// Arrange
var content = this.GetTestData("chat_completions_response.json");
var content = this.GetTestResponseAsString("chat_completions_response.json");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/chat/completions", content);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var service = new MistralAIChatCompletionService("mistral-small-latest", "key", httpClient: this.HttpClient);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public sealed class MistralAITextEmbeddingGenerationServiceTests : MistralTestBa
public async Task ValidateGenerateEmbeddingsAsync()
{
// Arrange
var content = this.GetTestData("embeddings_response.json");
var content = this.GetTestResponseAsString("embeddings_response.json");
this.DelegatingHandler = new AssertingDelegatingHandler("https://api.mistral.ai/v1/embeddings", content);
this.HttpClient = new HttpClient(this.DelegatingHandler, false);
var service = new MistralAITextEmbeddingGenerationService("mistral-small-latest", "key", httpClient: this.HttpClient);
Expand Down
Loading