mirror of https://github.com/abpframework/abp.git
committed by
GitHub
13 changed files with 354 additions and 7 deletions
@ -0,0 +1,3 @@ |
|||||
|
{ |
||||
|
"role": "lib.test" |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\common.test.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net10.0</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.AI.Tests</AssemblyName> |
||||
|
<PackageId>Volo.Abp.AI.Tests</PackageId> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\src\Volo.Abp.AI\Volo.Abp.AI.csproj" /> |
||||
|
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" /> |
||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,40 @@ |
|||||
|
using Microsoft.Extensions.AI; |
||||
|
using Volo.Abp.AI; |
||||
|
using Volo.Abp.AI.Mocks; |
||||
|
using Volo.Abp.AI.Tests.Workspaces; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.AutoMapper; |
||||
|
|
||||
|
[DependsOn( |
||||
|
typeof(AbpTestBaseModule), |
||||
|
typeof(AbpAIModule) |
||||
|
)] |
||||
|
public class AbpAITestModule : AbpModule |
||||
|
{ |
||||
|
public override void PreConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
PreConfigure<AbpAIWorkspaceOptions>(options => |
||||
|
{ |
||||
|
options.Workspaces.ConfigureDefault(options => |
||||
|
{ |
||||
|
options.ConfigureChatClient(clientOptions => |
||||
|
{ |
||||
|
clientOptions.Builder = new ChatClientBuilder(new MockDefaultChatClient()); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
options.Workspaces.Configure<WordCounter>(workspaceOptions => |
||||
|
{ |
||||
|
workspaceOptions.ConfigureChatClient(clientOptions => |
||||
|
{ |
||||
|
clientOptions.Builder = new ChatClientBuilder(new MockChatClient()); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,47 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.AI.Tests.Workspaces; |
||||
|
using Volo.Abp.AutoMapper; |
||||
|
using Volo.Abp.Testing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.AI; |
||||
|
public class ChatClientAccessor_Tests : AbpIntegratedTest<AbpAITestModule> |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Should_Resolve_DefaultChatClientAccessor() |
||||
|
{ |
||||
|
// Arrange & Act
|
||||
|
var chatClientAccessor = GetRequiredService<IChatClientAccessor>(); |
||||
|
// Assert
|
||||
|
chatClientAccessor.ShouldNotBeNull(); |
||||
|
chatClientAccessor.ChatClient.ShouldNotBeNull(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Resolve_ChatClientAccessor_For_Workspace() |
||||
|
{ |
||||
|
// Arrange & Act
|
||||
|
var chatClientAccessor = GetRequiredService<IChatClientAccessor<WordCounter>>(); |
||||
|
// Assert
|
||||
|
chatClientAccessor.ShouldNotBeNull(); |
||||
|
chatClientAccessor.ChatClient.ShouldNotBeNull(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Resolve_ChatClientAccessor_For_NonConfigured_Workspace() |
||||
|
{ |
||||
|
// Arrange & Act
|
||||
|
var chatClientAccessor = GetRequiredService<IChatClientAccessor<NonConfiguredWorkspace>>(); |
||||
|
|
||||
|
// Assert
|
||||
|
chatClientAccessor.ShouldNotBeNull(); |
||||
|
chatClientAccessor.ChatClient.ShouldBeNull(); |
||||
|
} |
||||
|
|
||||
|
public class NonConfiguredWorkspace |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,89 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.AI; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.AI.Mocks; |
||||
|
using Volo.Abp.AI.Tests.Workspaces; |
||||
|
using Volo.Abp.AutoMapper; |
||||
|
using Volo.Abp.Testing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.AI.Tests; |
||||
|
|
||||
|
public class ChatClient_Tests : AbpIntegratedTest<AbpAITestModule> |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Should_Resolve_ChatClient_For_Workspace() |
||||
|
{ |
||||
|
// Arrange & Act
|
||||
|
var chatClient = GetRequiredService<IChatClient<WordCounter>>(); |
||||
|
|
||||
|
// Assert
|
||||
|
chatClient.ShouldNotBeNull(); |
||||
|
chatClient.ShouldNotBeOfType<MockDefaultChatClient>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Resolve_Keyed_ChatClient_For_Workspace() |
||||
|
{ |
||||
|
// Arrange
|
||||
|
var workspaceName = WorkspaceNameAttribute.GetWorkspaceName<WordCounter>(); |
||||
|
var serviceName = AbpAIWorkspaceOptions.GetChatClientServiceKeyName(workspaceName); |
||||
|
|
||||
|
// Act
|
||||
|
var chatClient = GetRequiredKeyedService<IChatClient>( |
||||
|
serviceName |
||||
|
); |
||||
|
|
||||
|
// Assert
|
||||
|
chatClient.ShouldNotBeNull(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Resolve_Default_ChatClient() |
||||
|
{ |
||||
|
// Arrange & Act
|
||||
|
var chatClient = GetRequiredService<IChatClient>(); |
||||
|
|
||||
|
// Assert
|
||||
|
chatClient.ShouldNotBeNull(); |
||||
|
chatClient.ShouldBeOfType<MockDefaultChatClient>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_Get_Response_For_Workspace() |
||||
|
{ |
||||
|
// Arrange
|
||||
|
var chatClient = GetRequiredService<IChatClient<WordCounter>>(); |
||||
|
|
||||
|
// Act
|
||||
|
var response = await chatClient.GetResponseAsync(new[] |
||||
|
{ |
||||
|
new ChatMessage(ChatRole.User, "Hello, how are you?") |
||||
|
}); |
||||
|
|
||||
|
// Assert
|
||||
|
response.ShouldNotBeNull(); |
||||
|
response.Messages.ShouldNotBeEmpty(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_Get_Streaming_Response_For_Workspace() |
||||
|
{ |
||||
|
// Arrange
|
||||
|
var chatClient = GetRequiredService<IChatClient<WordCounter>>(); |
||||
|
var messagesInput = new[] |
||||
|
{ |
||||
|
new ChatMessage(ChatRole.User, "Hello, how are you?") |
||||
|
}; |
||||
|
|
||||
|
// Act
|
||||
|
var responseParts = 0; |
||||
|
await foreach (var response in chatClient.GetStreamingResponseAsync(messagesInput)) |
||||
|
{ |
||||
|
responseParts++; |
||||
|
} |
||||
|
|
||||
|
// Assert
|
||||
|
responseParts.ShouldBe(MockChatClient.StreamingResponseParts); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,62 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.AI; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.AI.Mocks; |
||||
|
using Volo.Abp.AI.Tests.Workspaces; |
||||
|
using Volo.Abp.AutoMapper; |
||||
|
using Volo.Abp.Testing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.AI; |
||||
|
public class KernelAccessor_Tests : AbpIntegratedTest<AbpAITestModule> |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Should_Resolve_DefaultKernelAccessor() |
||||
|
{ |
||||
|
// Arrange & Act
|
||||
|
var kernelAccessor = GetRequiredService<IKernelAccessor>(); |
||||
|
// Assert
|
||||
|
kernelAccessor.ShouldNotBeNull(); |
||||
|
kernelAccessor.Kernel.ShouldNotBeNull(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_Get_Response_From_DefaultKernel() |
||||
|
{ |
||||
|
// Arrange
|
||||
|
var kernelAccessor = GetRequiredService<IKernelAccessor>(); |
||||
|
var kernel = kernelAccessor.Kernel; |
||||
|
// Act
|
||||
|
var result = await kernel.GetRequiredService<IChatClient>() |
||||
|
.GetResponseAsync("Hello, World!"); |
||||
|
// Assert
|
||||
|
result.ShouldNotBeNull(); |
||||
|
result.RawRepresentation.ShouldBe(MockChatClient.MockResponse); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Resolve_KernelAccessor_For_Workspace() |
||||
|
{ |
||||
|
// Arrange & Act
|
||||
|
var kernelAccessor = GetRequiredService<IKernelAccessor<WordCounter>>(); |
||||
|
// Assert
|
||||
|
kernelAccessor.ShouldNotBeNull(); |
||||
|
kernelAccessor.Kernel.ShouldNotBeNull(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_Get_Response_From_Kernel_For_Workspace() |
||||
|
{ |
||||
|
// Arrange
|
||||
|
var kernelAccessor = GetRequiredService<IKernelAccessor<WordCounter>>(); |
||||
|
var kernel = kernelAccessor.Kernel; |
||||
|
|
||||
|
// Act
|
||||
|
var result = await kernel.GetRequiredService<IChatClient>() |
||||
|
.GetResponseAsync("Hello, World!"); |
||||
|
|
||||
|
// Assert
|
||||
|
result.ShouldNotBeNull(); |
||||
|
result.RawRepresentation.ShouldBe(MockChatClient.MockResponse); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,61 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using Microsoft.Extensions.AI; |
||||
|
|
||||
|
namespace Volo.Abp.AI.Mocks; |
||||
|
|
||||
|
public class MockChatClient : IChatClient |
||||
|
{ |
||||
|
public const int StreamingResponseParts = 4; |
||||
|
|
||||
|
public const string MockResponse = "This is a mock response."; |
||||
|
public void Dispose() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public Task<ChatResponse> GetResponseAsync( |
||||
|
IEnumerable<ChatMessage> messages, |
||||
|
ChatOptions options = null, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var responseMessages = messages.ToList(); |
||||
|
responseMessages.Add(new ChatMessage(ChatRole.Assistant, MockResponse)); |
||||
|
return Task.FromResult(new ChatResponse |
||||
|
{ |
||||
|
Messages = responseMessages, |
||||
|
RawRepresentation = MockResponse |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public object GetService(Type serviceType, object serviceKey = null) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync( |
||||
|
IEnumerable<ChatMessage> messages, |
||||
|
ChatOptions options = null, |
||||
|
[EnumeratorCancellation] CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
for (var i = 0; i < StreamingResponseParts; i++) |
||||
|
{ |
||||
|
await Task.Delay(25, cancellationToken); |
||||
|
|
||||
|
if (cancellationToken.IsCancellationRequested) |
||||
|
{ |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
yield return new ChatResponseUpdate |
||||
|
{ |
||||
|
Role = ChatRole.Assistant, |
||||
|
RawRepresentation = MockResponse + " " + (i + 1), |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,4 @@ |
|||||
|
namespace Volo.Abp.AI.Mocks; |
||||
|
public class MockDefaultChatClient : MockChatClient |
||||
|
{ |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace Volo.Abp.AI.Tests.Workspaces; |
||||
|
|
||||
|
[WorkspaceName("WordCounter")] |
||||
|
public class WordCounter |
||||
|
{ |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue