/// <summary> /// Creates a new <see cref="ObjectResultExecutor"/>. /// </summary> /// <param name="formatterSelector">The <see cref="OutputFormatterSelector"/>.</param> /// <param name="writerFactory">The <see cref="IHttpResponseStreamWriterFactory"/>.</param> /// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param> /// <param name="mvcOptions">Accessor to <see cref="MvcOptions"/>.</param> public ObjectResultExecutor( OutputFormatterSelector formatterSelector, IHttpResponseStreamWriterFactory writerFactory, ILoggerFactory loggerFactory, IOptions <MvcOptions> mvcOptions) { if (formatterSelector == null) { throw new ArgumentNullException(nameof(formatterSelector)); } if (writerFactory == null) { throw new ArgumentNullException(nameof(writerFactory)); } if (loggerFactory == null) { throw new ArgumentNullException(nameof(loggerFactory)); } FormatterSelector = formatterSelector; WriterFactory = writerFactory.CreateWriter; Logger = loggerFactory.CreateLogger <ObjectResultExecutor>(); var options = mvcOptions?.Value ?? throw new ArgumentNullException(nameof(mvcOptions)); _asyncEnumerableReaderFactory = new AsyncEnumerableReader(options); }
public SystemTextJsonResultExecutor( IOptions <JsonOptions> options, ILogger <SystemTextJsonResultExecutor> logger, IOptions <MvcOptions> mvcOptions) { _options = options.Value; _logger = logger; _asyncEnumerableReader = new AsyncEnumerableReader(mvcOptions.Value); }
public async Task Reader_ThrowsIfIAsyncEnumerableThrows() { // Arrange var enumerable = ThrowingAsyncEnumerable(); var options = new MvcOptions(); var readerFactory = new AsyncEnumerableReader(options); // Act & Assert Assert.True(readerFactory.TryGetReader(enumerable.GetType(), out var reader)); await Assert.ThrowsAsync <TimeZoneNotFoundException>(() => reader(enumerable, default)); }
public void TryGetReader_ReturnsFalse_IfTypeIsNotIAsyncEnumerable(Type type) { // Arrange var options = new MvcOptions(); var readerFactory = new AsyncEnumerableReader(options); var asyncEnumerable = TestEnumerable(); // Act var result = readerFactory.TryGetReader(type, out var reader); // Assert Assert.False(result); }
public async Task ReadAsync_ReadsIAsyncEnumerable() { // Arrange var options = new MvcOptions(); var reader = new AsyncEnumerableReader(options); // Act var result = await reader.ReadAsync(TestEnumerable()); // Assert var collection = Assert.IsAssignableFrom <ICollection <string> >(result); Assert.Equal(new[] { "0", "1", "2", }, collection); }
public void TryGetReader_ReturnsCachedDelegate_WhenTypeImplementsMultipleIAsyncEnumerableContracts() { // Arrange var options = new MvcOptions(); var readerFactory = new AsyncEnumerableReader(options); var asyncEnumerable1 = new MultiAsyncEnumerable(); var asyncEnumerable2 = new MultiAsyncEnumerable(); // Act Assert.True(readerFactory.TryGetReader(asyncEnumerable1.GetType(), out var reader1)); Assert.True(readerFactory.TryGetReader(asyncEnumerable2.GetType(), out var reader2)); // Assert Assert.Same(reader1, reader2); }
public void TryGetReader_ReturnsCachedDelegate() { // Arrange var options = new MvcOptions(); var readerFactory = new AsyncEnumerableReader(options); var asyncEnumerable1 = TestEnumerable(); var asyncEnumerable2 = TestEnumerable(); // Act Assert.True(readerFactory.TryGetReader(asyncEnumerable1.GetType(), out var reader1)); Assert.True(readerFactory.TryGetReader(asyncEnumerable2.GetType(), out var reader2)); // Assert Assert.Same(reader1, reader2); }
public void TryGetReader_ReturnsDifferentInstancesForDifferentEnumerables() { // Arrange var options = new MvcOptions(); var readerFactory = new AsyncEnumerableReader(options); var enumerable1 = TestEnumerable(); var enumerable2 = TestEnumerable2(); // Act Assert.True(readerFactory.TryGetReader(enumerable1.GetType(), out var reader1)); Assert.True(readerFactory.TryGetReader(enumerable2.GetType(), out var reader2)); // Assert Assert.NotSame(reader1, reader2); }
public async Task CachedDelegate_CanReadEnumerableInstanceMultipleTimes_ThatProduceDifferentResults() { // Arrange var options = new MvcOptions(); var readerFactory = new AsyncEnumerableReader(options); var asyncEnumerable1 = TestEnumerable(); var asyncEnumerable2 = TestEnumerable(4); // Act Assert.True(readerFactory.TryGetReader(asyncEnumerable1.GetType(), out var reader)); // Assert Assert.Equal(new[] { "0", "1", "2" }, await reader(asyncEnumerable1, default)); Assert.Equal(new[] { "0", "1", "2", "3" }, await reader(asyncEnumerable2, default)); }
public async Task ReadAsync_ReadsIAsyncEnumerable_ImplementingMultipleAsyncEnumerableInterfaces() { // This test ensures the reader does not fail if you have a type that implements IAsyncEnumerable for multiple Ts // Arrange var options = new MvcOptions(); var reader = new AsyncEnumerableReader(options); // Act var result = await reader.ReadAsync(new MultiAsyncEnumerable()); // Assert var collection = Assert.IsAssignableFrom <ICollection <object> >(result); Assert.Equal(new[] { "0", "1", "2", }, collection); }
public async Task CachedDelegate_CanReadEnumerableInstanceMultipleTimes() { // Arrange var options = new MvcOptions(); var readerFactory = new AsyncEnumerableReader(options); var asyncEnumerable1 = TestEnumerable(); var asyncEnumerable2 = TestEnumerable(); var expected = new[] { "0", "1", "2" }; // Act Assert.True(readerFactory.TryGetReader(asyncEnumerable1.GetType(), out var reader)); // Assert Assert.Equal(expected, await reader(asyncEnumerable1)); Assert.Equal(expected, await reader(asyncEnumerable2)); }
public async Task Reader_PassesCancellationTokenToIAsyncEnumerable() { // Arrange var enumerable = AsyncEnumerable(); var options = new MvcOptions(); CancellationToken token = default; var readerFactory = new AsyncEnumerableReader(options); var cts = new CancellationTokenSource(); // Act & Assert Assert.True(readerFactory.TryGetReader(enumerable.GetType(), out var reader)); await reader(enumerable, cts.Token); cts.Cancel(); Assert.Equal(cts.Token, token); async IAsyncEnumerable <string> AsyncEnumerable([EnumeratorCancellation] CancellationToken cancellationToken = default)
public async Task TryGetReader_ReturnsReaderForIAsyncEnumerableOfValueType() { // Arrange var options = new MvcOptions(); var readerFactory = new AsyncEnumerableReader(options); var asyncEnumerable = PrimitiveEnumerable(); // Act var result = readerFactory.TryGetReader(asyncEnumerable.GetType(), out var reader); // Assert Assert.True(result); var readCollection = await reader(asyncEnumerable, default); var collection = Assert.IsAssignableFrom <ICollection <int> >(readCollection); Assert.Equal(new[] { 0, 1, 2, }, collection); }
public async Task TryGetReader_ReturnsReaderForIAsyncEnumerable() { // Arrange var options = new MvcOptions(); var readerFactory = new AsyncEnumerableReader(options); var asyncEnumerable = TestEnumerable(); // Act var result = readerFactory.TryGetReader(asyncEnumerable.GetType(), out var reader); // Assert Assert.True(result); var readCollection = await reader(asyncEnumerable, default); var collection = Assert.IsAssignableFrom <ICollection <string> >(readCollection); Assert.Equal(new[] { "0", "1", "2", }, collection); }
public async Task ReadAsync_ThrowsIfBufferimitIsReached() { // Arrange var enumerable = TestEnumerable(11); var expected = $"'AsyncEnumerableReader' reached the configured maximum size of the buffer when enumerating a value of type '{enumerable.GetType()}'. " + "This limit is in place to prevent infinite streams of 'IAsyncEnumerable<>' from continuing indefinitely. If this is not a programming mistake, " + $"consider ways to reduce the collection size, or consider manually converting '{enumerable.GetType()}' into a list rather than increasing the limit."; var options = new MvcOptions { MaxIAsyncEnumerableBufferLimit = 10 }; var reader = new AsyncEnumerableReader(options); // Act var ex = await Assert.ThrowsAsync <InvalidOperationException>(() => reader.ReadAsync(enumerable)); // Assert Assert.Equal(expected, ex.Message); }
public async Task Reader_ReadsIAsyncEnumerable_ImplementingMultipleAsyncEnumerableInterfaces() { // This test ensures the reader does not fail if you have a type that implements IAsyncEnumerable for multiple Ts // Arrange var options = new MvcOptions(); var readerFactory = new AsyncEnumerableReader(options); var asyncEnumerable = new MultiAsyncEnumerable(); // Act var result = readerFactory.TryGetReader(asyncEnumerable.GetType(), out var reader); // Assert Assert.True(result); var readCollection = await reader(asyncEnumerable, default); var collection = Assert.IsAssignableFrom <ICollection <object> >(readCollection); Assert.Equal(new[] { "0", "1", "2", }, collection); }