Skip to content

Commit 0f10ef1

Browse files
committed
Add GetBytes and GetChars parameter validation tests.
1 parent a7959e3 commit 0f10ef1

File tree

2 files changed

+188
-0
lines changed

2 files changed

+188
-0
lines changed

src/AdoNet.Specification.Tests/DataReaderTestBase.cs

+144
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,150 @@ public virtual void Read_works()
642642
[Fact]
643643
public virtual void NextResult_throws_when_closed() => X_throws_when_closed(r => r.NextResult());
644644

645+
[Fact]
646+
public virtual void GetBytes_throws_when_dataOffset_is_negative() => TestGetBytes(reader =>
647+
{
648+
AssertThrowsAny<ArgumentOutOfRangeException, IndexOutOfRangeException, InvalidOperationException>(() => reader.GetBytes(0, -1, new byte[4], 0, 4));
649+
});
650+
651+
[Fact]
652+
public virtual void GetBytes_reads_nothing_when_dataOffset_is_too_large() => TestGetBytes(reader =>
653+
{
654+
Assert.Equal(0, reader.GetBytes(0, 6, new byte[4], 0, 4));
655+
});
656+
657+
[Fact]
658+
public virtual void GetBytes_returns_length_when_buffer_is_null() => TestGetBytes(reader =>
659+
{
660+
Assert.Equal(4, reader.GetBytes(0, 0, null, 0, 0));
661+
});
662+
663+
[Fact]
664+
public virtual void GetBytes_throws_when_bufferOffset_is_negative() => TestGetBytes(reader =>
665+
{
666+
AssertThrowsAny<ArgumentOutOfRangeException, IndexOutOfRangeException>(() => reader.GetBytes(0, 0, new byte[4], -1, 4));
667+
});
668+
669+
[Fact]
670+
public virtual void GetBytes_throws_when_bufferOffset_is_too_large() => TestGetBytes(reader =>
671+
{
672+
AssertThrowsAny<ArgumentOutOfRangeException, IndexOutOfRangeException>(() => reader.GetBytes(0, 0, new byte[4], 5, 0));
673+
});
674+
675+
[Fact]
676+
public virtual void GetBytes_reads_nothing_at_end_of_buffer() => TestGetBytes(reader =>
677+
{
678+
Assert.Equal(0, reader.GetBytes(0, 0, new byte[4], 4, 0));
679+
});
680+
681+
[Fact]
682+
public virtual void GetBytes_throws_when_bufferOffset_plus_length_is_too_long() => TestGetBytes(reader =>
683+
{
684+
AssertThrowsAny<ArgumentException, IndexOutOfRangeException>(() => reader.GetBytes(0, 0, new byte[4], 2, 3));
685+
});
686+
687+
[Fact]
688+
public virtual void GetBytes_works_when_buffer_is_large() => TestGetBytes(reader =>
689+
{
690+
var buffer = new byte[6];
691+
Assert.Equal(4, reader.GetBytes(0, 0, buffer, 0, 6));
692+
Assert.Equal(new byte[] { 1, 2, 3, 4, 0, 0 }, buffer);
693+
});
694+
695+
[Fact]
696+
public virtual void GetBytes_reads_part_of_blob() => TestGetBytes(reader =>
697+
{
698+
var buffer = new byte[5];
699+
Assert.Equal(2, reader.GetBytes(0, 1, buffer, 2, 2));
700+
Assert.Equal(new byte[] { 0, 0, 2, 3, 0 }, buffer);
701+
});
702+
703+
private void TestGetBytes(Action<DbDataReader> action)
704+
{
705+
using (var connection = CreateOpenConnection())
706+
using (var command = connection.CreateCommand())
707+
{
708+
command.CommandText = $"SELECT {Fixture.CreateHexLiteral(new byte[] { 1, 2, 3, 4 })};";
709+
using (var reader = command.ExecuteReader())
710+
{
711+
reader.Read();
712+
action(reader);
713+
}
714+
}
715+
}
716+
717+
[Fact]
718+
public virtual void GetChars_throws_when_dataOffset_is_negative() => TestGetChars(reader =>
719+
{
720+
AssertThrowsAny<ArgumentOutOfRangeException, IndexOutOfRangeException, InvalidOperationException>(() => reader.GetChars(0, -1, new char[4], 0, 4));
721+
});
722+
723+
[Fact]
724+
public virtual void GetChars_reads_nothing_when_dataOffset_is_too_large() => TestGetChars(reader =>
725+
{
726+
Assert.Equal(0, reader.GetChars(0, 6, new char[4], 0, 4));
727+
});
728+
729+
[Fact]
730+
public virtual void GetChars_returns_length_when_buffer_is_null() => TestGetChars(reader =>
731+
{
732+
Assert.Equal(4, reader.GetChars(0, 0, null, 0, 0));
733+
});
734+
735+
[Fact]
736+
public virtual void GetChars_throws_when_bufferOffset_is_negative() => TestGetChars(reader =>
737+
{
738+
AssertThrowsAny<ArgumentOutOfRangeException, IndexOutOfRangeException>(() => reader.GetChars(0, 0, new char[4], -1, 4));
739+
});
740+
741+
[Fact]
742+
public virtual void GetChars_throws_when_bufferOffset_is_too_large() => TestGetChars(reader =>
743+
{
744+
AssertThrowsAny<ArgumentOutOfRangeException, IndexOutOfRangeException>(() => reader.GetChars(0, 0, new char[4], 5, 0));
745+
});
746+
747+
[Fact]
748+
public virtual void GetChars_reads_nothing_at_end_of_buffer() => TestGetChars(reader =>
749+
{
750+
Assert.Equal(0, reader.GetChars(0, 0, new char[4], 4, 0));
751+
});
752+
753+
[Fact]
754+
public virtual void GetChars_throws_when_bufferOffset_plus_length_is_too_long() => TestGetChars(reader =>
755+
{
756+
AssertThrowsAny<ArgumentException, IndexOutOfRangeException>(() => reader.GetChars(0, 0, new char[4], 2, 3));
757+
});
758+
759+
[Fact]
760+
public virtual void GetChars_works_when_buffer_is_large() => TestGetChars(reader =>
761+
{
762+
var buffer = new char[6];
763+
Assert.Equal(4, reader.GetChars(0, 0, buffer, 0, 6));
764+
Assert.Equal(new[] { 'a', 'b', 'c', 'd', '\0', '\0' }, buffer);
765+
});
766+
767+
[Fact]
768+
public virtual void GetChars_reads_part_of_string() => TestGetChars(reader =>
769+
{
770+
var buffer = new char[5];
771+
Assert.Equal(2, reader.GetChars(0, 1, buffer, 2, 2));
772+
Assert.Equal(new[] { '\0', '\0', 'b', 'c', '\0' }, buffer);
773+
});
774+
775+
private void TestGetChars(Action<DbDataReader> action)
776+
{
777+
using (var connection = CreateOpenConnection())
778+
using (var command = connection.CreateCommand())
779+
{
780+
command.CommandText = "SELECT 'abcd';";
781+
using (var reader = command.ExecuteReader())
782+
{
783+
reader.Read();
784+
action(reader);
785+
}
786+
}
787+
}
788+
645789
private void GetX_works<T>(string sql, Func<DbDataReader, T> action, T expected)
646790
{
647791
using (var connection = CreateOpenConnection())

src/AdoNet.Specification.Tests/DbFactoryTestBase.cs

+44
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Threading;
44
using System.Threading.Tasks;
55
using Xunit;
6+
using Xunit.Sdk;
67

78
namespace AdoNet.Specification.Tests
89
{
@@ -48,6 +49,49 @@ protected virtual DbConnection CreateOpenConnection()
4849
return connection;
4950
}
5051

52+
protected static Exception AssertThrowsAny<TException1, TException2>(Action action)
53+
where TException1 : Exception
54+
where TException2 : Exception
55+
{
56+
try
57+
{
58+
action();
59+
throw new ThrowsException(typeof(TException1));
60+
}
61+
catch (TException1 ex)
62+
{
63+
return ex;
64+
}
65+
catch (TException2 ex)
66+
{
67+
return ex;
68+
}
69+
}
70+
71+
protected static Exception AssertThrowsAny<TException1, TException2, TException3>(Action action)
72+
where TException1 : Exception
73+
where TException2 : Exception
74+
where TException3 : Exception
75+
{
76+
try
77+
{
78+
action();
79+
throw new ThrowsException(typeof(TException1));
80+
}
81+
catch (TException1 ex)
82+
{
83+
return ex;
84+
}
85+
catch (TException2 ex)
86+
{
87+
return ex;
88+
}
89+
catch (TException3 ex)
90+
{
91+
return ex;
92+
}
93+
}
94+
5195
readonly CancellationTokenSource m_cancellationTokenSource;
5296
}
5397
}

0 commit comments

Comments
 (0)