Skip to content

Commit

Permalink
Fix issue with nullability in ValidatingDataReader
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkPflug committed Jun 11, 2024
1 parent a7c66d9 commit 466678e
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 45 deletions.
6 changes: 3 additions & 3 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
</ItemGroup>

<ItemGroup Condition="'$(IsTestProject)' == 'true'">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.6.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="xunit" Version="2.8.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1" />
<PackageReference Include="Coverlet.MSBuild" Version="6.0.0"/>
<PackageReference Include="ReportGenerator" Version="5.2.0"/>
</ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions source/Sylvan.Data.Csv.Tests/CsvDataReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -479,9 +479,9 @@ public void Enumerator()
}

[Fact]
public void Create()
public async Task Create()
{
Assert.ThrowsAsync<ArgumentNullException>(() => CsvDataReader.CreateAsync((TextReader)null));
await Assert.ThrowsAsync<ArgumentNullException>(() => CsvDataReader.CreateAsync((TextReader)null));
}

[Fact]
Expand Down
76 changes: 73 additions & 3 deletions source/Sylvan.Data.Tests/SchemaValidatingDataReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ public class SchemaValidatingDataReaderTests
// uses preview features, which are marked obsolete.
#pragma warning disable CS0618

static object[] defaults = new object[] { -1, Guid.Empty, null };
static readonly object[] Defaults = new object[] { -1, Guid.Empty, null };

static bool Validate(DataValidationContext context)
{
foreach(var error in context.GetErrors())
{
context.SetValue(error, defaults[error]);
context.SetValue(error, Defaults[error]);
}
return true;
}
Expand Down Expand Up @@ -48,7 +48,7 @@ public void Test1()
[Fact]
public void Test2()
{
var schema = Schema.Parse(":int,:Guid,:DateTime");
var schema = Schema.Parse(":int,:Guid,:DateTime?");
var opts = new CsvDataReaderOptions { Schema = new CsvSchema(schema) };
var data = "A,B,C\na,,nope";
var csv = CsvDataReader.Create(new StringReader(data), opts);
Expand All @@ -62,6 +62,76 @@ public void Test2()
Assert.True(r.IsDBNull(2));
}

[Fact]
public void ValidationStringNullability()
{
var schema = Schema.Parse(":String?,:String");
var opts = new CsvDataReaderOptions { Schema = new CsvSchema(schema) };
var data = "A,B\na,b\n,b\na,";
var csv = CsvDataReader.Create(new StringReader(data), opts);

static bool Validate(DataValidationContext context)
{
return true;
}

var r = csv.ValidateSchema(Validate);
Assert.True(r.Read());
Assert.False(r.IsDBNull(0));
Assert.Equal("a", r.GetString(0));
Assert.False(r.IsDBNull(1));
Assert.Equal("b", r.GetString(1));
Assert.True(r.Read());
Assert.True(r.IsDBNull(0));
Assert.Throws<InvalidCastException>(() => r.GetString(0));
Assert.False(r.IsDBNull(1));
Assert.Equal("b", r.GetString(1));
Assert.True(r.Read());
Assert.False(r.IsDBNull(0));
Assert.Equal("a", r.GetString(0));
Assert.False(r.IsDBNull(1));
Assert.Equal("", r.GetString(1));
Assert.False(r.Read());
}

[Fact]
public void ValidationStructNullability()
{
var schema = Schema.Parse(":int?,:int");
var opts = new CsvDataReaderOptions { Schema = new CsvSchema(schema) };
var data = "A,B\n1,2\n,2\n1,";
var csv = CsvDataReader.Create(new StringReader(data), opts);

static bool Validate(DataValidationContext context)
{
return false;
}

var r = csv.ValidateSchema(Validate);

Assert.True(r.Read());
Assert.False(r.IsDBNull(0));
Assert.Equal(1, r.GetInt32(0));
Assert.False(r.IsDBNull(1));
Assert.Equal(2, r.GetInt32(1));


Assert.True(r.Read());
Assert.True(r.IsDBNull(0));
Assert.Throws<InvalidCastException>(() => r.GetInt32(0));
Assert.False(r.IsDBNull(1));
Assert.Equal(2, r.GetInt32(1));

// the last row is invalid, so will not be read
//Assert.True(r.Read());
//Assert.False(r.IsDBNull(0));
//Assert.Equal(1, r.GetInt32(0));
//Assert.False(r.IsDBNull(1)); // the schema says it can't be null...
//Assert.Throws<InvalidCastException>(() => r.GetInt32(0)); // but the underlying value can't be converted

Assert.False(r.Read());
}

class Validator
{
internal int count = 0;
Expand Down
Loading

0 comments on commit 466678e

Please sign in to comment.