From 6abcb4d7224138accc7b8f05110b544bb6020d80 Mon Sep 17 00:00:00 2001 From: Vladimir Pecanac Date: Sun, 30 Aug 2026 18:34:00 +0200 Subject: [PATCH] Custom naming policy: retarget net10.0, consolidate four projects to two, NUnit 4 - Both surviving projects move from net7 to net10.0. - The .NET8 sample and its four tests merge into CustomNamingPolicy and Test; both .NET8 projects are deleted and the solution loses their entries. The split only existed because the .NET 8 policies would not compile on net7. CustomNamingPolicy.NET8.Test had no ProjectReference, so nothing depended on the removed projects. - Test packages to current stable: NUnit 4.6.1, NUnit3TestAdapter 6.3.0, NUnit.Analyzers 4.14.0, Microsoft.NET.Test.Sdk 18.9.0, coverlet.collector 10.0.1. The seven assertions move to Assert.That(..., Is.EqualTo(...)). - Program.cs converts to top-level statements, which also removes a class that shared its name with its namespace. - NodeSeparatorPolicy uses ArgumentNullException.ThrowIfNull and CamelCasePolicy uses a range indexer; both land in the article's snippets. Build: 0 warnings, 0 errors. Tests: 7/7 passing. SDK 10.0.302, runtime 10.0.10. --- .../CustomNamingPolicy.NET8.Test.csproj | 20 ---- .../GlobalUsings.cs | 1 - .../CustomNamingPolicy.NET8.csproj | 10 -- .../CustomNamingPolicy.NET8/Program.cs | 59 ---------- .../CustomNamingPolicy/CustomNamingPolicy.sln | 12 -- .../CustomNamingPolicy/CamelCasePolicy.cs | 2 +- .../CustomNamingPolicy.csproj | 2 +- .../CustomNamingPolicy/NodeSeparatorPolicy.cs | 6 +- .../CustomNamingPolicy/Program.cs | 107 ++++++++++++------ .../BuiltInPolicyTests.cs} | 19 ++-- .../Test/CustomPolicyUnitTests.cs | 8 +- .../CustomNamingPolicy/Test/Test.csproj | 12 +- 12 files changed, 96 insertions(+), 162 deletions(-) delete mode 100644 json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8.Test/CustomNamingPolicy.NET8.Test.csproj delete mode 100644 json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8.Test/GlobalUsings.cs delete mode 100644 json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8/CustomNamingPolicy.NET8.csproj delete mode 100644 json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8/Program.cs rename json-csharp/CustomNamingPolicy/{CustomNamingPolicy.NET8.Test/CustomPolicyNet8UnitTests.cs => Test/BuiltInPolicyTests.cs} (86%) diff --git a/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8.Test/CustomNamingPolicy.NET8.Test.csproj b/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8.Test/CustomNamingPolicy.NET8.Test.csproj deleted file mode 100644 index 0072a6d1c6..0000000000 --- a/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8.Test/CustomNamingPolicy.NET8.Test.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - net8.0 - enable - enable - - false - true - - - - - - - - - - - diff --git a/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8.Test/GlobalUsings.cs b/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8.Test/GlobalUsings.cs deleted file mode 100644 index cefced4969..0000000000 --- a/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8.Test/GlobalUsings.cs +++ /dev/null @@ -1 +0,0 @@ -global using NUnit.Framework; \ No newline at end of file diff --git a/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8/CustomNamingPolicy.NET8.csproj b/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8/CustomNamingPolicy.NET8.csproj deleted file mode 100644 index 2150e3797b..0000000000 --- a/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8/CustomNamingPolicy.NET8.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - diff --git a/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8/Program.cs b/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8/Program.cs deleted file mode 100644 index f62420625b..0000000000 --- a/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8/Program.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Text.Json; - -namespace CustomNamingPolicy.NET8 -{ - internal class Program - { - static void Main(string[] args) - { - ConvertToSnakeCaseLower(); - ConvertToSnakeCaseUpper(); - ConvertToKebabCaseLower(); - ConvertToKebabCaseUpper(); - } - - private static void ConvertToSnakeCaseLower() - { - var snakeCaseLowerPolicy = new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower - }; - - var jsonObj = JsonSerializer.Serialize(new { PropertyName = "value" }, snakeCaseLowerPolicy); - Console.WriteLine(jsonObj); - } - - private static void ConvertToSnakeCaseUpper() - { - var snakeCaseUpperPolicy = new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseUpper - }; - - var jsonObj = JsonSerializer.Serialize(new { PropertyName = "value" }, snakeCaseUpperPolicy); - Console.WriteLine(jsonObj); - } - - private static void ConvertToKebabCaseLower() - { - var kebabCaseLowerPolicy = new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.KebabCaseLower - }; - - var jsonObj = JsonSerializer.Serialize(new { PropertyName = "value" }, kebabCaseLowerPolicy); - Console.WriteLine(jsonObj); - } - - private static void ConvertToKebabCaseUpper() - { - var kebabCaseUpperPolicy = new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.KebabCaseUpper - }; - - var jsonObj = JsonSerializer.Serialize(new { PropertyName = "value" }, kebabCaseUpperPolicy); - Console.WriteLine(jsonObj); - } - } -} \ No newline at end of file diff --git a/json-csharp/CustomNamingPolicy/CustomNamingPolicy.sln b/json-csharp/CustomNamingPolicy/CustomNamingPolicy.sln index 6b0d525932..e08ef227f2 100644 --- a/json-csharp/CustomNamingPolicy/CustomNamingPolicy.sln +++ b/json-csharp/CustomNamingPolicy/CustomNamingPolicy.sln @@ -7,10 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomNamingPolicy", "Custo EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "Test\Test.csproj", "{F0A97070-D698-4309-BD2A-19C1EF410EAA}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomNamingPolicy.NET8", "CustomNamingPolicy.NET8\CustomNamingPolicy.NET8.csproj", "{EA2B17EB-E1B1-4FF5-A64D-379DF523F1FE}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomNamingPolicy.NET8.Test", "CustomNamingPolicy.NET8.Test\CustomNamingPolicy.NET8.Test.csproj", "{D9E5E15E-E8E7-470D-B634-D46E786F6889}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -25,14 +21,6 @@ Global {F0A97070-D698-4309-BD2A-19C1EF410EAA}.Debug|Any CPU.Build.0 = Debug|Any CPU {F0A97070-D698-4309-BD2A-19C1EF410EAA}.Release|Any CPU.ActiveCfg = Release|Any CPU {F0A97070-D698-4309-BD2A-19C1EF410EAA}.Release|Any CPU.Build.0 = Release|Any CPU - {EA2B17EB-E1B1-4FF5-A64D-379DF523F1FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EA2B17EB-E1B1-4FF5-A64D-379DF523F1FE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EA2B17EB-E1B1-4FF5-A64D-379DF523F1FE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EA2B17EB-E1B1-4FF5-A64D-379DF523F1FE}.Release|Any CPU.Build.0 = Release|Any CPU - {D9E5E15E-E8E7-470D-B634-D46E786F6889}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D9E5E15E-E8E7-470D-B634-D46E786F6889}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D9E5E15E-E8E7-470D-B634-D46E786F6889}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D9E5E15E-E8E7-470D-B634-D46E786F6889}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/json-csharp/CustomNamingPolicy/CustomNamingPolicy/CamelCasePolicy.cs b/json-csharp/CustomNamingPolicy/CustomNamingPolicy/CamelCasePolicy.cs index b7c680390c..d8789a441d 100644 --- a/json-csharp/CustomNamingPolicy/CustomNamingPolicy/CamelCasePolicy.cs +++ b/json-csharp/CustomNamingPolicy/CustomNamingPolicy/CamelCasePolicy.cs @@ -6,7 +6,7 @@ public class CamelCasePolicy : JsonNamingPolicy { public override string ConvertName(string name) { - return char.IsUpper(name[0]) ? char.ToLower(name[0]) + name.Substring(1) : name; + return char.IsUpper(name[0]) ? char.ToLower(name[0]) + name[1..] : name; } } } diff --git a/json-csharp/CustomNamingPolicy/CustomNamingPolicy/CustomNamingPolicy.csproj b/json-csharp/CustomNamingPolicy/CustomNamingPolicy/CustomNamingPolicy.csproj index 8dbbfa89a8..ed9781c223 100644 --- a/json-csharp/CustomNamingPolicy/CustomNamingPolicy/CustomNamingPolicy.csproj +++ b/json-csharp/CustomNamingPolicy/CustomNamingPolicy/CustomNamingPolicy.csproj @@ -2,7 +2,7 @@ Exe - net7 + net10.0 enable enable diff --git a/json-csharp/CustomNamingPolicy/CustomNamingPolicy/NodeSeparatorPolicy.cs b/json-csharp/CustomNamingPolicy/CustomNamingPolicy/NodeSeparatorPolicy.cs index 7118bf511c..c8724ca9ea 100644 --- a/json-csharp/CustomNamingPolicy/CustomNamingPolicy/NodeSeparatorPolicy.cs +++ b/json-csharp/CustomNamingPolicy/CustomNamingPolicy/NodeSeparatorPolicy.cs @@ -7,10 +7,8 @@ public class NodeSeparatorPolicy : JsonNamingPolicy { public override string ConvertName(string name) { - if (name is null) - { - throw new ArgumentNullException(nameof(name)); - } + ArgumentNullException.ThrowIfNull(name); + var sb = new StringBuilder(); sb.Append(char.ToLower(name[0])); for (int i = 1; i < name.Length; i++) diff --git a/json-csharp/CustomNamingPolicy/CustomNamingPolicy/Program.cs b/json-csharp/CustomNamingPolicy/CustomNamingPolicy/Program.cs index bbd3c00871..ad21a0bea0 100644 --- a/json-csharp/CustomNamingPolicy/CustomNamingPolicy/Program.cs +++ b/json-csharp/CustomNamingPolicy/CustomNamingPolicy/Program.cs @@ -1,37 +1,80 @@ using System.Text.Json; +using CustomNamingPolicy; -namespace CustomNamingPolicy; +var person = new Person() +{ + GivenName = "Name1", + surName = "Surname1" +}; + +// No custom policy used +var jsonString = JsonSerializer.Serialize(person); +Console.WriteLine(jsonString); + +// camelCase Policy used +var camelCaseOptions = new JsonSerializerOptions() +{ + PropertyNamingPolicy = new CamelCasePolicy() +}; + +jsonString = JsonSerializer.Serialize(person, camelCaseOptions); +Console.WriteLine(jsonString); + +// node/separator Policy used +var nodeOptions = new JsonSerializerOptions() +{ + PropertyNamingPolicy = new NodeSeparatorPolicy() +}; + +jsonString = JsonSerializer.Serialize(person, nodeOptions); +Console.WriteLine(jsonString); + +// Built-in policies +ConvertToSnakeCaseLower(); +ConvertToSnakeCaseUpper(); +ConvertToKebabCaseLower(); +ConvertToKebabCaseUpper(); + +static void ConvertToSnakeCaseLower() +{ + var snakeCaseLowerPolicy = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower + }; + + var jsonObj = JsonSerializer.Serialize(new { PropertyName = "value" }, snakeCaseLowerPolicy); + Console.WriteLine(jsonObj); +} + +static void ConvertToSnakeCaseUpper() +{ + var snakeCaseUpperPolicy = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseUpper + }; + + var jsonObj = JsonSerializer.Serialize(new { PropertyName = "value" }, snakeCaseUpperPolicy); + Console.WriteLine(jsonObj); +} -public class CustomNamingPolicy +static void ConvertToKebabCaseLower() { - public static void Main() + var kebabCaseLowerPolicy = new JsonSerializerOptions { - var person = new Person() - { - GivenName = "Name1", - surName = "Surname1" - }; - - // No custom policy used - var jsonString = JsonSerializer.Serialize(person); - Console.WriteLine(jsonString); - - // camelCase Policy used - var camelCaseOptions = new JsonSerializerOptions() - { - PropertyNamingPolicy = new CamelCasePolicy() - }; - - jsonString = JsonSerializer.Serialize(person, camelCaseOptions); - Console.WriteLine(jsonString); - - // node/separator Policy used - var nodeOptions = new JsonSerializerOptions() - { - PropertyNamingPolicy = new NodeSeparatorPolicy() - }; - - jsonString = JsonSerializer.Serialize(person, nodeOptions); - Console.WriteLine(jsonString); - } -} \ No newline at end of file + PropertyNamingPolicy = JsonNamingPolicy.KebabCaseLower + }; + + var jsonObj = JsonSerializer.Serialize(new { PropertyName = "value" }, kebabCaseLowerPolicy); + Console.WriteLine(jsonObj); +} + +static void ConvertToKebabCaseUpper() +{ + var kebabCaseUpperPolicy = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.KebabCaseUpper + }; + + var jsonObj = JsonSerializer.Serialize(new { PropertyName = "value" }, kebabCaseUpperPolicy); + Console.WriteLine(jsonObj); +} diff --git a/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8.Test/CustomPolicyNet8UnitTests.cs b/json-csharp/CustomNamingPolicy/Test/BuiltInPolicyTests.cs similarity index 86% rename from json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8.Test/CustomPolicyNet8UnitTests.cs rename to json-csharp/CustomNamingPolicy/Test/BuiltInPolicyTests.cs index b7b728bdeb..74a39db96c 100644 --- a/json-csharp/CustomNamingPolicy/CustomNamingPolicy.NET8.Test/CustomPolicyNet8UnitTests.cs +++ b/json-csharp/CustomNamingPolicy/Test/BuiltInPolicyTests.cs @@ -1,14 +1,9 @@ using System.Text.Json; -namespace CustomNamingPolicy.NET8.Test; +namespace Test; -public class Tests +public class BuiltInPolicyTests { - [SetUp] - public void Setup() - { - } - [Test] public void GivenObject_WhenSerializeWithSnakeCaseLowerPolicy_ReturnSnakeCaseLowerResult() { @@ -24,7 +19,7 @@ public void GivenObject_WhenSerializeWithSnakeCaseLowerPolicy_ReturnSnakeCaseLow var expectedJsonObj = "{\"property_name\":\"value\"}"; //Assert - Assert.AreEqual(expectedJsonObj, jsonObj); + Assert.That(jsonObj, Is.EqualTo(expectedJsonObj)); } [Test] @@ -42,7 +37,7 @@ public void GivenObject_WhenSerializeWithSnakeCaseUpperPolicy_ReturnSnakeCaseUpp var expectedJsonObj = "{\"PROPERTY_NAME\":\"value\"}"; //Assert - Assert.AreEqual(expectedJsonObj, jsonObj); + Assert.That(jsonObj, Is.EqualTo(expectedJsonObj)); } [Test] @@ -60,7 +55,7 @@ public void GivenObject_WhenSerializeWithKebabCaseLowerPolicy_ReturnKebabCaseLow var expectedJsonObj = "{\"property-name\":\"value\"}"; //Assert - Assert.AreEqual(expectedJsonObj, jsonObj); + Assert.That(jsonObj, Is.EqualTo(expectedJsonObj)); } [Test] @@ -78,6 +73,6 @@ public void GivenObject_WhenSerializeWithKebabCaseUpperPolicy_ReturnKebabCaseUpp var expectedJsonObj = "{\"PROPERTY-NAME\":\"value\"}"; //Assert - Assert.AreEqual(expectedJsonObj, jsonObj); + Assert.That(jsonObj, Is.EqualTo(expectedJsonObj)); } -} \ No newline at end of file +} diff --git a/json-csharp/CustomNamingPolicy/Test/CustomPolicyUnitTests.cs b/json-csharp/CustomNamingPolicy/Test/CustomPolicyUnitTests.cs index 40d3fe28de..1d2c53171c 100644 --- a/json-csharp/CustomNamingPolicy/Test/CustomPolicyUnitTests.cs +++ b/json-csharp/CustomNamingPolicy/Test/CustomPolicyUnitTests.cs @@ -25,7 +25,7 @@ public void GivenPerson_WhenSerializeWithDefaultOptions_ReturnDefaultResult() var expectedJson = "{\"GivenName\":\"Name1\",\"surName\":\"Surname1\"}"; //Assert - Assert.AreEqual(expectedJson, jsonString); + Assert.That(jsonString, Is.EqualTo(expectedJson)); } [Test] @@ -42,7 +42,7 @@ public void GivenPerson_WhenSerializeWithNodeSeparatorPolicy_ReturnNodeSeparator var expectedJson = "{\"given/name\":\"Name1\",\"sur/name\":\"Surname1\"}"; //Assert - Assert.AreEqual(expectedJson, jsonString); + Assert.That(jsonString, Is.EqualTo(expectedJson)); } [Test] @@ -59,6 +59,6 @@ public void GivenPerson_WhenSerializeWithCamelCasePolicy_ReturnCamelCasePolicyRe var expectedJson = "{\"givenName\":\"Name1\",\"surName\":\"Surname1\"}"; //Assert - Assert.AreEqual(expectedJson, jsonString); + Assert.That(jsonString, Is.EqualTo(expectedJson)); } -} \ No newline at end of file +} diff --git a/json-csharp/CustomNamingPolicy/Test/Test.csproj b/json-csharp/CustomNamingPolicy/Test/Test.csproj index c00f5d9745..d777c1362c 100644 --- a/json-csharp/CustomNamingPolicy/Test/Test.csproj +++ b/json-csharp/CustomNamingPolicy/Test/Test.csproj @@ -1,7 +1,7 @@ - net7 + net10.0 enable enable @@ -10,11 +10,11 @@ - - - - - + + + + +