summaryrefslogtreecommitdiff
path: root/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserTests.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserTests.cs')
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserTests.cs1370
1 files changed, 1370 insertions, 0 deletions
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserTests.cs
new file mode 100644
index 0000000..78beeaf
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserTests.cs
@@ -0,0 +1,1370 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvParserTests
+ {
+ [Fact]
+ public void SimpleParseTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("3,4\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.True(parser.Read());
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ParseNewRecordTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("four,five,six");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ var count = 0;
+ while (parser.Read())
+ {
+ count++;
+ }
+
+ Assert.Equal(2, count);
+ }
+
+ [Fact]
+ public void ParseEmptyRowsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = true,
+ };
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("four,five,six");
+ writer.WriteLine(",,");
+ writer.WriteLine("");
+ writer.WriteLine("");
+ writer.WriteLine("seven,eight,nine");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, config);
+
+ var records = new List<string[]>();
+ while (parser.Read())
+ {
+ records.Add(parser.Record);
+ }
+
+ Assert.Equal(4, records.Count);
+ }
+
+ [Fact]
+ public void ParseTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("four,five,six");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ Assert.True(parser.Read());
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("four", parser[0]);
+ Assert.Equal("five", parser[1]);
+ Assert.Equal("six", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+
+ [Fact]
+ public void ParseFieldQuotesTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,\"two\",three");
+ writer.WriteLine("four,\"\"\"five\"\"\",six");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ Assert.True(parser.Read());
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("four", parser[0]);
+ Assert.Equal("\"five\"", parser[1]);
+ Assert.Equal("six", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+
+ [Fact]
+ public void ParseSpacesTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine(" one , \"two three\" , four ");
+ writer.WriteLine(" \" five \"\" six \"\" seven \" ");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BadDataFound = null,
+ };
+ var parser = new CsvParser(reader, config);
+
+ Assert.True(parser.Read());
+ Assert.Equal(" one ", parser[0]);
+ Assert.Equal(" \"two three\" ", parser[1]);
+ Assert.Equal(" four ", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(" \" five \"\" six \"\" seven \" ", parser[0]);
+
+ Assert.False(parser.Read());
+ }
+
+ [Fact]
+ public void CallingReadMultipleTimesAfterDoneReadingTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("four,five,six");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ parser.Read();
+ parser.Read();
+ parser.Read();
+ parser.Read();
+ }
+
+ [Fact]
+ public void ParseEmptyTest()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ParseCrOnlyTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("\r");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ParseLfOnlyTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ParseCrLnOnlyTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void Parse1RecordWithNoCrlfTest()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.Write("one,two,three");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void Parse2RecordsLastWithNoCrlfTest()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.WriteLine("one,two,three");
+ streamWriter.Write("four,five,six");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ parser.Read();
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("four", parser[0]);
+ Assert.Equal("five", parser[1]);
+ Assert.Equal("six", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ParseFirstFieldIsEmptyQuotedTest()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.WriteLine("\"\",\"two\",\"three\"");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void ParseLastFieldIsEmptyQuotedTest()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.WriteLine("\"one\",\"two\",\"\"");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void ParseQuoteOnlyQuotedFieldTest()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.WriteLine("\"\"\"\",\"two\",\"three\"");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("\"", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void ParseRecordsWithOnlyOneField()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.WriteLine("row one");
+ streamWriter.WriteLine("row two");
+ streamWriter.WriteLine("row three");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.Count);
+ Assert.Equal("row one", parser[0]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.Count);
+ Assert.Equal("row two", parser[0]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.Count);
+ Assert.Equal("row three", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void ParseRecordWhereOnlyCarriageReturnLineEndingIsUsed()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.Write("one,two\r");
+ streamWriter.Write("three,four\r");
+ streamWriter.Write("five,six\r");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("three", parser[0]);
+ Assert.Equal("four", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("five", parser[0]);
+ Assert.Equal("six", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void ParseRecordWhereOnlyLineFeedLineEndingIsUsed()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.Write("one,two\n");
+ streamWriter.Write("three,four\n");
+ streamWriter.Write("five,six\n");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("three", parser[0]);
+ Assert.Equal("four", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("five", parser[0]);
+ Assert.Equal("six", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void ParseCommentedOutLineWithCommentsOn()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("#four,five,six");
+ writer.WriteLine("seven,eight,nine");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ };
+ var parser = new CsvParser(reader, config);
+
+ parser.Read();
+ parser.Read();
+ Assert.Equal("seven", parser[0]);
+ }
+
+ [Fact]
+ public void ParseCommentedOutLineWithCommentsOff()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = false,
+ };
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("#four,five,six");
+ writer.WriteLine("seven,eight,nine");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, config);
+
+ parser.Read();
+ parser.Read();
+ Assert.Equal("#four", parser[0]);
+ }
+
+ [Fact]
+ public void ParseCommentedOutLineWithDifferentCommentCommentsOn()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("*four,five,six");
+ writer.WriteLine("seven,eight,nine");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ Comment = '*',
+ };
+ var parser = new CsvParser(reader, config);
+
+ parser.Read();
+ parser.Read();
+ Assert.Equal("seven", parser[0]);
+ }
+
+ [Fact]
+ public void ParseUsingDifferentDelimiter()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one\ttwo\tthree");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "\t",
+ WhiteSpaceChars = new[] { ' ' },
+ };
+ var parser = new CsvParser(reader, config);
+
+ Assert.True(parser.Read());
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+ }
+
+ [Fact]
+ public void ParseUsingDifferentQuote()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("'one','two','three'");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Quote = '\''
+ };
+ var parser = new CsvParser(reader, config);
+
+ Assert.True(parser.Read());
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+ }
+
+ [Fact]
+ public void ParseFinalRecordWithNoEndOfLineTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("1,2,");
+ writer.Write("4,5,");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ Assert.True(parser.Read());
+ Assert.Equal("", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+
+ [Fact]
+ public void ParseLastLineHasNoCrLf()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.Write("a");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ Assert.True(parser.Read());
+ Assert.Equal("a", parser[0]);
+
+ Assert.False(parser.Read());
+ }
+
+ [Fact]
+ public void CharReadTotalTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new TestStreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ // This is a breakdown of the char counts.
+ // Read() will read up to the first line end char
+ // and any more on the line will get read with the next read.
+
+ // [I][d][,][N][a][m][e][\r][\n]
+ // 1 2 3 4 5 6 7 8 9
+ // [1][,][o][n][e][\r][\n]
+ // 10 11 12 13 14 15 16
+ // [,][\r][\n]
+ // 17 18 19
+ // [\r][\n]
+ // 20 21
+ // [#][ ][c][o][m][m][e][n][t][s][\r][\n]
+ // 22 23 24 25 26 27 28 29 30 31 32 33
+ // [2][,][t][w][o][\r][\n]
+ // 34 35 36 37 38 39 40
+ // [3][,]["][t][h][r][e][e][,][ ][f][o][u][r]["][\r][\n]
+ // 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
+
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.WriteLine(",");
+ writer.WriteLine("");
+ writer.WriteLine("# comments");
+ writer.WriteLine("2,two");
+ writer.WriteLine("3,\"three, four\"");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(9, parser.CharCount);
+
+ parser.Read();
+ Assert.Equal(16, parser.CharCount);
+
+ parser.Read();
+ Assert.Equal(19, parser.CharCount);
+
+ parser.Read();
+ Assert.Equal(40, parser.CharCount);
+
+ parser.Read();
+ Assert.Equal(57, parser.CharCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void StreamSeekingUsingCharPositionTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ // This is a breakdown of the char counts.
+ // Read() will read up to the first line end char
+ // and any more on the line will get read with the next read.
+
+ // [I][d][,][N][a][m][e][\r][\n]
+ // 1 2 3 4 5 6 7 8 9
+ // [1][,][o][n][e][\r][\n]
+ // 10 11 12 13 14 15 16
+ // [,][\r][\n]
+ // 17 18 19
+ // [\r][\n]
+ // 20 21
+ // [#][ ][c][o][m][m][e][n][t][s][\r][\n]
+ // 22 23 24 25 26 27 28 29 30 31 32 33
+ // [2][,][t][w][o][\r][\n]
+ // 34 35 36 37 38 39 40
+ // [3][,]["][t][h][r][e][e][,][ ][f][o][u][r]["][\r][\n]
+ // 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
+
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.WriteLine(",");
+ writer.WriteLine("");
+ writer.WriteLine("# comments");
+ writer.WriteLine("2,two");
+ writer.WriteLine("3,\"three, four\"");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal("Id", parser[0]);
+ Assert.Equal("Name", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.CharCount, SeekOrigin.Begin);
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("one", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.CharCount, SeekOrigin.Begin);
+ parser.Read();
+ Assert.Equal("", parser[0]);
+ Assert.Equal("", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.CharCount, SeekOrigin.Begin);
+ parser.Read();
+ Assert.Equal("2", parser[0]);
+ Assert.Equal("two", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.CharCount, SeekOrigin.Begin);
+ parser.Read();
+ Assert.Equal("3", parser[0]);
+ Assert.Equal("three, four", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void RowTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("3,4\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ var rowCount = 0;
+ while (parser.Read())
+ {
+ rowCount++;
+ Assert.Equal(rowCount, parser.Row);
+ }
+ }
+ }
+
+ [Fact]
+ public void RowBlankLinesTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("\r\n");
+ writer.Write("3,4\r\n");
+ writer.Write("\r\n");
+ writer.Write("5,6\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ var rowCount = 1;
+ while (parser.Read())
+ {
+ Assert.Equal(rowCount, parser.Row);
+ rowCount += 2;
+ }
+ }
+ }
+
+ [Fact]
+ public void IgnoreBlankLinesRowCountTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("1,a");
+ writer.WriteLine();
+ writer.WriteLine("3,c");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.Row);
+ Assert.Equal("1", parser[0]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Row);
+ Assert.Equal("3", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void DoNotIgnoreBlankLinesRowCountTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("1,a");
+ writer.WriteLine();
+ writer.WriteLine("3,c");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.Row);
+ Assert.Equal("1", parser[0]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Row);
+ Assert.Equal(1, parser.Count);
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Row);
+ Assert.Equal("3", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void RowCommentLinesTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("# comment 1\r\n");
+ writer.Write("3,4\r\n");
+ writer.Write("# comment 2\r\n");
+ writer.Write("5,6\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ var rowCount = 1;
+ while (parser.Read())
+ {
+ Assert.Equal(rowCount, parser.Row);
+ rowCount += 2;
+ }
+ }
+ }
+
+ [Fact]
+ public void RowRawTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new TestStreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("1,\"2");
+ writer.WriteLine("2 continued");
+ writer.WriteLine("end of 2\",3");
+ writer.WriteLine("4,5,6");
+ writer.WriteLine("7,\"8");
+ writer.WriteLine("8 continued");
+ writer.WriteLine("end of 8\",9");
+ writer.WriteLine("10,11,12");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2\r\n2 continued\r\nend of 2", parser[1]);
+ Assert.Equal("3", parser[2]);
+ Assert.Equal(3, parser.RawRow);
+
+ Assert.True(parser.Read());
+ Assert.Equal("4", parser[0]);
+ Assert.Equal("5", parser[1]);
+ Assert.Equal("6", parser[2]);
+ Assert.Equal(4, parser.RawRow);
+
+ Assert.True(parser.Read());
+ Assert.Equal("7", parser[0]);
+ Assert.Equal("8\r\n8 continued\r\nend of 8", parser[1]);
+ Assert.Equal("9", parser[2]);
+ Assert.Equal(7, parser.RawRow);
+
+ Assert.True(parser.Read());
+ Assert.Equal("10", parser[0]);
+ Assert.Equal("11", parser[1]);
+ Assert.Equal("12", parser[2]);
+ Assert.Equal(8, parser.RawRow);
+ }
+ }
+
+ [Fact]
+ public void ByteCountTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, config.Encoding))
+ using (var reader = new StreamReader(stream, config.Encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("3,4\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(5, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(10, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ByteCountTestWithQuotedFields()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, config.Encoding))
+ using (var reader = new StreamReader(stream, config.Encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,\"2\"\r\n");
+ writer.Write("\"3\",4\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(7, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(14, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ByteCountTestWithQuotedFieldsEmptyQuotedField()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, config.Encoding))
+ using (var reader = new StreamReader(stream, config.Encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,\"\",2\r\n");
+ writer.Write("\"3\",4,\"5\"\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(8, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(19, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ByteCountTestWithQuotedFieldsClosingQuoteAtStartOfBuffer()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true,
+ BufferSize = 4
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, config.Encoding))
+ using (var reader = new StreamReader(stream, config.Encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,\"2\",3\r\n");
+ writer.Write("\"4\",5,\"6\"\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(9, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(20, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ByteCountTestWithQuotedFieldsEscapedQuoteAtStartOfBuffer()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true,
+ BufferSize = 4
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, config.Encoding))
+ using (var reader = new StreamReader(stream, config.Encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,\"2a\",3\r\n");
+ writer.Write("\"\"\"4\"\"\",5,\"6\"\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(10, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(25, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ByteCountUsingCharWithMoreThanSingleByteTest()
+ {
+ var encoding = Encoding.Unicode;
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true,
+ Encoding = encoding,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, encoding))
+ using (var reader = new StreamReader(stream, encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ //崔钟铉
+ writer.Write("1,崔\r\n");
+ writer.Write("3,钟\r\n");
+ writer.Write("5,铉\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(10, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(20, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(30, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void StreamSeekingUsingByteCountTest()
+ {
+ var encoding = Encoding.Unicode;
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ CountBytes = true,
+ Encoding = encoding,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, encoding))
+ using (var reader = new StreamReader(stream, encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ // This is a breakdown of the char counts.
+ // Read() will read up to the first line end char
+ // and any more on the line will get read with the next read.
+
+ // [I][d][,][N][a][m][e][\r][\n]
+ // 1 2 3 4 5 6 7 8 9
+ // [1][,][o][n][e][\r][\n]
+ // 10 11 12 13 14 15 16
+ // [,][\r][\n]
+ // 17 18 19
+ // [\r][\n]
+ // 20 21
+ // [#][ ][c][o][m][m][e][n][t][s][\r][\n]
+ // 22 23 24 25 26 27 28 29 30 31 32 33
+ // [2][,][t][w][o][\r][\n]
+ // 34 35 36 37 38 39 40
+ // [3][,]["][t][h][r][e][e][,][ ][f][o][u][r]["][\r][\n]
+ // 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
+
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.WriteLine(",");
+ writer.WriteLine("");
+ writer.WriteLine("# comments");
+ writer.WriteLine("2,two");
+ writer.WriteLine("3,\"three, four\"");
+ writer.Flush();
+ stream.Position = 0;
+
+ var record = parser.Read();
+ Assert.Equal("Id", parser[0]);
+ Assert.Equal("Name", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.ByteCount, SeekOrigin.Begin);
+ record = parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("one", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.ByteCount, SeekOrigin.Begin);
+ record = parser.Read();
+ Assert.Equal("", parser[0]);
+ Assert.Equal("", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.ByteCount, SeekOrigin.Begin);
+ record = parser.Read();
+ Assert.Equal("2", parser[0]);
+ Assert.Equal("two", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.ByteCount, SeekOrigin.Begin);
+ record = parser.Read();
+ Assert.Equal("3", parser[0]);
+ Assert.Equal("three, four", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void SimulateSeekingTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ // Already read:
+ // 1,2,3\r
+ // Seeked to this position.
+ writer.Write("\n4,5,6\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ // Make sure this doesn't throw an exception.
+ Assert.True(parser.Read());
+ Assert.Equal("4", parser[0]);
+ Assert.Equal("5", parser[1]);
+ Assert.Equal("6", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void NullCharTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("1,\0,3");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("\0", parser[1]);
+ Assert.Equal("3", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void RawRecordCorruptionTest()
+ {
+ var row1 = new string('a', 2038) + ",b\r\n";
+ var row2 = "test1,test2";
+ var val = row1 + row2;
+
+ using (var reader = new StringReader(val))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal(row1, parser.RawRecord.ToString());
+
+ parser.Read();
+ Assert.Equal(row2, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void ParseNoQuotesTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.Escape,
+ Escape = '\\',
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("one,\"two\",three \" four, \"five\" \n"); // `one,"two",three " four, "five" `
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("\"two\"", parser[1]);
+ Assert.Equal("three \" four", parser[2]);
+ Assert.Equal(" \"five\" ", parser[3]);
+ }
+ }
+
+ [Fact]
+ public void LastLineHasCommentTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("#comment");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void LastLineHasCommentNoEolTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("#c");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void DoNotIgnoreBlankLinesTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("1,2,3");
+ writer.WriteLine(",,");
+ writer.WriteLine("");
+ writer.WriteLine("4,5,6");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+ Assert.Equal("3", parser[2]);
+
+ parser.Read();
+ Assert.Equal("", parser[0]);
+ Assert.Equal("", parser[1]);
+ Assert.Equal("", parser[2]);
+
+ parser.Read();
+ Assert.Equal(1, parser.Count);
+
+ parser.Read();
+ Assert.Equal("4", parser[0]);
+ Assert.Equal("5", parser[1]);
+ Assert.Equal("6", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void QuotedFieldWithCarriageReturnTest()
+ {
+ using (var reader = new StringReader("\"a\r\",b"))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal(new[] { "a\r", "b" }, parser.Record);
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void QuotedFieldWithLineFeedTest()
+ {
+ using (var reader = new StringReader("\"a\n\",b"))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal(new[] { "a\n", "b" }, parser.Record);
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void RowCountWithSingleLineAndNoLineEndingTest()
+ {
+ using (var reader = new StringReader("a,b"))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.Row);
+ }
+ }
+
+ [Fact]
+ public void RawRowCountWithSingleLineAndNoLineEndingTest()
+ {
+ using (var reader = new StringReader("a,b"))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.RawRow);
+ }
+ }
+ }
+}