From 2e6cd8a48189ea64e4efdcdb122700e076fd042c Mon Sep 17 00:00:00 2001 From: philipmat Date: Mon, 21 Sep 2020 18:04:53 -0500 Subject: [PATCH] csv files are written without BOM - fixes #118 --- alternatives/dotnet/discogs/CsvExporter.cs | 5 +- .../tests/CsvExporterItegrationTests.cs | 60 +++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 alternatives/dotnet/tests/CsvExporterItegrationTests.cs diff --git a/alternatives/dotnet/discogs/CsvExporter.cs b/alternatives/dotnet/discogs/CsvExporter.cs index 06f0204..705799e 100644 --- a/alternatives/dotnet/discogs/CsvExporter.cs +++ b/alternatives/dotnet/discogs/CsvExporter.cs @@ -3,6 +3,7 @@ using System.IO; using System.IO.Compression; using System.Linq; +using System.Text; using System.Threading.Tasks; namespace discogs @@ -64,11 +65,11 @@ public async Task ExportAsync(T value) { var fs = File.Create(csvFile, bufferSize: BufferSize); var gzStream = new GZipStream(fs, CompressionMode.Compress, leaveOpen: false); - stream = new StreamWriter(gzStream, encoding: System.Text.Encoding.UTF8); + stream = new StreamWriter(gzStream, encoding: new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); } else { - stream = new StreamWriter(csvFile, append: false, encoding: System.Text.Encoding.UTF8, bufferSize: BufferSize); + stream = new StreamWriter(csvFile, append: false, encoding: new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), bufferSize: BufferSize); } stream.WriteLine(CsvExtensions.ToCsv(kvp.Value)); return (csvFile, stream); diff --git a/alternatives/dotnet/tests/CsvExporterItegrationTests.cs b/alternatives/dotnet/tests/CsvExporterItegrationTests.cs new file mode 100644 index 0000000..7f72d9c --- /dev/null +++ b/alternatives/dotnet/tests/CsvExporterItegrationTests.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using discogs; +using FluentAssertions; +using Xunit; + +namespace tests +{ + public class CsvExporterIntegrationTests : IDisposable + { + public static readonly string TestPath = Path.Combine(Path.GetTempPath(), "CvsExporter"); + + public CsvExporterIntegrationTests() + { + // deletes folder as a shorcut to cleaning out and starting the test with blank slate + if (Directory.Exists(TestPath)) Directory.Delete(TestPath, recursive: true); + Directory.CreateDirectory(TestPath); + } + + public void Dispose() + { + Directory.Delete(TestPath, recursive: true); + } + + [Fact] + public async Task Export_DoesNotCreateBomAsync() + { + //Given + var exporter = new CsvExporter(TestPath, compress: false); + var record = new SimpleRecord(); + + //When + await exporter.ExportAsync(record); + await exporter.CompleteExportAsync(1); + + //Then + var outputFile = Path.Combine(TestPath, "test_1.csv"); + File.Exists(outputFile).Should().BeTrue(); + byte[] content = await File.ReadAllBytesAsync(outputFile); + + content[0].Should().Be((byte)'f', because: "foo is the first word in the file"); + content[1].Should().Be((byte)'o', because: "foo is the first word in the file"); + } + + private class SimpleRecord : IExportToCsv + { + public IEnumerable<(string StreamName, string[] RowValues)> ExportToCsv() + { + yield return ("test_1", new string[] { "1.0", "1.1" }); + } + + public IReadOnlyDictionary GetCsvExportScheme() + => new Dictionary { + ["test_1"] = new string[] { "foo", "bar" } + }; + } + } +} \ No newline at end of file