From ceaa3833a4ec91f2695ea3e0a5d68220606c6461 Mon Sep 17 00:00:00 2001 From: Josh Close Date: Fri, 29 Jan 2021 14:44:20 -0600 Subject: [PATCH] Changed delegate ShouldQuote to include the field type. --- performance/CsvHelper.Performance/Program.cs | 2 +- .../Configuration/ConfigurationFunctions.cs | 2 +- src/CsvHelper/CsvWriter.cs | 9 ++-- src/CsvHelper/Delegates.cs | 2 +- .../ConfigurationConstructorTests.cs | 2 +- tests/CsvHelper.Tests/CsvWriterTests.cs | 8 ++-- .../CsvHelper.Tests/Writing/FieldTypeTests.cs | 42 +++++++++++++++++++ .../Writing/SanitizationTests.cs | 4 +- .../Writing/ShouldQuoteTests.cs | 8 ++-- 9 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 tests/CsvHelper.Tests/Writing/FieldTypeTests.cs diff --git a/performance/CsvHelper.Performance/Program.cs b/performance/CsvHelper.Performance/Program.cs index 2148d65f0..a64c928d1 100644 --- a/performance/CsvHelper.Performance/Program.cs +++ b/performance/CsvHelper.Performance/Program.cs @@ -79,7 +79,7 @@ static void WriteField(int columns = 50, int rows = 2_000_000, bool quoteAllFiel var config = new CsvConfiguration(CultureInfo.InvariantCulture) { //Delimiter = ";", - ShouldQuote = (field, context) => quoteAllFields, + ShouldQuote = (_, _, _) => quoteAllFields, }; using (var stream = File.Create(GetFilePath())) using (var writer = new StreamWriter(stream)) diff --git a/src/CsvHelper/Configuration/ConfigurationFunctions.cs b/src/CsvHelper/Configuration/ConfigurationFunctions.cs index 9d848f597..9c28b0264 100644 --- a/src/CsvHelper/Configuration/ConfigurationFunctions.cs +++ b/src/CsvHelper/Configuration/ConfigurationFunctions.cs @@ -92,7 +92,7 @@ public static bool ReadingExceptionOccurred(CsvHelperException exception) /// The current field. /// The current row. /// - public static bool ShouldQuote(string field, IWriterRow row) + public static bool ShouldQuote(string field, Type fieldType, IWriterRow row) { var config = row.Configuration; diff --git a/src/CsvHelper/CsvWriter.cs b/src/CsvHelper/CsvWriter.cs index 1862aa8f8..af8951b70 100644 --- a/src/CsvHelper/CsvWriter.cs +++ b/src/CsvHelper/CsvWriter.cs @@ -57,12 +57,12 @@ public class CsvWriter : IWriter private bool disposed; private bool hasHeaderBeenWritten; - private bool hasRecordBeenWritten; private int row = 1; private int index; private char[] buffer; private int bufferSize; private int bufferPosition; + private Type fieldType; /// public virtual string[] HeaderRecord { get; private set; } @@ -145,7 +145,9 @@ public virtual void WriteField(string field) field = field.Trim(); } - var shouldQuoteResult = shouldQuote(field, this); + fieldType ??= typeof(string); + + var shouldQuoteResult = shouldQuote(field, fieldType, this); WriteField(field, shouldQuoteResult); } @@ -182,6 +184,7 @@ public virtual void WriteField(string field, bool shouldQuote) CopyToBuffer(field); index++; + fieldType = null; } /// @@ -195,7 +198,7 @@ public virtual void WriteField(T field) /// public virtual void WriteField(T field, ITypeConverter converter) { - var type = field == null ? typeof(string) : field.GetType(); + var type = fieldType = field == null ? typeof(string) : field.GetType(); reusableMemberMapData.TypeConverter = converter; if (!typeConverterOptionsCache.TryGetValue(type, out TypeConverterOptions typeConverterOptions)) { diff --git a/src/CsvHelper/Delegates.cs b/src/CsvHelper/Delegates.cs index d14eb413e..b6bf9a757 100644 --- a/src/CsvHelper/Delegates.cs +++ b/src/CsvHelper/Delegates.cs @@ -81,7 +81,7 @@ namespace CsvHelper /// /// Function that is used to determine if a field should get quoted when writing. /// - public delegate bool ShouldQuote(string field, IWriterRow row); + public delegate bool ShouldQuote(string field, Type fieldType, IWriterRow row); /// /// Function that determines whether to skip the given record or not. diff --git a/tests/CsvHelper.Tests/Configuration/ConfigurationConstructorTests.cs b/tests/CsvHelper.Tests/Configuration/ConfigurationConstructorTests.cs index 364d05f79..f43b34efe 100644 --- a/tests/CsvHelper.Tests/Configuration/ConfigurationConstructorTests.cs +++ b/tests/CsvHelper.Tests/Configuration/ConfigurationConstructorTests.cs @@ -78,7 +78,7 @@ public void Constructor_AllArguments_SetsProperites() PrepareHeaderForMatch prepareHeaderForMatch = (header, fieldIndex) => header; ReadingExceptionOccurred readingExceptionOccurred = (ex) => true; ReferenceHeaderPrefix referenceHeaderPrefix = (type, memberName) => string.Empty; - ShouldQuote shouldQuote = (field, row) => true; + ShouldQuote shouldQuote = (_, _, _) => true; ShouldSkipRecord shouldSkipRecord = (record) => true; ShouldUseConstructorParameters shouldUseConstructorParameters = (parameterType) => true; diff --git a/tests/CsvHelper.Tests/CsvWriterTests.cs b/tests/CsvHelper.Tests/CsvWriterTests.cs index 17278155c..dcef0f8bb 100644 --- a/tests/CsvHelper.Tests/CsvWriterTests.cs +++ b/tests/CsvHelper.Tests/CsvWriterTests.cs @@ -315,7 +315,7 @@ public void WriteRecordsAllFieldsQuotedTest() var config = new CsvConfiguration(CultureInfo.InvariantCulture) { - ShouldQuote = (field, context) => true, + ShouldQuote = (_, _, _) => true, }; string csv; @@ -352,7 +352,7 @@ public void WriteRecordsNoFieldsQuotedTest() var config = new CsvConfiguration(CultureInfo.InvariantCulture) { - ShouldQuote = (field, context) => false, + ShouldQuote = (_, _, _) => false, }; string csv; using (var stream = new MemoryStream()) @@ -449,7 +449,7 @@ public void WriteRecordWithQuoteAllFieldsOnAndDelimiterInFieldTest() { var config = new CsvConfiguration(CultureInfo.InvariantCulture) { - ShouldQuote = (field, context) => true, + ShouldQuote = (_, _, _) => true, }; using (var stream = new MemoryStream()) using (var reader = new StreamReader(stream)) @@ -476,7 +476,7 @@ public void WriteRecordWithQuoteAllFieldsOnAndQuoteInFieldTest() { var config = new CsvConfiguration(CultureInfo.InvariantCulture) { - ShouldQuote = (field, context) => true, + ShouldQuote = (_, _, _) => true, }; using (var stream = new MemoryStream()) using (var reader = new StreamReader(stream)) diff --git a/tests/CsvHelper.Tests/Writing/FieldTypeTests.cs b/tests/CsvHelper.Tests/Writing/FieldTypeTests.cs new file mode 100644 index 000000000..e70dd151c --- /dev/null +++ b/tests/CsvHelper.Tests/Writing/FieldTypeTests.cs @@ -0,0 +1,42 @@ +using CsvHelper.Configuration; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CsvHelper.Tests.Writing +{ + [TestClass] + public class FieldTypeTests + { + [TestMethod] + public void Test1() + { + Type type = null; + var config = new CsvConfiguration(CultureInfo.InvariantCulture) + { + ShouldQuote = (field, fieldType, row) => + { + type = fieldType; + return ConfigurationFunctions.ShouldQuote(field, fieldType, row); + }, + }; + using (var writer = new StringWriter()) + using (var csv = new CsvWriter(writer, config)) + { + csv.WriteField(string.Empty); + Assert.AreEqual(typeof(string), type); + + csv.WriteField(1); + Assert.AreEqual(typeof(int), type); + + csv.WriteField(string.Empty); + Assert.AreEqual(typeof(string), type); + } + } + } +} diff --git a/tests/CsvHelper.Tests/Writing/SanitizationTests.cs b/tests/CsvHelper.Tests/Writing/SanitizationTests.cs index c6b66bd31..8578bc979 100644 --- a/tests/CsvHelper.Tests/Writing/SanitizationTests.cs +++ b/tests/CsvHelper.Tests/Writing/SanitizationTests.cs @@ -36,7 +36,7 @@ public void QuoteTest() var config = new CsvConfiguration(CultureInfo.InvariantCulture) { SanitizeForInjection = true, - ShouldQuote = (field, context) => false, + ShouldQuote = (_, _, _) => false, }; using (var writer = new StringWriter()) using (var csv = new CsvWriter(writer, config)) @@ -73,7 +73,7 @@ public void QuoteChangeEscapeCharacterTest() { SanitizeForInjection = true, InjectionEscapeCharacter = '\'', - ShouldQuote = (field, context) => false, + ShouldQuote = (_, _, _) => false, }; using (var writer = new StringWriter()) using (var csv = new CsvWriter(writer, config)) diff --git a/tests/CsvHelper.Tests/Writing/ShouldQuoteTests.cs b/tests/CsvHelper.Tests/Writing/ShouldQuoteTests.cs index 311d08092..e663eecc8 100644 --- a/tests/CsvHelper.Tests/Writing/ShouldQuoteTests.cs +++ b/tests/CsvHelper.Tests/Writing/ShouldQuoteTests.cs @@ -18,7 +18,7 @@ public void QuoteAllFieldsTest() { var config = new CsvConfiguration(CultureInfo.InvariantCulture) { - ShouldQuote = (field, context) => true, + ShouldQuote = (_, _, _) => true, }; using (var writer = new StringWriter()) using (var csv = new CsvWriter(writer, config)) @@ -35,7 +35,7 @@ public void QuoteNoFieldsTest() { var config = new CsvConfiguration(CultureInfo.InvariantCulture) { - ShouldQuote = (field, context) => false, + ShouldQuote = (_, _, _) => false, }; using (var writer = new StringWriter()) using (var csv = new CsvWriter(writer, config)) @@ -144,11 +144,11 @@ public void Test1() var data = new List<(int row, int column, string field)>(); var config = new CsvConfiguration(CultureInfo.InvariantCulture) { - ShouldQuote = (field, row) => + ShouldQuote = (field, fieldType, row) => { data.Add((row.Row, row.Index, field)); - return ConfigurationFunctions.ShouldQuote(field, row); + return ConfigurationFunctions.ShouldQuote(field, fieldType, row); }, }; using (var writer = new StringWriter())