-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
* Addition of factories for better testability. * Updates from review.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using NATS.Client.Core; | ||
|
||
namespace NATS.Client.JetStream; | ||
|
||
internal interface INatsJSContextFactory | ||
{ | ||
INatsJSContext CreateContext(INatsConnection connection); | ||
|
||
INatsJSContext CreateContext(INatsConnection connection, NatsJSOpts opts); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using NATS.Client.Core; | ||
|
||
namespace NATS.Client.JetStream; | ||
|
||
public sealed class NatsJSContextFactory : INatsJSContextFactory | ||
{ | ||
public INatsJSContext CreateContext(INatsConnection connection) | ||
{ | ||
var con = connection as NatsConnection ?? throw new ArgumentException("Connection must be a NatsConnection"); | ||
|
||
return new NatsJSContext(con); | ||
} | ||
|
||
public INatsJSContext CreateContext(INatsConnection connection, NatsJSOpts opts) | ||
{ | ||
var con = connection as NatsConnection ?? throw new ArgumentException("Connection must be a NatsConnection"); | ||
|
||
return new NatsJSContext(con, opts); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using NATS.Client.JetStream; | ||
|
||
namespace NATS.Client.KeyValueStore; | ||
|
||
public interface INatsKVContextFactory | ||
{ | ||
INatsKVContext CreateContext(INatsJSContext jsContext); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using NATS.Client.JetStream; | ||
|
||
namespace NATS.Client.KeyValueStore; | ||
|
||
public sealed class NatsKVContextFactory : INatsKVContextFactory | ||
{ | ||
public INatsKVContext CreateContext(INatsJSContext jsContext) | ||
{ | ||
var context = jsContext as NatsJSContext ?? throw new ArgumentException("Connection must be a NatsConnection"); | ||
|
||
return new NatsKVContext(context); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using NATS.Client.JetStream; | ||
|
||
namespace NATS.Client.ObjectStore; | ||
|
||
public interface INatsObjContextFactory | ||
{ | ||
INatsObjContext CreateContext(INatsJSContext jsContext); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using NATS.Client.JetStream; | ||
|
||
namespace NATS.Client.ObjectStore; | ||
|
||
public class NatsObjContextFactory : INatsObjContextFactory | ||
{ | ||
public INatsObjContext CreateContext(INatsJSContext jsContext) | ||
{ | ||
var context = jsContext as NatsJSContext ?? throw new ArgumentException("Connection must be a NatsConnection"); | ||
|
||
return new NatsObjContext(context); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
using NATS.Client.Core.Tests; | ||
using NATS.Client.JetStream.Models; | ||
|
||
namespace NATS.Client.JetStream.Tests; | ||
|
||
public class NatsJSContextFactoryTest | ||
{ | ||
private readonly ITestOutputHelper _output; | ||
|
||
public NatsJSContextFactoryTest(ITestOutputHelper output) => _output = output; | ||
|
||
[Fact] | ||
public async Task Create_Context_Test() | ||
{ | ||
// Arrange | ||
await using var server = NatsServer.Start( | ||
outputHelper: _output, | ||
opts: new NatsServerOptsBuilder() | ||
.UseTransport(TransportType.Tcp) | ||
.Trace() | ||
.UseJetStream() | ||
.Build()); | ||
await using var connection = server.CreateClientConnection(new NatsOpts { RequestTimeout = TimeSpan.FromSeconds(10) }); | ||
var factory = new NatsJSContextFactory(); | ||
|
||
// Act | ||
var context = factory.CreateContext(connection); | ||
|
||
// Assert | ||
context.Should().NotBeNull(); | ||
} | ||
|
||
[Fact] | ||
public async Task Create_Context_WithOpts_Test() | ||
{ | ||
// Arrange | ||
await using var server = NatsServer.Start( | ||
outputHelper: _output, | ||
opts: new NatsServerOptsBuilder() | ||
.UseTransport(TransportType.Tcp) | ||
.Trace() | ||
.UseJetStream() | ||
.Build()); | ||
await using var connection = server.CreateClientConnection(new NatsOpts { RequestTimeout = TimeSpan.FromSeconds(10) }); | ||
var factory = new NatsJSContextFactory(); | ||
var opts = new NatsJSOpts(connection.Opts); | ||
|
||
// Act | ||
var context = factory.CreateContext(connection, opts); | ||
|
||
// Assert | ||
context.Should().NotBeNull(); | ||
} | ||
|
||
[Fact] | ||
public void Create_Context_WithOptsAndMockConnection_Test() | ||
{ | ||
// Arrange | ||
var connection = new MockConnection(); | ||
var factory = new NatsJSContextFactory(); | ||
var opts = new NatsJSOpts(connection.Opts); | ||
|
||
// Act | ||
var context = () => factory.CreateContext(connection, opts); | ||
|
||
// Assert | ||
context.Should().Throw<ArgumentException>(); | ||
} | ||
|
||
[Fact] | ||
public void Create_Context_WithMockConnection_Test() | ||
{ | ||
// Arrange | ||
var connection = new MockConnection(); | ||
var factory = new NatsJSContextFactory(); | ||
|
||
// Act | ||
var context = () => factory.CreateContext(connection); | ||
|
||
// Assert | ||
context.Should().Throw<ArgumentException>(); | ||
} | ||
|
||
public class MockConnection : INatsConnection | ||
{ | ||
public INatsServerInfo? ServerInfo { get; } = null; | ||
|
||
public NatsOpts Opts { get; } = new(); | ||
|
||
public NatsConnectionState ConnectionState { get; } = NatsConnectionState.Closed; | ||
|
||
public ValueTask<TimeSpan> PingAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask PublishAsync<T>(string subject, T data, NatsHeaders? headers = default, string? replyTo = default, INatsSerialize<T>? serializer = default, NatsPubOpts? opts = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask PublishAsync(string subject, NatsHeaders? headers = default, string? replyTo = default, NatsPubOpts? opts = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask PublishAsync<T>(in NatsMsg<T> msg, INatsSerialize<T>? serializer = default, NatsPubOpts? opts = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public IAsyncEnumerable<NatsMsg<T>> SubscribeAsync<T>(string subject, string? queueGroup = default, INatsDeserialize<T>? serializer = default, NatsSubOpts? opts = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<INatsSub<T>> SubscribeCoreAsync<T>(string subject, string? queueGroup = default, INatsDeserialize<T>? serializer = default, NatsSubOpts? opts = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public string NewInbox() => throw new NotImplementedException(); | ||
|
||
public ValueTask<NatsMsg<TReply>> RequestAsync<TRequest, TReply>(string subject, TRequest? data, NatsHeaders? headers = default, INatsSerialize<TRequest>? requestSerializer = default, INatsDeserialize<TReply>? replySerializer = default, NatsPubOpts? requestOpts = default, | ||
NatsSubOpts? replyOpts = default, CancellationToken cancellationToken = default) => | ||
Check warning on line 107 in tests/NATS.Client.JetStream.Tests/NatsJsContextFactoryTest.cs
|
||
throw new NotImplementedException(); | ||
|
||
public IAsyncEnumerable<NatsMsg<TReply>> RequestManyAsync<TRequest, TReply>(string subject, TRequest? data, NatsHeaders? headers = default, INatsSerialize<TRequest>? requestSerializer = default, INatsDeserialize<TReply>? replySerializer = default, NatsPubOpts? requestOpts = default, | ||
NatsSubOpts? replyOpts = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
Check warning on line 111 in tests/NATS.Client.JetStream.Tests/NatsJsContextFactoryTest.cs
|
||
|
||
public ValueTask ConnectAsync() => throw new NotImplementedException(); | ||
|
||
public ValueTask DisposeAsync() => throw new NotImplementedException(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using NATS.Client.Core.Tests; | ||
using NATS.Client.JetStream.Models; | ||
|
||
namespace NATS.Client.KeyValueStore.Tests; | ||
|
||
public class NatsKVContextFactoryTest | ||
{ | ||
private readonly ITestOutputHelper _output; | ||
|
||
public NatsKVContextFactoryTest(ITestOutputHelper output) => _output = output; | ||
|
||
[Fact] | ||
public async Task Create_Context_Test() | ||
{ | ||
// Arrange | ||
await using var server = NatsServer.Start( | ||
outputHelper: _output, | ||
opts: new NatsServerOptsBuilder() | ||
.UseTransport(TransportType.Tcp) | ||
.Trace() | ||
.UseJetStream() | ||
.Build()); | ||
await using var connection = server.CreateClientConnection(new NatsOpts { RequestTimeout = TimeSpan.FromSeconds(10) }); | ||
var jsFactory = new NatsJSContextFactory(); | ||
var jsContext = jsFactory.CreateContext(connection); | ||
var factory = new NatsKVContextFactory(); | ||
|
||
// Act | ||
var context = factory.CreateContext(jsContext); | ||
|
||
// Assert | ||
context.Should().NotBeNull(); | ||
} | ||
|
||
Check warning on line 34 in tests/NATS.Client.KeyValueStore.Tests/NatsKVContextFactoryTest.cs
|
||
|
||
[Fact] | ||
public void Create_Context_WithMockConnection_Test() | ||
{ | ||
// Arrange | ||
var mockJsContext = new MockJsContext(); | ||
var factory = new NatsKVContextFactory(); | ||
|
||
// Act | ||
var context = () => factory.CreateContext(mockJsContext); | ||
|
||
// Assert | ||
context.Should().Throw<ArgumentException>(); | ||
} | ||
|
||
public class MockJsContext : INatsJSContext | ||
{ | ||
public ValueTask<INatsJSConsumer> CreateOrderedConsumerAsync(string stream, NatsJSOrderedConsumerOpts? opts = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<INatsJSConsumer> CreateOrUpdateConsumerAsync(string stream, ConsumerConfig config, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<INatsJSConsumer> GetConsumerAsync(string stream, string consumer, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public IAsyncEnumerable<INatsJSConsumer> ListConsumersAsync(string stream, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public IAsyncEnumerable<string> ListConsumerNamesAsync(string stream, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<bool> DeleteConsumerAsync(string stream, string consumer, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<AccountInfoResponse> GetAccountInfoAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<PubAckResponse> PublishAsync<T>(string subject, T? data, INatsSerialize<T>? serializer = default, NatsJSPubOpts? opts = default, NatsHeaders? headers = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<INatsJSStream> CreateStreamAsync(StreamConfig config, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<bool> DeleteStreamAsync(string stream, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<StreamPurgeResponse> PurgeStreamAsync(string stream, StreamPurgeRequest request, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<StreamMsgDeleteResponse> DeleteMessageAsync(string stream, StreamMsgDeleteRequest request, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<INatsJSStream> GetStreamAsync(string stream, StreamInfoRequest? request = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<NatsJSStream> UpdateStreamAsync(StreamConfig request, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public IAsyncEnumerable<INatsJSStream> ListStreamsAsync(string? subject = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public IAsyncEnumerable<string> ListStreamNamesAsync(string? subject = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using NATS.Client.Core.Tests; | ||
using NATS.Client.JetStream.Models; | ||
|
||
namespace NATS.Client.ObjectStore.Tests; | ||
|
||
public class NatsObjContextFactoryTest | ||
{ | ||
private readonly ITestOutputHelper _output; | ||
|
||
public NatsObjContextFactoryTest(ITestOutputHelper output) => _output = output; | ||
|
||
[Fact] | ||
public async Task Create_Context_Test() | ||
{ | ||
// Arrange | ||
await using var server = NatsServer.Start( | ||
outputHelper: _output, | ||
opts: new NatsServerOptsBuilder() | ||
.UseTransport(TransportType.Tcp) | ||
.Trace() | ||
.UseJetStream() | ||
.Build()); | ||
await using var connection = server.CreateClientConnection(new NatsOpts { RequestTimeout = TimeSpan.FromSeconds(10) }); | ||
var jsFactory = new NatsJSContextFactory(); | ||
var jsContext = jsFactory.CreateContext(connection); | ||
var factory = new NatsObjContextFactory(); | ||
|
||
// Act | ||
var context = factory.CreateContext(jsContext); | ||
|
||
// Assert | ||
context.Should().NotBeNull(); | ||
} | ||
|
||
Check warning on line 34 in tests/NATS.Client.ObjectStore.Tests/NatsObjContextFactoryTest.cs
|
||
|
||
[Fact] | ||
public void Create_Context_WithMockConnection_Test() | ||
{ | ||
// Arrange | ||
var mockJsContext = new MockJsContext(); | ||
var factory = new NatsObjContextFactory(); | ||
|
||
// Act | ||
var context = () => factory.CreateContext(mockJsContext); | ||
|
||
// Assert | ||
context.Should().Throw<ArgumentException>(); | ||
} | ||
|
||
public class MockJsContext : INatsJSContext | ||
{ | ||
public ValueTask<INatsJSConsumer> CreateOrderedConsumerAsync(string stream, NatsJSOrderedConsumerOpts? opts = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<INatsJSConsumer> CreateOrUpdateConsumerAsync(string stream, ConsumerConfig config, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<INatsJSConsumer> GetConsumerAsync(string stream, string consumer, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public IAsyncEnumerable<INatsJSConsumer> ListConsumersAsync(string stream, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public IAsyncEnumerable<string> ListConsumerNamesAsync(string stream, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<bool> DeleteConsumerAsync(string stream, string consumer, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<AccountInfoResponse> GetAccountInfoAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<PubAckResponse> PublishAsync<T>(string subject, T? data, INatsSerialize<T>? serializer = default, NatsJSPubOpts? opts = default, NatsHeaders? headers = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<INatsJSStream> CreateStreamAsync(StreamConfig config, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<bool> DeleteStreamAsync(string stream, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<StreamPurgeResponse> PurgeStreamAsync(string stream, StreamPurgeRequest request, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<StreamMsgDeleteResponse> DeleteMessageAsync(string stream, StreamMsgDeleteRequest request, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<INatsJSStream> GetStreamAsync(string stream, StreamInfoRequest? request = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public ValueTask<NatsJSStream> UpdateStreamAsync(StreamConfig request, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public IAsyncEnumerable<INatsJSStream> ListStreamsAsync(string? subject = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
|
||
public IAsyncEnumerable<string> ListStreamNamesAsync(string? subject = default, CancellationToken cancellationToken = default) => throw new NotImplementedException(); | ||
} | ||
} |