Skip to content

Commit

Permalink
Fixed read error in inconsistent csv header (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
shibayan authored Mar 4, 2022
1 parent f90a46b commit 7c19212
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
Expand Down
77 changes: 62 additions & 15 deletions CsvHelper.FastDynamic.Tests/CsvReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace CsvHelper.FastDynamic.Tests
public class CsvReaderTests
{
[Fact]
public void ReadDynamicRecords_Member()
public void ReadDynamicRecords()
{
var csvReader = CreateInMemoryReader();

Expand All @@ -20,7 +20,7 @@ public void ReadDynamicRecords_Member()
Assert.NotNull(records);
Assert.Equal(3, records.Count);

for (int i = 0; i < 3; i++)
for (var i = 0; i < 3; i++)
{
Assert.Equal(TestData.CsvRecords[i]["Id"], records[i].Id);
Assert.Equal(TestData.CsvRecords[i]["Name"], records[i].Name);
Expand All @@ -29,7 +29,7 @@ public void ReadDynamicRecords_Member()
}

[Fact]
public void ReadDynamicRecords_Indexer()
public void ReadDynamicRecords_UseIndexer()
{
var csvReader = CreateInMemoryReader();

Expand All @@ -38,7 +38,7 @@ public void ReadDynamicRecords_Indexer()
Assert.NotNull(records);
Assert.Equal(3, records.Count);

for (int i = 0; i < 3; i++)
for (var i = 0; i < 3; i++)
{
Assert.Equal(TestData.CsvRecords[i]["Id"], records[i]["Id"]);
Assert.Equal(TestData.CsvRecords[i]["Name"], records[i]["Name"]);
Expand All @@ -47,7 +47,7 @@ public void ReadDynamicRecords_Indexer()
}

[Fact]
public void ReadDynamicRecords_Dictionary()
public void ReadDynamicRecords_AsDictionary()
{
var csvReader = CreateInMemoryReader();

Expand All @@ -58,14 +58,35 @@ public void ReadDynamicRecords_Dictionary()
Assert.NotNull(records);
Assert.Equal(3, records.Length);

for (int i = 0; i < 3; i++)
for (var i = 0; i < 3; i++)
{
Assert.Equal(TestData.CsvRecords[i]["Id"], records[i]["Id"]);
Assert.Equal(TestData.CsvRecords[i]["Name"], records[i]["Name"]);
Assert.Equal(TestData.CsvRecords[i]["Location"], records[i]["Location"]);
}
}

[Fact]
public void ReadDynamicRecords_WithMissingHeader()
{
var csvReader = CreateInMemoryReader_WithMissingHeader();

var records = csvReader.GetDynamicRecords()
.Cast<IDictionary<string, object>>()
.ToArray();

Assert.NotNull(records);
Assert.Equal(3, records.Length);

for (var i = 0; i < 3; i++)
{
Assert.Equal(2, records[i].Count);

Assert.Equal(TestData.CsvRecords[i]["Id"], records[i]["Id"]);
Assert.Equal(TestData.CsvRecords[i]["Name"], records[i]["Name"]);
}
}

[Fact]
public async Task ReadDynamicRecordsAsync()
{
Expand All @@ -76,22 +97,43 @@ public async Task ReadDynamicRecordsAsync()
Assert.NotNull(records);
Assert.Equal(3, records.Count);

for (int i = 0; i < 3; i++)
for (var i = 0; i < 3; i++)
{
Assert.Equal(TestData.CsvRecords[i]["Id"], records[i].Id);
Assert.Equal(TestData.CsvRecords[i]["Name"], records[i].Name);
Assert.Equal(TestData.CsvRecords[i]["Location"], records[i].Location);
}
}

[Fact]
public async Task ReadDynamicRecordsAsync_WithMissingHeader()
{
var csvReader = CreateInMemoryReader_WithMissingHeader();

var records = (await csvReader.GetDynamicRecordsAsync())
.Cast<IDictionary<string, object>>()
.ToArray();

Assert.NotNull(records);
Assert.Equal(3, records.Length);

for (var i = 0; i < 3; i++)
{
Assert.Equal(2, records[i].Count);

Assert.Equal(TestData.CsvRecords[i]["Id"], records[i]["Id"]);
Assert.Equal(TestData.CsvRecords[i]["Name"], records[i]["Name"]);
}
}

[Fact]
public void EnumerateDynamicRecords()
{
var csvReader = CreateInMemoryReader();

var records = csvReader.EnumerateDynamicRecords();

int count = 0;
var count = 0;

foreach (var record in records)
{
Expand All @@ -115,7 +157,7 @@ public async Task EnumerateDynamicRecordsAsync()

var records = csvReader.EnumerateDynamicRecordsAsync();

int count = 0;
var count = 0;

await foreach (var record in records)
{
Expand All @@ -139,12 +181,12 @@ public void AddDynamicColumns_Member()

var records = csvReader.GetDynamicRecords();

for (int i = 0; i < 3; i++)
for (var i = 0; i < 3; i++)
{
records[i].Append = $"test-{i}";
}

for (int i = 0; i < 3; i++)
for (var i = 0; i < 3; i++)
{
Assert.Equal(TestData.CsvRecords[i]["Id"], records[i].Id);
Assert.Equal(TestData.CsvRecords[i]["Name"], records[i].Name);
Expand All @@ -161,12 +203,12 @@ public void AddDynamicColumns_Indexer()

var records = csvReader.GetDynamicRecords();

for (int i = 0; i < 3; i++)
for (var i = 0; i < 3; i++)
{
records[i]["Append"] = $"test-{i}";
}

for (int i = 0; i < 3; i++)
for (var i = 0; i < 3; i++)
{
Assert.Equal(TestData.CsvRecords[i]["Id"], records[i]["Id"]);
Assert.Equal(TestData.CsvRecords[i]["Name"], records[i]["Name"]);
Expand All @@ -185,12 +227,12 @@ public void AddDynamicColumns_Dictionary()
.Cast<IDictionary<string, object>>()
.ToArray();

for (int i = 0; i < 3; i++)
for (var i = 0; i < 3; i++)
{
records[i]["Append"] = $"test-{i}";
}

for (int i = 0; i < 3; i++)
for (var i = 0; i < 3; i++)
{
Assert.Equal(TestData.CsvRecords[i]["Id"], records[i]["Id"]);
Assert.Equal(TestData.CsvRecords[i]["Name"], records[i]["Name"]);
Expand All @@ -204,5 +246,10 @@ private CsvReader CreateInMemoryReader()
{
return new CsvReader(new StringReader(TestData.CsvContent), CultureInfo.InvariantCulture);
}

private CsvReader CreateInMemoryReader_WithMissingHeader()
{
return new CsvReader(new StringReader(TestData.CsvContentWithMissingHeader), CultureInfo.InvariantCulture);
}
}
}
2 changes: 2 additions & 0 deletions CsvHelper.FastDynamic.Tests/TestData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ public static class TestData
{
public static readonly string CsvContent = $"Id,Name,Location\r\n1,kazuakix,Wakayama\r\n2,daruyanagi,Ehime\r\n3,buchizo,Osaka\r\n";

public static readonly string CsvContentWithMissingHeader = $"Id,Name\r\n1,kazuakix\r\n2,daruyanagi,Ehime\r\n3,buchizo\r\n";

public static readonly IReadOnlyList<IDictionary<string, string>> CsvRecords = new[]
{
new Dictionary<string, string> { { "Id", "1" }, { "Name", "kazuakix" }, { "Location", "Wakayama" } },
Expand Down
10 changes: 3 additions & 7 deletions CsvHelper.FastDynamic/CsvReaderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ namespace CsvHelper.FastDynamic
{
public static class CsvReaderExtensions
{
public static IReadOnlyList<dynamic> GetDynamicRecords(this CsvReader csvReader)
=> csvReader.EnumerateDynamicRecords().ToArray();
public static IReadOnlyList<dynamic> GetDynamicRecords(this CsvReader csvReader) => csvReader.EnumerateDynamicRecords().ToArray();

public static IEnumerable<dynamic> EnumerateDynamicRecords(this CsvReader csvReader)
{
Expand All @@ -34,10 +33,7 @@ public static IEnumerable<dynamic> EnumerateDynamicRecords(this CsvReader csvRea
{
var values = new object[csvReader.HeaderRecord.Length];

for (var i = 0; i < csvReader.HeaderRecord.Length; i++)
{
values[i] = csvReader.Parser[i];
}
Array.Copy(csvReader.Parser.Record, values, csvReader.HeaderRecord.Length);

record = new CsvRecord(csvHeader, values);
}
Expand Down Expand Up @@ -95,7 +91,7 @@ public static async IAsyncEnumerable<dynamic> EnumerateDynamicRecordsAsync(this
{
var values = new object[csvReader.HeaderRecord.Length];

Array.Copy(csvReader.Parser.Record, values, csvReader.Parser.Record.Length);
Array.Copy(csvReader.Parser.Record, values, csvReader.HeaderRecord.Length);

record = new CsvRecord(csvHeader, values);
}
Expand Down

0 comments on commit 7c19212

Please sign in to comment.