From 95e811e18b8206788d106df6b0e3c8648f5f4035 Mon Sep 17 00:00:00 2001
From: Edward Neal <55035479+edwardneal@users.noreply.github.com>
Date: Mon, 16 Jun 2025 07:47:06 +0100
Subject: [PATCH 01/10] Expand code coverage for UDT serialization
---
.../Microsoft.Data.SqlClient.UnitTests.csproj | 1 +
.../InvalidSerializationTest.cs | 41 +++
.../NativeSerializationTest.cs | 268 ++++++++++++++++++
.../UdtSerialization/SerializedTypes.cs | 207 ++++++++++++++
.../UserDefinedSerializationTest.cs | 97 +++++++
5 files changed, 614 insertions(+)
create mode 100644 src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
create mode 100644 src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
create mode 100644 src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs
create mode 100644 src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj
index 2f0e12c922..2a8c60f4ce 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj
@@ -25,6 +25,7 @@
all
+
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
new file mode 100644
index 0000000000..cba44991b2
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
@@ -0,0 +1,41 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.IO;
+using Microsoft.Data.SqlClient.Server;
+using Microsoft.Data.SqlClient.UnitTests.UdtSerialization.SerializedTypes;
+using Microsoft.SqlServer.Server;
+using Xunit;
+
+namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization;
+
+public class InvalidSerializationTest
+{
+ [Fact]
+ public void RequiresSqlUserDefinedTypeAttribute()
+ {
+ using MemoryStream stream = new MemoryStream();
+
+ InvalidUdtException exception = Assert.Throws(
+ () => SerializationHelperSql9.Serialize(stream, new ClassMissingSqlUserDefinedTypeAttribute()));
+
+ Assert.Equal($"'{typeof(ClassMissingSqlUserDefinedTypeAttribute).FullName}' is an invalid user defined type, reason: no UDT attribute.", exception.Message);
+ }
+
+ [Fact]
+ public void CannotSerializeUnknownFormattedType()
+ {
+ using MemoryStream stream = new MemoryStream();
+
+ ArgumentOutOfRangeException exception = Assert.Throws("Format",
+ () => SerializationHelperSql9.Serialize(stream, new UnknownFormattedClass()));
+
+#if NET
+ Assert.Equal("The Format enumeration value, 0, is not supported by the format method. (Parameter 'Format')", exception.Message);
+#else
+ Assert.Equal("The Format enumeration value, Unknown, is not supported by the format method.\r\nParameter name: Format", exception.Message);
+#endif
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
new file mode 100644
index 0000000000..6b399700dd
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
@@ -0,0 +1,268 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Data.SqlClient.Server;
+using Microsoft.Data.SqlClient.UnitTests.UdtSerialization.SerializedTypes;
+using System;
+using System.Collections.Generic;
+using System.Data.SqlTypes;
+using System.IO;
+using Xunit;
+
+namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization;
+
+///
+/// Tests the serialization method defined by MS-SSCLRT. Ensures that combinations of primitives and custom types round-trip.
+///
+///
+public class NativeSerializationTest
+{
+ public static IEnumerable
From 4db8883ae144e38a65bc970f00e85a1b143adafb Mon Sep 17 00:00:00 2001
From: Edward Neal <55035479+edwardneal@users.noreply.github.com>
Date: Fri, 20 Jun 2025 19:34:59 +0100
Subject: [PATCH 04/10] Reformat SerializedTypes.cs
---
.../UdtSerialization/SerializedTypes.cs | 216 ++++++++++++++----
1 file changed, 172 insertions(+), 44 deletions(-)
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs
index df59f7556b..d6538f3584 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs
@@ -11,60 +11,188 @@
namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization.SerializedTypes;
// Simple cases: a struct containing one of the designated primitive types
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct BoolWrapperStruct { public bool Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct ByteWrapperStruct { public byte Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct SByteWrapperStruct { public sbyte Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct UShortWrapperStruct { public ushort Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct ShortWrapperStruct { public short Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct UIntWrapperStruct { public uint Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct IntWrapperStruct { public int Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct ULongWrapperStruct { public ulong Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct LongWrapperStruct { public long Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct FloatWrapperStruct { public float Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct DoubleWrapperStruct { public double Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct SqlByteWrapperStruct { public SqlByte Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct SqlInt16WrapperStruct { public SqlInt16 Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct SqlInt32WrapperStruct { public SqlInt32 Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct SqlInt64WrapperStruct { public SqlInt64 Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct SqlBooleanWrapperStruct { public SqlBoolean Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct SqlSingleWrapperStruct { public SqlSingle Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct SqlDoubleWrapperStruct { public SqlDouble Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct SqlDateTimeWrapperStruct { public SqlDateTime Field1; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct SqlMoneyWrapperStruct { public SqlMoney Field1; }
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct BoolWrapperStruct { public bool Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct ByteWrapperStruct { public byte Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct SByteWrapperStruct { public sbyte Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct UShortWrapperStruct { public ushort Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct ShortWrapperStruct { public short Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct UIntWrapperStruct { public uint Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct IntWrapperStruct { public int Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct ULongWrapperStruct { public ulong Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct LongWrapperStruct { public long Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct FloatWrapperStruct { public float Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct DoubleWrapperStruct { public double Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct SqlByteWrapperStruct { public SqlByte Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct SqlInt16WrapperStruct { public SqlInt16 Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct SqlInt32WrapperStruct { public SqlInt32 Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct SqlInt64WrapperStruct { public SqlInt64 Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct SqlBooleanWrapperStruct { public SqlBoolean Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct SqlSingleWrapperStruct { public SqlSingle Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct SqlDoubleWrapperStruct { public SqlDouble Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct SqlDateTimeWrapperStruct { public SqlDateTime Field1; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct SqlMoneyWrapperStruct { public SqlMoney Field1; }
+
// Success case: a class containing one of the designated primitive types
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public class BoolWrapperClass { public bool Field1; }
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public class BoolWrapperClass { public bool Field1; }
// Success case: a struct containing one designated primitive type and one nested struct
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedBoolWrapperStruct { public bool Field1; public BoolWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedByteWrapperStruct { public byte Field1; public ByteWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedSByteWrapperStruct { public sbyte Field1; public SByteWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedUShortWrapperStruct { public ushort Field1; public UShortWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedShortWrapperStruct { public short Field1; public ShortWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedUIntWrapperStruct { public uint Field1; public UIntWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedIntWrapperStruct { public int Field1; public IntWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedULongWrapperStruct { public ulong Field1; public ULongWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedLongWrapperStruct { public long Field1; public LongWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedFloatWrapperStruct { public float Field1; public FloatWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedDoubleWrapperStruct { public double Field1; public DoubleWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedSqlByteWrapperStruct { public SqlByte Field1; public SqlByteWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedSqlInt16WrapperStruct { public SqlInt16 Field1; public SqlInt16WrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedSqlInt32WrapperStruct { public SqlInt32 Field1; public SqlInt32WrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedSqlInt64WrapperStruct { public SqlInt64 Field1; public SqlInt64WrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedSqlBooleanWrapperStruct { public SqlBoolean Field1; public SqlBooleanWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedSqlSingleWrapperStruct { public SqlSingle Field1; public SqlSingleWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedSqlDoubleWrapperStruct { public SqlDouble Field1; public SqlDoubleWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedSqlDateTimeWrapperStruct { public SqlDateTime Field1; public SqlDateTimeWrapperStruct Field2; }
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct NestedSqlMoneyWrapperStruct { public SqlMoney Field1; public SqlMoneyWrapperStruct Field2; }
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedBoolWrapperStruct { public bool Field1; public BoolWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedByteWrapperStruct { public byte Field1; public ByteWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedSByteWrapperStruct { public sbyte Field1; public SByteWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedUShortWrapperStruct { public ushort Field1; public UShortWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedShortWrapperStruct { public short Field1; public ShortWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedUIntWrapperStruct { public uint Field1; public UIntWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedIntWrapperStruct { public int Field1; public IntWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedULongWrapperStruct { public ulong Field1; public ULongWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedLongWrapperStruct { public long Field1; public LongWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedFloatWrapperStruct { public float Field1; public FloatWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedDoubleWrapperStruct { public double Field1; public DoubleWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedSqlByteWrapperStruct { public SqlByte Field1; public SqlByteWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedSqlInt16WrapperStruct { public SqlInt16 Field1; public SqlInt16WrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedSqlInt32WrapperStruct { public SqlInt32 Field1; public SqlInt32WrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedSqlInt64WrapperStruct { public SqlInt64 Field1; public SqlInt64WrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedSqlBooleanWrapperStruct { public SqlBoolean Field1; public SqlBooleanWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedSqlSingleWrapperStruct { public SqlSingle Field1; public SqlSingleWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedSqlDoubleWrapperStruct { public SqlDouble Field1; public SqlDoubleWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedSqlDateTimeWrapperStruct { public SqlDateTime Field1; public SqlDateTimeWrapperStruct Field2; }
+
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct NestedSqlMoneyWrapperStruct { public SqlMoney Field1; public SqlMoneyWrapperStruct Field2; }
+
// Success case: a class containing one designated primitive type and a nested struct
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public class NestedBoolWrapperClass { public bool Field1; public BoolWrapperStruct Field2; }
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public class NestedBoolWrapperClass { public bool Field1; public BoolWrapperStruct Field2; }
// Failure case: a struct or a class containing one designated primitive type and a nested class
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public class InvalidNestedBoolWrapperClass { public bool Field1; public BoolWrapperClass Field2; }
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public class InvalidNestedBoolWrapperClass { public bool Field1; public BoolWrapperClass Field2; }
// Failure case: a struct or a class containing a field which is not a designated primitive type
-[SqlUserDefinedType(Format.Native)] [StructLayout(LayoutKind.Sequential)] public struct InvalidIntPtrAndByteWrapperStruct { public byte Field1; public IntPtr Field2; }
+[SqlUserDefinedType(Format.Native)]
+[StructLayout(LayoutKind.Sequential)]
+public struct InvalidIntPtrAndByteWrapperStruct { public byte Field1; public IntPtr Field2; }
// Success case: a struct or a class implementing IBinarySerialize which would not otherwise be serializable
public interface IFormattingProgress
From bd495149b1d81a949af2323e96d7f43e7b32c05d Mon Sep 17 00:00:00 2001
From: Edward Neal <55035479+edwardneal@users.noreply.github.com>
Date: Fri, 20 Jun 2025 23:09:56 +0100
Subject: [PATCH 05/10] Switch to implicit object creation
Also enforce this via editorconfig
---
.../tests/UnitTests/.editorconfig | 11 +++++++++++
.../InvalidSerializationTest.cs | 8 ++++----
.../NativeSerializationTest.cs | 18 +++++++++---------
.../UserDefinedSerializationTest.cs | 6 +++---
4 files changed, 27 insertions(+), 16 deletions(-)
create mode 100644 src/Microsoft.Data.SqlClient/tests/UnitTests/.editorconfig
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/.editorconfig b/src/Microsoft.Data.SqlClient/tests/UnitTests/.editorconfig
new file mode 100644
index 0000000000..c75dd30b68
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/.editorconfig
@@ -0,0 +1,11 @@
+# editorconfig.org
+
+# top-most EditorConfig file
+root = false
+
+[*.cs]
+
+csharp_style_var_when_type_is_apparent = false:refactor
+# IDE0090: Use 'new(...)'
+csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
+
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
index cba44991b2..6036253304 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
@@ -16,9 +16,9 @@ public class InvalidSerializationTest
[Fact]
public void RequiresSqlUserDefinedTypeAttribute()
{
- using MemoryStream stream = new MemoryStream();
+ using MemoryStream stream = new();
- InvalidUdtException exception = Assert.Throws(
+ var exception = Assert.Throws(
() => SerializationHelperSql9.Serialize(stream, new ClassMissingSqlUserDefinedTypeAttribute()));
Assert.Equal($"'{typeof(ClassMissingSqlUserDefinedTypeAttribute).FullName}' is an invalid user defined type, reason: no UDT attribute.", exception.Message);
@@ -27,9 +27,9 @@ public void RequiresSqlUserDefinedTypeAttribute()
[Fact]
public void CannotSerializeUnknownFormattedType()
{
- using MemoryStream stream = new MemoryStream();
+ using MemoryStream stream = new();
- ArgumentOutOfRangeException exception = Assert.Throws("Format",
+ var exception = Assert.Throws("Format",
() => SerializationHelperSql9.Serialize(stream, new UnknownFormattedClass()));
#if NET
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
index 6b399700dd..ae5523579a 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
@@ -188,12 +188,12 @@ public void SerializeNullPrimitiveType(object primitive, byte[] expectedValue)
[Fact]
public void CanSerializeTopLevelClass()
{
- NestedBoolWrapperClass validWrapper = new NestedBoolWrapperClass()
+ NestedBoolWrapperClass validWrapper = new()
{
Field1 = true,
Field2 = new BoolWrapperStruct() { Field1 = true }
};
- using MemoryStream stream = new MemoryStream();
+ using MemoryStream stream = new();
SerializationHelperSql9.Serialize(stream, validWrapper);
}
@@ -207,14 +207,14 @@ public void CanSerializeTopLevelClass()
[Fact]
public void CannotSerializeNestedClass()
{
- InvalidNestedBoolWrapperClass invalidWrapper = new InvalidNestedBoolWrapperClass()
+ InvalidNestedBoolWrapperClass invalidWrapper = new()
{
Field1 = true,
Field2 = new BoolWrapperClass() { Field1 = true }
};
- using MemoryStream stream = new MemoryStream();
+ using MemoryStream stream = new();
- Exception ex = Assert.Throws(() => SerializationHelperSql9.Serialize(stream, invalidWrapper));
+ var ex = Assert.Throws(() => SerializationHelperSql9.Serialize(stream, invalidWrapper));
string expectedException = StringsHelper.GetString(Strings.SQL_CannotCreateNormalizer, invalidWrapper.Field2.GetType().FullName);
Assert.Equal(expectedException, ex.Message);
@@ -227,14 +227,14 @@ public void CannotSerializeNestedClass()
[Fact]
public void CannotSerializeNonPrimitiveType()
{
- InvalidIntPtrAndByteWrapperStruct invalidWrapper = new InvalidIntPtrAndByteWrapperStruct()
+ InvalidIntPtrAndByteWrapperStruct invalidWrapper = new()
{
Field1 = 1,
Field2 = IntPtr.Zero
};
- using MemoryStream stream = new MemoryStream();
+ using MemoryStream stream = new();
- Exception ex = Assert.Throws(() => SerializationHelperSql9.Serialize(stream, invalidWrapper));
+ var ex = Assert.Throws(() => SerializationHelperSql9.Serialize(stream, invalidWrapper));
string expectedException = StringsHelper.GetString(Strings.SQL_CannotCreateNormalizer, invalidWrapper.Field2.GetType().FullName);
Assert.Equal(expectedException, ex.Message);
@@ -247,7 +247,7 @@ public void CannotSerializeNonPrimitiveType()
/// Expected serialization output.
private static void RoundtripType(object inputValue, byte[] expectedValue)
{
- using MemoryStream stream = new MemoryStream();
+ using MemoryStream stream = new();
object readPrimitive;
int typeSize = SerializationHelperSql9.SizeInBytes(inputValue.GetType());
int objectSize = SerializationHelperSql9.SizeInBytes(inputValue);
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
index 34f8ab660a..fef8425121 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
@@ -27,7 +27,7 @@ public void CanSerializeClass()
[Fact]
public void RequiresPublicParameterlessConstructor()
{
- using MemoryStream stream = new MemoryStream();
+ using MemoryStream stream = new();
SerializationHelperSql9.Serialize(stream, new UserDefinedMissingPublicConstructor(true));
stream.Seek(0, SeekOrigin.Begin);
@@ -39,7 +39,7 @@ public void RequiresPublicParameterlessConstructor()
[Fact]
public void RequiresIBinarySerializeImplementation()
{
- using MemoryStream stream = new MemoryStream();
+ using MemoryStream stream = new();
Assert.Throws(
() => SerializationHelperSql9.Serialize(stream, new UserDefinedDoesNotImplementIBinarySerialize()));
@@ -48,7 +48,7 @@ public void RequiresIBinarySerializeImplementation()
private static void RoundtripType(T userObject)
where T : IFormattingProgress
{
- using MemoryStream stream = new MemoryStream();
+ using MemoryStream stream = new();
byte[] serializedValue;
T readInstance;
int typeSize = SerializationHelperSql9.SizeInBytes(userObject.GetType());
From 9f195c991a6b29899e5d0ede322f0a0961a2caf4 Mon Sep 17 00:00:00 2001
From: Edward Neal <55035479+edwardneal@users.noreply.github.com>
Date: Fri, 20 Jun 2025 23:35:53 +0100
Subject: [PATCH 06/10] Add and correct comments
Also mandating this by generating a documentation XML file
---
.../tests/UnitTests/InternalsVisibleToTest.cs | 6 ++
.../Microsoft.Data.SqlClient.UnitTests.csproj | 1 +
.../ChannelDbConnectionPoolTest.cs | 2 +
.../InvalidSerializationTest.cs | 10 ++
.../NativeSerializationTest.cs | 22 +++-
.../UdtSerialization/SerializedTypes.cs | 102 +++++++++---------
.../UserDefinedSerializationTest.cs | 16 +++
7 files changed, 103 insertions(+), 56 deletions(-)
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/InternalsVisibleToTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/InternalsVisibleToTest.cs
index eb924990db..36621fcb51 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/InternalsVisibleToTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/InternalsVisibleToTest.cs
@@ -4,8 +4,14 @@
namespace Microsoft.Data.SqlClient.UnitTests
{
+ ///
+ /// Tests proving that the InternalsVisibleTo attribute works correctly.
+ ///
public class InternalsVisibleToTest
{
+ ///
+ /// Creates an instance of an internal class. Verifies that this compiles.
+ ///
[Fact]
public void TestInternalsVisible()
{
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj
index f12807a403..4493b00b4d 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj
@@ -7,6 +7,7 @@
$(ObjFolder)$(Configuration).$(Platform).$(AssemblyName)$(BinFolder)$(Configuration).$(Platform).$(AssemblyName)true
+ true
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPoolTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPoolTest.cs
index 2dcfe476fe..671c1428dd 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPoolTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPoolTest.cs
@@ -11,6 +11,7 @@
namespace Microsoft.Data.SqlClient.UnitTests
{
+#pragma warning disable CS1591 // Test classes do not require XML documentation comments
public class ChannelDbConnectionPoolTest
{
private readonly ChannelDbConnectionPool _pool;
@@ -152,4 +153,5 @@ public void TestTryGetConnection()
Assert.Throws(() => _pool.TryGetConnection(null!, null!, null!, out _));
}
}
+#pragma warning restore CS1591
}
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
index 6036253304..0aeb910356 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
@@ -11,8 +11,14 @@
namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization;
+///
+/// Attempts to serialize types which do not meet the requirements for either user-defined or native serialization.
+///
public class InvalidSerializationTest
{
+ ///
+ /// Attempts to serialize a class that does not have the SqlUserDefinedType attribute. Verifies that this fails.
+ ///
[Fact]
public void RequiresSqlUserDefinedTypeAttribute()
{
@@ -24,6 +30,10 @@ public void RequiresSqlUserDefinedTypeAttribute()
Assert.Equal($"'{typeof(ClassMissingSqlUserDefinedTypeAttribute).FullName}' is an invalid user defined type, reason: no UDT attribute.", exception.Message);
}
+ ///
+ /// Attempts to serialize a class that has a SqlUserDefinedType attribute, but specifies a Format enumeration value of
+ /// Unknown. Verifies that this fails.
+ ///
[Fact]
public void CannotSerializeUnknownFormattedType()
{
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
index ae5523579a..f88b1707a1 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
@@ -18,6 +18,11 @@ namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization;
///
public class NativeSerializationTest
{
+ ///
+ /// Provides a collection of test data representing non-null primitive type values and their corresponding
+ /// serialized byte arrays.
+ ///
+ ///
public static IEnumerable SerializedNonNullPrimitiveTypeValues()
{
yield return [new BoolWrapperStruct { Field1 = true },
@@ -62,6 +67,10 @@ public static IEnumerable SerializedNonNullPrimitiveTypeValues()
new byte[] { 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xF8 }];
}
+ ///
+ /// Provides a collection of test data representing serialized values of nested non-null primitive types.
+ ///
+ ///
public static IEnumerable SerializedNestedNonNullPrimitiveTypeValues()
{
yield return [new NestedBoolWrapperStruct { Field1 = true, Field2 = new BoolWrapperStruct { Field1 = false } },
@@ -126,6 +135,10 @@ public static IEnumerable SerializedNestedNonNullPrimitiveTypeValues()
0x01, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9C, 0x64 }];
}
+ ///
+ /// Provides a collection of test data representing serialized null values for various primitive types.
+ ///
+ ///
public static IEnumerable SerializedNullPrimitiveTypeValues()
{
yield return [new SqlByteWrapperStruct { Field1 = SqlByte.Null },
@@ -182,7 +195,7 @@ public void SerializeNullPrimitiveType(object primitive, byte[] expectedValue)
=> RoundtripType(primitive, expectedValue);
///
- /// Attempts to serializes an instance of a class.
+ /// Attempts to serialize an instance of a class.
///
///
[Fact]
@@ -199,11 +212,10 @@ public void CanSerializeTopLevelClass()
}
///
- /// Attempts to serializes a field referring to an instance of a class.
- /// Verifies that this succeeds, and that Native format serialization only operates with primitive types
- /// and value types containing these.
+ /// Attempts to serialize a field referring to an instance of a class.
+ /// Verifies that this fails, and that Native format serialization only operates with primitive types and value types containing these.
///
- ///
+ ///
[Fact]
public void CannotSerializeNestedClass()
{
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs
index d6538f3584..5929958959 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs
@@ -13,189 +13,189 @@ namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization.SerializedTypes;
// Simple cases: a struct containing one of the designated primitive types
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct BoolWrapperStruct { public bool Field1; }
+internal struct BoolWrapperStruct { public bool Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct ByteWrapperStruct { public byte Field1; }
+internal struct ByteWrapperStruct { public byte Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct SByteWrapperStruct { public sbyte Field1; }
+internal struct SByteWrapperStruct { public sbyte Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct UShortWrapperStruct { public ushort Field1; }
+internal struct UShortWrapperStruct { public ushort Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct ShortWrapperStruct { public short Field1; }
+internal struct ShortWrapperStruct { public short Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct UIntWrapperStruct { public uint Field1; }
+internal struct UIntWrapperStruct { public uint Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct IntWrapperStruct { public int Field1; }
+internal struct IntWrapperStruct { public int Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct ULongWrapperStruct { public ulong Field1; }
+internal struct ULongWrapperStruct { public ulong Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct LongWrapperStruct { public long Field1; }
+internal struct LongWrapperStruct { public long Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct FloatWrapperStruct { public float Field1; }
+internal struct FloatWrapperStruct { public float Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct DoubleWrapperStruct { public double Field1; }
+internal struct DoubleWrapperStruct { public double Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct SqlByteWrapperStruct { public SqlByte Field1; }
+internal struct SqlByteWrapperStruct { public SqlByte Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct SqlInt16WrapperStruct { public SqlInt16 Field1; }
+internal struct SqlInt16WrapperStruct { public SqlInt16 Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct SqlInt32WrapperStruct { public SqlInt32 Field1; }
+internal struct SqlInt32WrapperStruct { public SqlInt32 Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct SqlInt64WrapperStruct { public SqlInt64 Field1; }
+internal struct SqlInt64WrapperStruct { public SqlInt64 Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct SqlBooleanWrapperStruct { public SqlBoolean Field1; }
+internal struct SqlBooleanWrapperStruct { public SqlBoolean Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct SqlSingleWrapperStruct { public SqlSingle Field1; }
+internal struct SqlSingleWrapperStruct { public SqlSingle Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct SqlDoubleWrapperStruct { public SqlDouble Field1; }
+internal struct SqlDoubleWrapperStruct { public SqlDouble Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct SqlDateTimeWrapperStruct { public SqlDateTime Field1; }
+internal struct SqlDateTimeWrapperStruct { public SqlDateTime Field1; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct SqlMoneyWrapperStruct { public SqlMoney Field1; }
+internal struct SqlMoneyWrapperStruct { public SqlMoney Field1; }
// Success case: a class containing one of the designated primitive types
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public class BoolWrapperClass { public bool Field1; }
+internal class BoolWrapperClass { public bool Field1; }
// Success case: a struct containing one designated primitive type and one nested struct
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedBoolWrapperStruct { public bool Field1; public BoolWrapperStruct Field2; }
+internal struct NestedBoolWrapperStruct { public bool Field1; public BoolWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedByteWrapperStruct { public byte Field1; public ByteWrapperStruct Field2; }
+internal struct NestedByteWrapperStruct { public byte Field1; public ByteWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedSByteWrapperStruct { public sbyte Field1; public SByteWrapperStruct Field2; }
+internal struct NestedSByteWrapperStruct { public sbyte Field1; public SByteWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedUShortWrapperStruct { public ushort Field1; public UShortWrapperStruct Field2; }
+internal struct NestedUShortWrapperStruct { public ushort Field1; public UShortWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedShortWrapperStruct { public short Field1; public ShortWrapperStruct Field2; }
+internal struct NestedShortWrapperStruct { public short Field1; public ShortWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedUIntWrapperStruct { public uint Field1; public UIntWrapperStruct Field2; }
+internal struct NestedUIntWrapperStruct { public uint Field1; public UIntWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedIntWrapperStruct { public int Field1; public IntWrapperStruct Field2; }
+internal struct NestedIntWrapperStruct { public int Field1; public IntWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedULongWrapperStruct { public ulong Field1; public ULongWrapperStruct Field2; }
+internal struct NestedULongWrapperStruct { public ulong Field1; public ULongWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedLongWrapperStruct { public long Field1; public LongWrapperStruct Field2; }
+internal struct NestedLongWrapperStruct { public long Field1; public LongWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedFloatWrapperStruct { public float Field1; public FloatWrapperStruct Field2; }
+internal struct NestedFloatWrapperStruct { public float Field1; public FloatWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedDoubleWrapperStruct { public double Field1; public DoubleWrapperStruct Field2; }
+internal struct NestedDoubleWrapperStruct { public double Field1; public DoubleWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedSqlByteWrapperStruct { public SqlByte Field1; public SqlByteWrapperStruct Field2; }
+internal struct NestedSqlByteWrapperStruct { public SqlByte Field1; public SqlByteWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedSqlInt16WrapperStruct { public SqlInt16 Field1; public SqlInt16WrapperStruct Field2; }
+internal struct NestedSqlInt16WrapperStruct { public SqlInt16 Field1; public SqlInt16WrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedSqlInt32WrapperStruct { public SqlInt32 Field1; public SqlInt32WrapperStruct Field2; }
+internal struct NestedSqlInt32WrapperStruct { public SqlInt32 Field1; public SqlInt32WrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedSqlInt64WrapperStruct { public SqlInt64 Field1; public SqlInt64WrapperStruct Field2; }
+internal struct NestedSqlInt64WrapperStruct { public SqlInt64 Field1; public SqlInt64WrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedSqlBooleanWrapperStruct { public SqlBoolean Field1; public SqlBooleanWrapperStruct Field2; }
+internal struct NestedSqlBooleanWrapperStruct { public SqlBoolean Field1; public SqlBooleanWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedSqlSingleWrapperStruct { public SqlSingle Field1; public SqlSingleWrapperStruct Field2; }
+internal struct NestedSqlSingleWrapperStruct { public SqlSingle Field1; public SqlSingleWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedSqlDoubleWrapperStruct { public SqlDouble Field1; public SqlDoubleWrapperStruct Field2; }
+internal struct NestedSqlDoubleWrapperStruct { public SqlDouble Field1; public SqlDoubleWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedSqlDateTimeWrapperStruct { public SqlDateTime Field1; public SqlDateTimeWrapperStruct Field2; }
+internal struct NestedSqlDateTimeWrapperStruct { public SqlDateTime Field1; public SqlDateTimeWrapperStruct Field2; }
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct NestedSqlMoneyWrapperStruct { public SqlMoney Field1; public SqlMoneyWrapperStruct Field2; }
+internal struct NestedSqlMoneyWrapperStruct { public SqlMoney Field1; public SqlMoneyWrapperStruct Field2; }
// Success case: a class containing one designated primitive type and a nested struct
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public class NestedBoolWrapperClass { public bool Field1; public BoolWrapperStruct Field2; }
+internal class NestedBoolWrapperClass { public bool Field1; public BoolWrapperStruct Field2; }
// Failure case: a struct or a class containing one designated primitive type and a nested class
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public class InvalidNestedBoolWrapperClass { public bool Field1; public BoolWrapperClass Field2; }
+internal class InvalidNestedBoolWrapperClass { public bool Field1; public BoolWrapperClass Field2; }
// Failure case: a struct or a class containing a field which is not a designated primitive type
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-public struct InvalidIntPtrAndByteWrapperStruct { public byte Field1; public IntPtr Field2; }
+internal struct InvalidIntPtrAndByteWrapperStruct { public byte Field1; public IntPtr Field2; }
// Success case: a struct or a class implementing IBinarySerialize which would not otherwise be serializable
-public interface IFormattingProgress
+internal interface IFormattingProgress
{
bool ParameterlessConstructorInvoked { get; }
bool ReadInvoked { get; }
@@ -203,7 +203,7 @@ public interface IFormattingProgress
}
[SqlUserDefinedType(Format.UserDefined, MaxByteSize = 11)]
-public struct UserDefinedFormattedStruct : IBinarySerialize, IFormattingProgress, IEquatable
+internal struct UserDefinedFormattedStruct : IBinarySerialize, IFormattingProgress, IEquatable
{
public IntPtr Field1;
public bool ParameterlessConstructorInvoked { get; }
@@ -255,7 +255,7 @@ public bool Equals(UserDefinedFormattedStruct other)
}
[SqlUserDefinedType(Format.UserDefined, MaxByteSize = 11)]
-public class UserDefinedFormattedClass : IBinarySerialize, IFormattingProgress, IEquatable
+internal class UserDefinedFormattedClass : IBinarySerialize, IFormattingProgress, IEquatable
{
public IntPtr Field1;
public bool ParameterlessConstructorInvoked { get; }
@@ -310,7 +310,7 @@ public bool Equals(UserDefinedFormattedClass other)
// or has a SqlUserDefinedType attribute with a Format of Unknown.
[SqlUserDefinedType(Format.UserDefined)]
-public class UserDefinedMissingPublicConstructor : IBinarySerialize
+internal class UserDefinedMissingPublicConstructor : IBinarySerialize
{
public UserDefinedMissingPublicConstructor(bool _) { }
@@ -320,16 +320,16 @@ public void Write(BinaryWriter w) { }
}
[SqlUserDefinedType(Format.UserDefined)]
-public class UserDefinedDoesNotImplementIBinarySerialize
+internal class UserDefinedDoesNotImplementIBinarySerialize
{
public UserDefinedDoesNotImplementIBinarySerialize() { }
}
-public class ClassMissingSqlUserDefinedTypeAttribute
+internal class ClassMissingSqlUserDefinedTypeAttribute
{
}
[SqlUserDefinedType(Format.Unknown)]
-public class UnknownFormattedClass
+internal class UnknownFormattedClass
{
}
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
index fef8425121..a944f48d81 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
@@ -16,14 +16,26 @@ namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization;
///
public class UserDefinedSerializationTest
{
+ ///
+ /// Attempts to serialize and deserialize an instance of a struct with a user-defined serialization method.
+ ///
+ ///
[Fact]
public void CanSerializeStruct()
=> RoundtripType(new UserDefinedFormattedStruct((IntPtr)0x12345678));
+ ///
+ /// Attempts to serialize and deserialize an instance of a class with a user-defined serialization method.
+ ///
+ ///
[Fact]
public void CanSerializeClass()
=> RoundtripType(new UserDefinedFormattedClass((IntPtr)0x12345678));
+ ///
+ /// Attempts to deserialize an instance of a type with a user-defined serialization method but without a public
+ /// parameterless constructor. Verifies that this fails.
+ ///
[Fact]
public void RequiresPublicParameterlessConstructor()
{
@@ -36,6 +48,10 @@ public void RequiresPublicParameterlessConstructor()
() => SerializationHelperSql9.Deserialize(stream, typeof(UserDefinedMissingPublicConstructor)));
}
+ ///
+ /// Attempts to deserialize an instance of a type with a user-defined serialization method but which does not,
+ /// implement IBinarySerialize. Verifies that this fails.
+ ///
[Fact]
public void RequiresIBinarySerializeImplementation()
{
From 62edb700162fefafdb87437b520f8b92c15f2a72 Mon Sep 17 00:00:00 2001
From: Edward Neal <55035479+edwardneal@users.noreply.github.com>
Date: Fri, 20 Jun 2025 23:38:26 +0100
Subject: [PATCH 07/10] Enable nullable for project
---
.../tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj | 1 +
.../Data/SqlClient/UdtSerialization/SerializedTypes.cs | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj
index 4493b00b4d..cb9ea86243 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj
@@ -8,6 +8,7 @@
$(BinFolder)$(Configuration).$(Platform).$(AssemblyName)truetrue
+ enable
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs
index 5929958959..a02c213e01 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/SerializedTypes.cs
@@ -187,7 +187,7 @@ internal class NestedBoolWrapperClass { public bool Field1; public BoolWrapperSt
// Failure case: a struct or a class containing one designated primitive type and a nested class
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
-internal class InvalidNestedBoolWrapperClass { public bool Field1; public BoolWrapperClass Field2; }
+internal class InvalidNestedBoolWrapperClass { public bool Field1; public BoolWrapperClass? Field2; }
// Failure case: a struct or a class containing a field which is not a designated primitive type
[SqlUserDefinedType(Format.Native)]
@@ -302,7 +302,7 @@ public void Write(BinaryWriter w)
WriteInvoked = true;
}
- public bool Equals(UserDefinedFormattedClass other)
+ public bool Equals(UserDefinedFormattedClass? other)
=> other is not null && other.Field1 == Field1;
}
From f9136f9a111417cba3ac9106c3032d3fbf403662 Mon Sep 17 00:00:00 2001
From: Edward Neal <55035479+edwardneal@users.noreply.github.com>
Date: Fri, 20 Jun 2025 23:54:19 +0100
Subject: [PATCH 08/10] Declare and assign variables together
---
.../SqlClient/UdtSerialization/NativeSerializationTest.cs | 3 +--
.../UdtSerialization/UserDefinedSerializationTest.cs | 6 ++----
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
index f88b1707a1..987a1cb6e5 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
@@ -260,14 +260,13 @@ public void CannotSerializeNonPrimitiveType()
private static void RoundtripType(object inputValue, byte[] expectedValue)
{
using MemoryStream stream = new();
- object readPrimitive;
int typeSize = SerializationHelperSql9.SizeInBytes(inputValue.GetType());
int objectSize = SerializationHelperSql9.SizeInBytes(inputValue);
int maxTypeSize = SerializationHelperSql9.GetUdtMaxLength(inputValue.GetType());
SerializationHelperSql9.Serialize(stream, inputValue);
stream.Seek(0, SeekOrigin.Begin);
- readPrimitive = SerializationHelperSql9.Deserialize(stream, inputValue.GetType());
+ object readPrimitive = SerializationHelperSql9.Deserialize(stream, inputValue.GetType());
// For native formatting, the type size, the object size and the maximum object size will always be identical
Assert.Equal(typeSize, objectSize);
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
index a944f48d81..e338a90628 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
@@ -65,16 +65,14 @@ private static void RoundtripType(T userObject)
where T : IFormattingProgress
{
using MemoryStream stream = new();
- byte[] serializedValue;
- T readInstance;
int typeSize = SerializationHelperSql9.SizeInBytes(userObject.GetType());
int objectSize = SerializationHelperSql9.SizeInBytes(userObject);
int maxTypeSize = SerializationHelperSql9.GetUdtMaxLength(userObject.GetType());
SerializationHelperSql9.Serialize(stream, userObject);
- serializedValue = stream.ToArray();
stream.Seek(0, SeekOrigin.Begin);
- readInstance = (T)SerializationHelperSql9.Deserialize(stream, userObject.GetType());
+ byte[] serializedValue = stream.ToArray();
+ T readInstance = (T)SerializationHelperSql9.Deserialize(stream, userObject.GetType());
// If this is a struct, it will have been copied by value and the write to WriteInvoked will have been made
// to another copy of our object
From 6e80cc54c8b46d9ab55a0c2b11a4d5850c915d5c Mon Sep 17 00:00:00 2001
From: Edward Neal <55035479+edwardneal@users.noreply.github.com>
Date: Sat, 21 Jun 2025 00:41:37 +0100
Subject: [PATCH 09/10] Moved MemoryStream to an instance variable
---
.../InvalidSerializationTest.cs | 25 ++++++++----
.../NativeSerializationTest.cs | 37 +++++++++++------
.../UserDefinedSerializationTest.cs | 40 ++++++++++++-------
3 files changed, 67 insertions(+), 35 deletions(-)
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
index 0aeb910356..bee1db5838 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/InvalidSerializationTest.cs
@@ -14,18 +14,31 @@ namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization;
///
/// Attempts to serialize types which do not meet the requirements for either user-defined or native serialization.
///
-public class InvalidSerializationTest
+public sealed class InvalidSerializationTest : IDisposable
{
+ private readonly MemoryStream _stream;
+
+ ///
+ /// Initializes the MemoryStream used for all tests in this class.
+ ///
+ public InvalidSerializationTest()
+ {
+ _stream = new MemoryStream();
+ }
+
+ void IDisposable.Dispose()
+ {
+ _stream.Dispose();
+ }
+
///
/// Attempts to serialize a class that does not have the SqlUserDefinedType attribute. Verifies that this fails.
///
[Fact]
public void RequiresSqlUserDefinedTypeAttribute()
{
- using MemoryStream stream = new();
-
var exception = Assert.Throws(
- () => SerializationHelperSql9.Serialize(stream, new ClassMissingSqlUserDefinedTypeAttribute()));
+ () => SerializationHelperSql9.Serialize(_stream, new ClassMissingSqlUserDefinedTypeAttribute()));
Assert.Equal($"'{typeof(ClassMissingSqlUserDefinedTypeAttribute).FullName}' is an invalid user defined type, reason: no UDT attribute.", exception.Message);
}
@@ -37,10 +50,8 @@ public void RequiresSqlUserDefinedTypeAttribute()
[Fact]
public void CannotSerializeUnknownFormattedType()
{
- using MemoryStream stream = new();
-
var exception = Assert.Throws("Format",
- () => SerializationHelperSql9.Serialize(stream, new UnknownFormattedClass()));
+ () => SerializationHelperSql9.Serialize(_stream, new UnknownFormattedClass()));
#if NET
Assert.Equal("The Format enumeration value, 0, is not supported by the format method. (Parameter 'Format')", exception.Message);
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
index 987a1cb6e5..e37e862e99 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/NativeSerializationTest.cs
@@ -16,8 +16,23 @@ namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization;
/// Tests the serialization method defined by MS-SSCLRT. Ensures that combinations of primitives and custom types round-trip.
///
///
-public class NativeSerializationTest
+public sealed class NativeSerializationTest : IDisposable
{
+ private readonly MemoryStream _stream;
+
+ ///
+ /// Initializes the MemoryStream used for all tests in this class.
+ ///
+ public NativeSerializationTest()
+ {
+ _stream = new MemoryStream();
+ }
+
+ void IDisposable.Dispose()
+ {
+ _stream.Dispose();
+ }
+
///
/// Provides a collection of test data representing non-null primitive type values and their corresponding
/// serialized byte arrays.
@@ -206,9 +221,8 @@ public void CanSerializeTopLevelClass()
Field1 = true,
Field2 = new BoolWrapperStruct() { Field1 = true }
};
- using MemoryStream stream = new();
- SerializationHelperSql9.Serialize(stream, validWrapper);
+ SerializationHelperSql9.Serialize(_stream, validWrapper);
}
///
@@ -224,9 +238,8 @@ public void CannotSerializeNestedClass()
Field1 = true,
Field2 = new BoolWrapperClass() { Field1 = true }
};
- using MemoryStream stream = new();
- var ex = Assert.Throws(() => SerializationHelperSql9.Serialize(stream, invalidWrapper));
+ var ex = Assert.Throws(() => SerializationHelperSql9.Serialize(_stream, invalidWrapper));
string expectedException = StringsHelper.GetString(Strings.SQL_CannotCreateNormalizer, invalidWrapper.Field2.GetType().FullName);
Assert.Equal(expectedException, ex.Message);
@@ -244,9 +257,8 @@ public void CannotSerializeNonPrimitiveType()
Field1 = 1,
Field2 = IntPtr.Zero
};
- using MemoryStream stream = new();
- var ex = Assert.Throws(() => SerializationHelperSql9.Serialize(stream, invalidWrapper));
+ var ex = Assert.Throws(() => SerializationHelperSql9.Serialize(_stream, invalidWrapper));
string expectedException = StringsHelper.GetString(Strings.SQL_CannotCreateNormalizer, invalidWrapper.Field2.GetType().FullName);
Assert.Equal(expectedException, ex.Message);
@@ -257,23 +269,22 @@ public void CannotSerializeNonPrimitiveType()
///
/// Object to serialize.
/// Expected serialization output.
- private static void RoundtripType(object inputValue, byte[] expectedValue)
+ private void RoundtripType(object inputValue, byte[] expectedValue)
{
- using MemoryStream stream = new();
int typeSize = SerializationHelperSql9.SizeInBytes(inputValue.GetType());
int objectSize = SerializationHelperSql9.SizeInBytes(inputValue);
int maxTypeSize = SerializationHelperSql9.GetUdtMaxLength(inputValue.GetType());
- SerializationHelperSql9.Serialize(stream, inputValue);
- stream.Seek(0, SeekOrigin.Begin);
- object readPrimitive = SerializationHelperSql9.Deserialize(stream, inputValue.GetType());
+ SerializationHelperSql9.Serialize(_stream, inputValue);
+ _stream.Seek(0, SeekOrigin.Begin);
+ object readPrimitive = SerializationHelperSql9.Deserialize(_stream, inputValue.GetType());
// For native formatting, the type size, the object size and the maximum object size will always be identical
Assert.Equal(typeSize, objectSize);
Assert.Equal(expectedValue.Length, typeSize);
Assert.Equal(typeSize, maxTypeSize);
- Assert.Equal(expectedValue, stream.ToArray());
+ Assert.Equal(expectedValue, _stream.ToArray());
Assert.Equal(inputValue, readPrimitive);
}
}
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
index e338a90628..da3f47f5ee 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/UdtSerialization/UserDefinedSerializationTest.cs
@@ -14,8 +14,23 @@ namespace Microsoft.Data.SqlClient.UnitTests.UdtSerialization;
///
/// Tests the user-defined UDT serialization method. Verifies that custom types round-trip.
///
-public class UserDefinedSerializationTest
+public sealed class UserDefinedSerializationTest : IDisposable
{
+ private readonly MemoryStream _stream;
+
+ ///
+ /// Initializes the MemoryStream used for all tests in this class.
+ ///
+ public UserDefinedSerializationTest()
+ {
+ _stream = new MemoryStream();
+ }
+
+ void IDisposable.Dispose()
+ {
+ _stream.Dispose();
+ }
+
///
/// Attempts to serialize and deserialize an instance of a struct with a user-defined serialization method.
///
@@ -39,13 +54,11 @@ public void CanSerializeClass()
[Fact]
public void RequiresPublicParameterlessConstructor()
{
- using MemoryStream stream = new();
-
- SerializationHelperSql9.Serialize(stream, new UserDefinedMissingPublicConstructor(true));
- stream.Seek(0, SeekOrigin.Begin);
+ SerializationHelperSql9.Serialize(_stream, new UserDefinedMissingPublicConstructor(true));
+ _stream.Seek(0, SeekOrigin.Begin);
Assert.Throws(
- () => SerializationHelperSql9.Deserialize(stream, typeof(UserDefinedMissingPublicConstructor)));
+ () => SerializationHelperSql9.Deserialize(_stream, typeof(UserDefinedMissingPublicConstructor)));
}
///
@@ -55,24 +68,21 @@ public void RequiresPublicParameterlessConstructor()
[Fact]
public void RequiresIBinarySerializeImplementation()
{
- using MemoryStream stream = new();
-
Assert.Throws(
- () => SerializationHelperSql9.Serialize(stream, new UserDefinedDoesNotImplementIBinarySerialize()));
+ () => SerializationHelperSql9.Serialize(_stream, new UserDefinedDoesNotImplementIBinarySerialize()));
}
- private static void RoundtripType(T userObject)
+ private void RoundtripType(T userObject)
where T : IFormattingProgress
{
- using MemoryStream stream = new();
int typeSize = SerializationHelperSql9.SizeInBytes(userObject.GetType());
int objectSize = SerializationHelperSql9.SizeInBytes(userObject);
int maxTypeSize = SerializationHelperSql9.GetUdtMaxLength(userObject.GetType());
- SerializationHelperSql9.Serialize(stream, userObject);
- stream.Seek(0, SeekOrigin.Begin);
- byte[] serializedValue = stream.ToArray();
- T readInstance = (T)SerializationHelperSql9.Deserialize(stream, userObject.GetType());
+ SerializationHelperSql9.Serialize(_stream, userObject);
+ _stream.Seek(0, SeekOrigin.Begin);
+ byte[] serializedValue = _stream.ToArray();
+ T readInstance = (T)SerializationHelperSql9.Deserialize(_stream, userObject.GetType());
// If this is a struct, it will have been copied by value and the write to WriteInvoked will have been made
// to another copy of our object
From fa46855ed26f35b6620e3b6cebe3f10e0ebabc6d Mon Sep 17 00:00:00 2001
From: Edward Neal <55035479+edwardneal@users.noreply.github.com>
Date: Fri, 27 Jun 2025 21:47:13 +0100
Subject: [PATCH 10/10] Post-merge build corrections
---
.../tests/UnitTests/Microsoft/Data/SqlTypes/SqlJsonTest.cs | 4 ++++
src/Microsoft.Data.SqlClient/tests/UnitTests/SqlVectorTest.cs | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlTypes/SqlJsonTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlTypes/SqlJsonTest.cs
index faf44a4e29..52d22b54b3 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlTypes/SqlJsonTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlTypes/SqlJsonTest.cs
@@ -12,6 +12,8 @@
namespace Microsoft.Data.SqlClient.UnitTests;
+#pragma warning disable CS1591 // Test classes do not require XML documentation comments
+
public class SqlJsonTest
{
#region Private Fields
@@ -155,3 +157,5 @@ private static JsonDocument GenerateRandomJson()
#endregion
}
+
+#pragma warning restore CS1591
diff --git a/src/Microsoft.Data.SqlClient/tests/UnitTests/SqlVectorTest.cs b/src/Microsoft.Data.SqlClient/tests/UnitTests/SqlVectorTest.cs
index 3390d95c02..3206c64881 100644
--- a/src/Microsoft.Data.SqlClient/tests/UnitTests/SqlVectorTest.cs
+++ b/src/Microsoft.Data.SqlClient/tests/UnitTests/SqlVectorTest.cs
@@ -11,6 +11,8 @@
namespace Microsoft.Data.SqlClient.Tests;
+#pragma warning disable CS1591 // Test classes do not require XML documentation comments
+
public class SqlVectorTest
{
#region Tests
@@ -243,3 +245,5 @@ private byte[] MakeTdsPayload(byte[] header, ReadOnlyMemory values)
#endregion
}
+
+#pragma warning restore CS1591