public async Task Async(string csv, ReadRowEnding expected, string valueSep = ",") { var opts = Options.CreateBuilder(Options.Default).WithReadRowEnding(ReadRowEnding.Detect).WithValueSeparator(valueSep).BuildInternal(); await RunAsyncReaderVariants <_Test>( opts, async (config, getReader) => { var configForced = config as AsyncCountingAndForcingConfig <_Test>; var configCancel = config as AsyncCancelControlConfig <_Test>; var cInner = (ConcreteBoundConfiguration <_Test>)(configForced?.Inner ?? configCancel?.Inner ?? config); await using (var str = await getReader(csv)) { var stateMachine = new ReaderStateMachine(); var charLookup = CharacterLookup.MakeCharacterLookup(cInner.Options, out _); using (var detector = new RowEndingDetector(stateMachine, cInner.Options, MemoryPool <char> .Shared, charLookup, str, cInner.Options.ValueSeparator.AsMemory())) { if (configForced != null) { configForced.Set(detector); } var detect = await detector.DetectAsync(CancellationToken.None); Assert.True(detect.HasValue); Assert.Equal(expected, detect.Value.Ending); } } }, cancellable : false ); }
public async Task ManyHeadersAsync() { var config = Configuration.For <_ManyHeaders>(Options.Default.NewBuilder().WithRowEnding(RowEndings.CarriageReturnLineFeed).Build()); var csv = string.Join( ",", new[] { nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader1), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader2), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader3), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader4), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader5), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader6), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader7), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader8), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader9), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader10) } ); await RunAsyncReaderVariants <_ManyHeaders>( Options.Default, async (config, makeReader) => { var c = (ConcreteBoundConfiguration <_ManyHeaders>)config; using (var str = makeReader(csv)) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(c.MemoryPool, c.EscapedValueStartAndStop, c.ValueSeparator, c.EscapeValueEscapeChar, c.CommentChar); using var reader = new HeadersReader <_ManyHeaders>(c, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = await reader.ReadAsync(default);
public void Sync(string csv, RowEndings expected) { var config = (ConcreteBoundConfiguration <_Test>)Configuration.For <_Test>(Options.Default.NewBuilder().WithReadHeader(ReadHeaders.None).WithRowEnding(RowEndings.Detect).BuildInternal()); using (var str = new StringReader(csv)) { using (var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar)) { var detector = new RowEndingDetector <_Test>(config, charLookup, str); var detect = detector.Detect(); Assert.True(detect.HasValue); Assert.Equal(expected, detect.Value.Ending); } } }
public void BufferToLarge() { var config = (ConcreteBoundConfiguration <_BufferToLarge>)Configuration.For <_BufferToLarge>(Options.Default.NewBuilder().WithMemoryPool(new TestMemoryPool <char>(16)).Build()); // none { using (var str = new StringReader("foo,fizz,bar,buzz,baz,nope,nada,zilch,what,who,when,where,qwerty,dvorak")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(MemoryPool <char> .Shared, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using (var reader = new HeadersReader <_BufferToLarge>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500))) { Assert.Throws <InvalidOperationException>(() => reader.Read()); } } } }
public void ManyHeaders() { var csv = string.Join( ",", new[] { nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader1), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader2), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader3), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader4), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader5), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader6), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader7), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader8), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader9), nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader10) } ); var config = (ConcreteBoundConfiguration <_ManyHeaders>)Configuration.For <_ManyHeaders>(Options.Default.NewBuilder().WithRowEnding(RowEndings.CarriageReturnLineFeed).Build()); using (var str = new StringReader(csv)) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_ManyHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal(nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader1), new string(i.Span)), i => Assert.Equal(nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader2), new string(i.Span)), i => Assert.Equal(nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader3), new string(i.Span)), i => Assert.Equal(nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader4), new string(i.Span)), i => Assert.Equal(nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader5), new string(i.Span)), i => Assert.Equal(nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader6), new string(i.Span)), i => Assert.Equal(nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader7), new string(i.Span)), i => Assert.Equal(nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader8), new string(i.Span)), i => Assert.Equal(nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader9), new string(i.Span)), i => Assert.Equal(nameof(_ManyHeaders.LoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongHeader10), new string(i.Span)) ); Assert.True(res.IsHeader); } }
public async Task Async(string csv, RowEndings expected) { var config = (ConcreteBoundConfiguration <_Test>)Configuration.For <_Test>(Options.Default.NewBuilder().WithReadHeader(ReadHeaders.None).WithRowEnding(RowEndings.Detect).BuildInternal()); await RunAsyncReaderVariants <_Foo>( Options.Default, async (_, getReader) => { using (var str = getReader(csv)) { using (var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar)) { var detector = new RowEndingDetector <_Test>(config, charLookup, str); var detect = await detector.DetectAsync(CancellationToken.None); Assert.True(detect.HasValue); Assert.Equal(expected, detect.Value.Ending); } } } ); }
public void JustHeaders() { var config = (ConcreteBoundConfiguration <_JustHeaders>)Configuration.For <_JustHeaders>(); // none { using (var str = new StringReader("fizz")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection(ToEnumerable(res.Headers), i => Assert.Equal("fizz", new string(i.Span))); Assert.False(res.IsHeader); } } // one, exact { using (var str = new StringReader("Foo")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection(ToEnumerable(res.Headers), i => Assert.Equal("Foo", new string(i.Span))); Assert.True(res.IsHeader); } } // one, inexact { using (var str = new StringReader("Foo,fizz")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Foo", new string(i.Span)), i => Assert.Equal("fizz", new string(i.Span)) ); Assert.True(res.IsHeader); } using (var str = new StringReader("fizz,Bar")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("fizz", new string(i.Span)), i => Assert.Equal("Bar", new string(i.Span)) ); Assert.True(res.IsHeader); } } // two, exact { using (var str = new StringReader("Foo,Bar")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Foo", new string(i.Span)), i => Assert.Equal("Bar", new string(i.Span)) ); Assert.True(res.IsHeader); } using (var str = new StringReader("Bar,Foo")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Bar", new string(i.Span)), i => Assert.Equal("Foo", new string(i.Span)) ); Assert.True(res.IsHeader); } } // two, inexact { using (var str = new StringReader("Foo,Bar,Fizz")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Foo", new string(i.Span)), i => Assert.Equal("Bar", new string(i.Span)), i => Assert.Equal("Fizz", new string(i.Span)) ); Assert.True(res.IsHeader); } using (var str = new StringReader("Bar,Fizz,Foo")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Bar", new string(i.Span)), i => Assert.Equal("Fizz", new string(i.Span)), i => Assert.Equal("Foo", new string(i.Span)) ); Assert.True(res.IsHeader); } } }
public async Task JustHeadersAsync() { var config = (ConcreteBoundConfiguration <_JustHeaders>)Configuration.For <_JustHeaders>(Options.Default.NewBuilder().WithRowEnding(RowEndings.CarriageReturnLineFeed).Build()); // none { await RunAsyncReaderVariants <_Foo>( Options.Default, async (_, getReader) => { using (var str = getReader("fizz")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = await reader.ReadAsync(CancellationToken.None); Assert.Collection(ToEnumerable(res.Headers), i => Assert.Equal("fizz", new string(i.Span))); Assert.False(res.IsHeader); } } ); } // one, exact { await RunAsyncReaderVariants <_Foo>( Options.Default, async (_, getReader) => { using (var str = getReader("Foo")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = await reader.ReadAsync(CancellationToken.None); Assert.Collection(ToEnumerable(res.Headers), i => Assert.Equal("Foo", new string(i.Span))); Assert.True(res.IsHeader); } } ); } // one, inexact { await RunAsyncReaderVariants <_Foo>( Options.Default, async (_, getReader) => { using (var str = getReader("Foo,fizz")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = await reader.ReadAsync(CancellationToken.None); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Foo", new string(i.Span)), i => Assert.Equal("fizz", new string(i.Span)) ); Assert.True(res.IsHeader); } } ); await RunAsyncReaderVariants <_Foo>( Options.Default, async (_, getReader) => { using (var str = getReader("fizz,Bar")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = await reader.ReadAsync(CancellationToken.None); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("fizz", new string(i.Span)), i => Assert.Equal("Bar", new string(i.Span)) ); Assert.True(res.IsHeader); } } ); } // two, exact { await RunAsyncReaderVariants <_Foo>( Options.Default, async (_, getReader) => { using (var str = getReader("Foo,Bar")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = await reader.ReadAsync(CancellationToken.None); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Foo", new string(i.Span)), i => Assert.Equal("Bar", new string(i.Span)) ); Assert.True(res.IsHeader); } } ); await RunAsyncReaderVariants <_Foo>( Options.Default, async (_, getReader) => { using (var str = getReader("Bar,Foo")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = await reader.ReadAsync(CancellationToken.None); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Bar", new string(i.Span)), i => Assert.Equal("Foo", new string(i.Span)) ); Assert.True(res.IsHeader); } } ); } // two, inexact { await RunAsyncReaderVariants <_Foo>( Options.Default, async (_, getReader) => { using (var str = getReader("Foo,Bar,Fizz")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = await reader.ReadAsync(CancellationToken.None); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Foo", new string(i.Span)), i => Assert.Equal("Bar", new string(i.Span)), i => Assert.Equal("Fizz", new string(i.Span)) ); Assert.True(res.IsHeader); } } ); await RunAsyncReaderVariants <_Foo>( Options.Default, async (_, getReader) => { using (var str = getReader("Bar,Fizz,Foo")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = await reader.ReadAsync(CancellationToken.None); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Bar", new string(i.Span)), i => Assert.Equal("Fizz", new string(i.Span)), i => Assert.Equal("Foo", new string(i.Span)) ); Assert.True(res.IsHeader); } } ); } }
public void TrailingRecords() { var config = (ConcreteBoundConfiguration <_JustHeaders>)Configuration.For <_JustHeaders>(Options.Default.NewBuilder().WithRowEnding(RowEndings.CarriageReturnLineFeed).Build()); // none { using (var str = new StringReader("fizz\r\n0\r\n")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection(ToEnumerable(res.Headers), i => Assert.Equal("fizz", new string(i.Span))); Assert.False(res.IsHeader); } } // one, exact { using (var str = new StringReader("Foo\r\nfoo")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection(ToEnumerable(res.Headers), i => Assert.Equal("Foo", new string(i.Span))); Assert.True(res.IsHeader); } } // one, inexact { using (var str = new StringReader("Foo,fizz\r\n1,2")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Foo", new string(i.Span)), i => Assert.Equal("fizz", new string(i.Span)) ); Assert.True(res.IsHeader); } using (var str = new StringReader("fizz,Bar\r\n2,blah\r\n")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("fizz", new string(i.Span)), i => Assert.Equal("Bar", new string(i.Span)) ); Assert.True(res.IsHeader); } } // two, exact { using (var str = new StringReader("Foo,Bar\r\nwhatever,something")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Foo", new string(i.Span)), i => Assert.Equal("Bar", new string(i.Span)) ); Assert.True(res.IsHeader); } using (var str = new StringReader("Bar,Foo\r\n3,4")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Bar", new string(i.Span)), i => Assert.Equal("Foo", new string(i.Span)) ); Assert.True(res.IsHeader); } } // two, inexact { using (var str = new StringReader("Foo,Bar,Fizz\r\na,b,c\r\n")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Foo", new string(i.Span)), i => Assert.Equal("Bar", new string(i.Span)), i => Assert.Equal("Fizz", new string(i.Span)) ); Assert.True(res.IsHeader); } using (var str = new StringReader("Bar,Fizz,Foo\r\n1,2,3")) { using var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar); using var reader = new HeadersReader <_JustHeaders>(config, charLookup, str, new BufferWithPushback(MemoryPool <char> .Shared, 500)); var res = reader.Read(); Assert.Collection( ToEnumerable(res.Headers), i => Assert.Equal("Bar", new string(i.Span)), i => Assert.Equal("Fizz", new string(i.Span)), i => Assert.Equal("Foo", new string(i.Span)) ); Assert.True(res.IsHeader); } } }
public void IDisposable() { var implementors = typeof(Options).Assembly .GetTypes() .Where(t => t.GetInterfaces().Any(x => x == typeof(IDisposable))) .Where(t => !t.IsInterface) .Where(t => !t.IsAbstract) .Where(t => !t.Name.Contains("<")); // exclude compiler generated classes, let's assume they get it right? foreach (var t in implementors) { if (t == typeof(Reader <>)) { IDisposable_Reader(); } else if (t == typeof(ReaderStateMachine)) { IDisposable_ReaderStateMachine(); } else if (t == typeof(Writer <>)) { IDisposable_Writer(); } else if (t == typeof(BufferWithPushback)) { IDisposable_BufferWithPushback(); } else if (t == typeof(MaybeInPlaceBuffer <>)) { IDisposable_MaybeInPlaceBuffer(); } else if (t == typeof(Partial <>)) { IDisposable_Partial(); } else if (t == typeof(RowEndingDetector <>)) { IDisposable_RowEndingDetector(); } else if (t == typeof(HeadersReader <>)) { IDisposable_HeadersReader(); } else if (t == typeof(HeadersReader <> .HeaderEnumerator)) { IDisposable_HeaderEnumerator(); } else if (t == typeof(ReaderStateMachine.CharacterLookup)) { IDisposable_CharacterLookup(); } else if (t == typeof(MaxSizedBufferWriter)) { IDisposable_MaxSizedBufferWriter(); } else if (t == typeof(DynamicReader)) { IDisposable_DynamicReader(); } else if (t == typeof(DynamicRow)) { IDisposable_DynamicRow(); } else if (t == typeof(DynamicRowEnumerable <>)) { IDisposable_DynamicRowEnumerable(); } else if (t == typeof(DynamicRowEnumerator <>)) { IDisposable_DynamicRowEnumerator(); } else { throw new XunitException($"No test configured for .Dispose() on {t.Name}"); } } // test for Reader void IDisposable_Reader() { // double dispose does not error { var r = MakeReader(); r.Dispose(); r.Dispose(); } // assert throws after dispose { var r = MakeReader(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)r).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var r = MakeReader()) { expectedTestCases = GetNumberExpectedDisposableTestCases(r); } } // EnumerateAll { var r = MakeReader(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => r.EnumerateAll()); testCases++; } // ReadAll { var r = MakeReader(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => r.ReadAll()); testCases++; } // ReadAll pre-allocated { var r = MakeReader(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => r.ReadAll(new List <_IDisposable>())); testCases++; } // TryRead { var r = MakeReader(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => r.TryRead(out _)); testCases++; } // TryReadWithReuse { var r = MakeReader(); r.Dispose(); _IDisposable x = null; Assert.Throws <ObjectDisposedException>(() => r.TryReadWithReuse(ref x)); testCases++; } Assert.Equal(expectedTestCases, testCases); // make a reader that's "good to go" IReader <_IDisposable> MakeReader() { return (Configuration.For <_IDisposable>(Options.Default) .CreateReader( new StringReader("") )); } } // test for ReaderStateMachine void IDisposable_ReaderStateMachine() { // double dispose does not error { var r = MakeReader(); r.Dispose(); r.Dispose(); } // assert throws after dispose { var r = MakeReader(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)r).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var r = MakeReader()) { expectedTestCases = GetNumberExpectedDisposableTestCases(r); } } Assert.Equal(expectedTestCases, testCases); // make a reader that's "good to go" ReaderStateMachine MakeReader() { return (new ReaderStateMachine(MemoryPool <char> .Shared, 'a', 'b', 'c', RowEndings.CarriageReturnLineFeed, ReadHeaders.Always, 'd')); } } // test for Writer void IDisposable_Writer() { // double dispose does not error { var w = MakeWriter(); w.Dispose(); w.Dispose(); } // assert throws after dispose { var w = MakeWriter(); w.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)w).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var w = MakeWriter()) { expectedTestCases = GetNumberExpectedDisposableTestCases(w); } } // Write { var w = MakeWriter(); w.Dispose(); Assert.Throws <ObjectDisposedException>(() => w.Write(new _IDisposable())); testCases++; } // WriteAll { var w = MakeWriter(); w.Dispose(); Assert.Throws <ObjectDisposedException>(() => w.WriteAll(new[] { new _IDisposable() })); testCases++; } Assert.Equal(expectedTestCases, testCases); // make a writer that's "good to go" IWriter <_IDisposable> MakeWriter() { return (Configuration.For <_IDisposable>(Options.Default) .CreateWriter( new StringWriter() )); } } // test for BufferWithPushback void IDisposable_BufferWithPushback() { // double dispose does not error { var b = MakeBuffer(); b.Dispose(); b.Dispose(); } // assert throws after dispose { var b = MakeBuffer(); b.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)b).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var b = MakeBuffer()) { expectedTestCases = GetNumberExpectedDisposableTestCases(b); } } Assert.Equal(expectedTestCases, testCases); // make a buffer that's "good to go" BufferWithPushback MakeBuffer() { return(new BufferWithPushback(MemoryPool <char> .Shared, 64)); } } // test for MaybeInPlaceBuffer void IDisposable_MaybeInPlaceBuffer() { // double dispose does not error { var b = MakeBuffer(); b.Dispose(); b.Dispose(); } // assert throws after dispose { var b = MakeBuffer(); b.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)b).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var b = MakeBuffer()) { expectedTestCases = GetNumberExpectedDisposableTestCases(b); } } Assert.Equal(expectedTestCases, testCases); // make a buffer that's "good to go" MaybeInPlaceBuffer <char> MakeBuffer() { return(new MaybeInPlaceBuffer <char>(MemoryPool <char> .Shared)); } } // test for Partial void IDisposable_Partial() { // double dispose does not error { var p = MakePartial(); p.Dispose(); p.Dispose(); } // assert throws after dispose { var p = MakePartial(); p.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)p).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var p = MakePartial()) { expectedTestCases = GetNumberExpectedDisposableTestCases(p); } } Assert.Equal(expectedTestCases, testCases); // make a partial that's "good to go" Partial <_IDisposable> MakePartial() { return(new Partial <_IDisposable>(MemoryPool <char> .Shared)); } } // test for RowEndingDetector void IDisposable_RowEndingDetector() { // double dispose does not error { var d = MakeDetector(); d.Dispose(); d.Dispose(); } // assert throws after dispose { var d = MakeDetector(); d.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)d).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var d = MakeDetector()) { expectedTestCases = GetNumberExpectedDisposableTestCases(d); } } Assert.Equal(expectedTestCases, testCases); // make a partial that's "good to go" RowEndingDetector <_IDisposable> MakeDetector() { return(new RowEndingDetector <_IDisposable>( (ConcreteBoundConfiguration <_IDisposable>)Configuration.For <_IDisposable>(), ReaderStateMachine.MakeCharacterLookup(MemoryPool <char> .Shared, 'a', 'b', 'c', 'd'), TextReader.Null )); } } // test for HeadersReader void IDisposable_HeadersReader() { // double dispose does not error { var r = MakeReader(); r.Dispose(); r.Dispose(); } // assert throws after dispose { var r = MakeReader(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)r).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var r = MakeReader()) { expectedTestCases = GetNumberExpectedDisposableTestCases(r); } } Assert.Equal(expectedTestCases, testCases); // make a partial that's "good to go" HeadersReader <_IDisposable> MakeReader() { var config = (ConcreteBoundConfiguration <_IDisposable>)Configuration.For <_IDisposable>(); return (new HeadersReader <_IDisposable>( config, ReaderStateMachine.MakeCharacterLookup(MemoryPool <char> .Shared, 'a', 'b', 'c', 'd'), TextReader.Null, new BufferWithPushback(MemoryPool <char> .Shared, 64) )); } } // test HeaderEnumerator void IDisposable_HeaderEnumerator() { // double dispose does not error { var e = MakeEnumerator(); e.Dispose(); e.Dispose(); } // assert throws after dispose { var e = MakeEnumerator(); e.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)e).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var e = MakeEnumerator()) { expectedTestCases = GetNumberExpectedDisposableTestCases(e); } } // Current { var e = MakeEnumerator(); e.Dispose(); Assert.Throws <ObjectDisposedException>(() => e.Current); testCases++; } // MoveNext { var e = MakeEnumerator(); e.Dispose(); Assert.Throws <ObjectDisposedException>(() => e.MoveNext()); testCases++; } // Reset { var e = MakeEnumerator(); e.Dispose(); Assert.Throws <ObjectDisposedException>(() => e.Reset()); testCases++; } Assert.Equal(expectedTestCases, testCases); // make a partial that's "good to go" HeadersReader <_IDisposable> .HeaderEnumerator MakeEnumerator() { return(new HeadersReader <_IDisposable> .HeaderEnumerator(0, ReadOnlyMemory <char> .Empty)); } } // test CharacterLookup void IDisposable_CharacterLookup() { // double dispose does not error { var l = MakeLookup(); l.Dispose(); l.Dispose(); } // assert throws after dispose { var l = MakeLookup(); l.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)l).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var l = MakeLookup()) { expectedTestCases = GetNumberExpectedDisposableTestCases(l); } } Assert.Equal(expectedTestCases, testCases); // make a partial that's "good to go" ReaderStateMachine.CharacterLookup MakeLookup() { return(ReaderStateMachine.MakeCharacterLookup(MemoryPool <char> .Shared, 'a', 'b', 'c', 'd')); } } // test CharacterLookup void IDisposable_MaxSizedBufferWriter() { // double dispose does not error { var w = MakeWriter(); w.Dispose(); w.Dispose(); } // assert throws after dispose { var w = MakeWriter(); w.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)w).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var w = MakeWriter()) { expectedTestCases = GetNumberExpectedDisposableTestCases(w); } } // Advance { var w = MakeWriter(); w.Dispose(); Assert.Throws <ObjectDisposedException>(() => w.Advance(0)); testCases++; } // GetMemory { var w = MakeWriter(); w.Dispose(); Assert.Throws <ObjectDisposedException>(() => w.GetMemory(0)); testCases++; } // GetSpan { var w = MakeWriter(); w.Dispose(); Assert.Throws <ObjectDisposedException>(() => w.GetSpan(0)); testCases++; } Assert.Equal(expectedTestCases, testCases); // make a partial that's "good to go" MaxSizedBufferWriter MakeWriter() { return(new MaxSizedBufferWriter(MemoryPool <char> .Shared, null)); } } // test for DynamicReader void IDisposable_DynamicReader() { // double dispose does not error { var r = MakeReader(); r.Dispose(); r.Dispose(); } // assert throws after dispose { var r = MakeReader(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)r).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var r = MakeReader()) { expectedTestCases = GetNumberExpectedDisposableTestCases(r); } } // EnumerateAll { var r = MakeReader(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => r.EnumerateAll()); testCases++; } // ReadAll { var r = MakeReader(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => r.ReadAll()); testCases++; } // ReadAll pre-allocated { var r = MakeReader(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => r.ReadAll(new List <dynamic>())); testCases++; } // TryRead { var r = MakeReader(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => r.TryRead(out _)); testCases++; } // TryReadWithReuse { var r = MakeReader(); r.Dispose(); dynamic x = null; Assert.Throws <ObjectDisposedException>(() => r.TryReadWithReuse(ref x)); testCases++; } Assert.Equal(expectedTestCases, testCases); // make a reader that's "good to go" IReader <dynamic> MakeReader() { return (Configuration.ForDynamic(Options.Default.NewBuilder().WithReadHeader(ReadHeaders.Always).Build()) .CreateReader(new StringReader(""))); } } // test for DynamicRow void IDisposable_DynamicRow() { // double dispose does not error { var r = MakeRow(); r.Dispose(); r.Dispose(); } // assert throws after dispose { var r = MakeRow(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)r).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var r = MakeRow()) { expectedTestCases = GetNumberExpectedDisposableTestCases(r); } } Assert.Equal(expectedTestCases, testCases); // make a reader that's "good to go" DynamicRow MakeRow() { return(new DynamicRow()); } } // test for DynamicRowEnumerable void IDisposable_DynamicRowEnumerable() { // double dispose does not error { var r = MakeDynamicRowEnumerable(); r.Dispose(); r.Dispose(); } // assert throws after dispose { var r = MakeDynamicRowEnumerable(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)r).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var r = MakeDynamicRowEnumerable()) { expectedTestCases = GetNumberExpectedDisposableTestCases(r); } } // GetEnumerator { var r = MakeDynamicRowEnumerable(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => r.GetEnumerator()); testCases++; } Assert.Equal(expectedTestCases, testCases); // make a reader that's "good to go" DynamicRowEnumerable <_IDisposable> MakeDynamicRowEnumerable() { return(new DynamicRowEnumerable <_IDisposable>(new DynamicRow())); } } // test for DynamicRowEnumerator void IDisposable_DynamicRowEnumerator() { // double dispose does not error { var r = MakeDynamicRowEnumerator(); r.Dispose(); r.Dispose(); } // assert throws after dispose { var r = MakeDynamicRowEnumerator(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => ((ITestableDisposable)r).AssertNotDisposed()); } var testCases = 0; // figure out how many _public_ methods need testing int expectedTestCases; { using (var r = MakeDynamicRowEnumerator()) { expectedTestCases = GetNumberExpectedDisposableTestCases(r); } } // Current { var r = MakeDynamicRowEnumerator(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => r.Current); testCases++; } // MoveNext { var r = MakeDynamicRowEnumerator(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => r.MoveNext()); testCases++; } // Reset { var r = MakeDynamicRowEnumerator(); r.Dispose(); Assert.Throws <ObjectDisposedException>(() => r.Reset()); testCases++; } Assert.Equal(expectedTestCases, testCases); // make a reader that's "good to go" IEnumerator <string> MakeDynamicRowEnumerator() { var opts = Options.Default.NewBuilder().WithReadHeader(ReadHeaders.Never).Build(); var config = Configuration.ForDynamic(opts); var r = config.CreateReader(new StringReader("a,b,c")); r.TryRead(out var row); IEnumerable <string> e = row; var ee = e.GetEnumerator(); return(ee); } } }