Upgrade to MSTest 4

This commit is contained in:
Andy Howard
2026-09-14 18:31:46 +01:00
parent de59098961
commit 7651e8824f
7 changed files with 58 additions and 62 deletions
+2 -2
View File
@@ -10,8 +10,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.10.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.10.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.10.1" />
<PackageReference Include="MSTest.TestAdapter" Version="4.4.0" />
<PackageReference Include="MSTest.TestFramework" Version="4.4.0" />
<PackageReference Include="coverlet.collector" Version="10.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
@@ -1,4 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Utils;
using System;
@@ -21,11 +21,11 @@ namespace Sacs.UnitTests.Net.Standard.Base.Bus
public void SysId_CTR_Void ()
{
Assert.IsNotNull(new SysId());
Assert.AreEqual(new SysId().ToInt(), 0);
Assert.AreEqual(0, new SysId().ToInt());
Assert.IsTrue(String.IsNullOrEmpty(new SysId().ToString()));
Assert.IsTrue(StringUtil.IsEmpty(new SysId().ToString()));
Assert.AreEqual(new SysId().ToString(), "");
Assert.AreEqual(new SysId().ToString(), string.Empty);
Assert.AreEqual("", new SysId().ToString());
Assert.AreEqual(string.Empty, new SysId().ToString());
}
[TestMethod]
@@ -1,4 +1,4 @@
using System;
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sarand.Net.Standard.Base.Utils;
@@ -168,7 +168,7 @@ namespace Sarand.UnitTests.Core.Base.Utils
// Random date between 0AD and 3000AD (or thereabouts):
DateTime date = new DateTime(random.Next(0, 365 * 3000) * TimeSpan.TicksPerDay);
//Trace.WriteLine("DateUtil_Tester.DateTime_StartOfWeek Date=" + date.Format("ddd d-MMM-yyyy") + ", Start of week=" + date.StartOfWeek().Format("ddd d-MMM-yyyy"));
Assert.AreEqual(date.StartOfWeek().Format("ddd"), "Sun");
Assert.AreEqual("Sun", date.StartOfWeek().Format("ddd"));
}
}
// DateUtil.StartOfWeek
@@ -180,7 +180,7 @@ namespace Sarand.UnitTests.Core.Base.Utils
// Random date between 0AD and 3000AD (or thereabouts):
DateTime date = new DateTime(random.Next(0, 365 * 3000) * TimeSpan.TicksPerDay);
//Trace.WriteLine("DateUtil_Tester.DateTime_StartOfWorkingWeek Date=" + date.Format("ddd d-MMM-yyyy") + ", Start of week=" + date.StartOfWorkingWeek().Format("ddd d-MMM-yyyy"));
Assert.AreEqual(date.StartOfWorkingWeek().Format("ddd"), "Mon");
Assert.AreEqual("Mon", date.StartOfWorkingWeek().Format("ddd"));
}
}
@@ -198,7 +198,7 @@ namespace Sarand.UnitTests.Core.Base.Utils
public void DateTime_DaysInMonth ()
{
DateTime dt20160723 = new DateTime(2016, 7, 23);
Assert.AreEqual(dt20160723.DaysInMonth(), 31);
Assert.AreEqual(31, dt20160723.DaysInMonth());
}
// DateUtil.EndOfMonth
[TestMethod]
@@ -217,11 +217,11 @@ namespace Sarand.UnitTests.Core.Base.Utils
DateTime dt20160723 = new DateTime(2016, 7, 23);
DateTime dt20160723172829 = new DateTime(2016, 7, 23, 17, 28, 39);
Assert.AreEqual(dt20160723.Format("dd/MM/yyyy"), "23/07/2016");
Assert.AreEqual(dt20160723.Format("dd/MM/yyyy HH:mm:ss"), "23/07/2016 00:00:00");
Assert.AreEqual("23/07/2016", dt20160723.Format("dd/MM/yyyy"));
Assert.AreEqual("23/07/2016 00:00:00", dt20160723.Format("dd/MM/yyyy HH:mm:ss"));
Assert.AreEqual(dt20160723172829.Format("dd/MM/yyyy"), "23/07/2016");
Assert.AreEqual(dt20160723172829.Format("dd/MM/yyyy HH:mm:ss"), "23/07/2016 17:28:39");
Assert.AreEqual("23/07/2016", dt20160723172829.Format("dd/MM/yyyy"));
Assert.AreEqual("23/07/2016 17:28:39", dt20160723172829.Format("dd/MM/yyyy HH:mm:ss"));
}
//-------------------------------------------------------------------
@@ -61,7 +61,7 @@ namespace Sarand.UnitTests.Core.Base.Utils
Assert.AreEqual(SaMessageLevel.Debug, EnumUtil.StartsWith<SaMessageLevel>("DEB", SaMessageLevel.Error));
Assert.AreEqual(SaMessageLevel.Debug, EnumUtil.StartsWith<SaMessageLevel>("DEBU", SaMessageLevel.Error));
Assert.AreEqual(SaMessageLevel.Debug, EnumUtil.StartsWith<SaMessageLevel>("DEBUG", SaMessageLevel.Error));
Assert.AreEqual(EnumUtil.StartsWith<SaMessageLevel>("Err", SaMessageLevel.Error), SaMessageLevel.Error);
Assert.AreEqual(SaMessageLevel.Error, EnumUtil.StartsWith<SaMessageLevel>("Err", SaMessageLevel.Error));
Assert.AreEqual(SaMessageLevel.None, EnumUtil.StartsWith<SaMessageLevel>("", SaMessageLevel.Error));
Assert.AreEqual(SaMessageLevel.Error, EnumUtil.StartsWith<SaMessageLevel>("ABC", SaMessageLevel.Error));
}
@@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -9,13 +9,12 @@ namespace Sarand.UnitTests.Core.Base.Utils
[TestClass]
public class StringUtil_Tester
{
//-------------------------------------------------------------------
// Data members.
// --- Data Members ---
private Random random = new Random();
//-------------------------------------------------------------------
// Properties.
//-------------------------------------------------------------------
// --- Empty and Blank Values ---
[TestMethod]
public void StringUtil_IsEmpty()
{
@@ -45,9 +44,8 @@ namespace Sarand.UnitTests.Core.Base.Utils
Assert.AreEqual(false, "Abc".IsBlank());
}
//-------------------------------------------------------------------
// Regular Expression Matching.
//-------------------------------------------------------------------
// --- Regular Expression Matching ---
[TestMethod]
public void StringUtil_IsMatch()
{
@@ -135,9 +133,8 @@ namespace Sarand.UnitTests.Core.Base.Utils
Assert.AreEqual(2, "ABCDEFGHICDEJKL".MatchesCount(new Regex("CDE")));
}
//-------------------------------------------------------------------
// Padding.
//-------------------------------------------------------------------
// --- Padding ---
[TestMethod]
public void StringUtil_PadLeft()
{
@@ -174,50 +171,49 @@ namespace Sarand.UnitTests.Core.Base.Utils
Assert.AreEqual("12300", "123".PadRight(5, '0'));
}
//-------------------------------------------------------------------
// S u b S t r i n g
//-------------------------------------------------------------------
// --- Safe Substrings ---
[TestMethod]
public void StringUtil_SubstringSafe()
{
Assert.AreEqual(StringUtil.SubstringSafe(null, 0), "");
Assert.AreEqual(StringUtil.SubstringSafe("", 0), "");
Assert.AreEqual("".SubstringSafe(0), "");
Assert.AreEqual("", StringUtil.SubstringSafe(null, 0));
Assert.AreEqual("", StringUtil.SubstringSafe("", 0));
Assert.AreEqual("", "".SubstringSafe(0));
// Right portion from start position.
Assert.AreEqual("abc".SubstringSafe(-3), "abc");
Assert.AreEqual("abc".SubstringSafe(-2), "abc");
Assert.AreEqual("abc".SubstringSafe(-1), "abc");
Assert.AreEqual("abc".SubstringSafe(0), "abc");
Assert.AreEqual("abc".SubstringSafe(1), "bc");
Assert.AreEqual("abc".SubstringSafe(2), "c");
Assert.AreEqual("abc".SubstringSafe(3), "");
Assert.AreEqual("abc", "abc".SubstringSafe(-3));
Assert.AreEqual("abc", "abc".SubstringSafe(-2));
Assert.AreEqual("abc", "abc".SubstringSafe(-1));
Assert.AreEqual("abc", "abc".SubstringSafe(0));
Assert.AreEqual("bc", "abc".SubstringSafe(1));
Assert.AreEqual("c", "abc".SubstringSafe(2));
Assert.AreEqual("", "abc".SubstringSafe(3));
// Zero length.
Assert.AreEqual(StringUtil.SubstringSafe(null, 0, 0), "");
Assert.AreEqual(StringUtil.SubstringSafe("", 0, 0), "");
Assert.AreEqual("".SubstringSafe(0, 0), "");
Assert.AreEqual("abc".SubstringSafe(-1, 0), "");
Assert.AreEqual("abc".SubstringSafe(0, 0), "");
Assert.AreEqual("abc".SubstringSafe(1, 0), "");
Assert.AreEqual("abc".SubstringSafe(2, 0), "");
Assert.AreEqual("abc".SubstringSafe(3, 0), "");
Assert.AreEqual("abc".SubstringSafe(4, 0), "");
Assert.AreEqual("", StringUtil.SubstringSafe(null, 0, 0));
Assert.AreEqual("", StringUtil.SubstringSafe("", 0, 0));
Assert.AreEqual("", "".SubstringSafe(0, 0));
Assert.AreEqual("", "abc".SubstringSafe(-1, 0));
Assert.AreEqual("", "abc".SubstringSafe(0, 0));
Assert.AreEqual("", "abc".SubstringSafe(1, 0));
Assert.AreEqual("", "abc".SubstringSafe(2, 0));
Assert.AreEqual("", "abc".SubstringSafe(3, 0));
Assert.AreEqual("", "abc".SubstringSafe(4, 0));
// Mid portion.
Assert.AreEqual("abcde".SubstringSafe(0, 3), "abc");
Assert.AreEqual("abcde".SubstringSafe(1, 3), "bcd");
Assert.AreEqual("abcde".SubstringSafe(2, 3), "cde");
Assert.AreEqual("abc", "abcde".SubstringSafe(0, 3));
Assert.AreEqual("bcd", "abcde".SubstringSafe(1, 3));
Assert.AreEqual("cde", "abcde".SubstringSafe(2, 3));
// Excessive length.
Assert.AreEqual("abcde".SubstringSafe(-1, 12), "abcde");
Assert.AreEqual("abcde".SubstringSafe(0, 12), "abcde");
Assert.AreEqual("abcde".SubstringSafe(1, 12), "bcde");
Assert.AreEqual("abcde".SubstringSafe(2, 12), "cde");
Assert.AreEqual("abcde".SubstringSafe(3, 12), "de");
Assert.AreEqual("abcde".SubstringSafe(4, 12), "e");
Assert.AreEqual("abcde".SubstringSafe(5, 12), "");
Assert.AreEqual("abcde", "abcde".SubstringSafe(-1, 12));
Assert.AreEqual("abcde", "abcde".SubstringSafe(0, 12));
Assert.AreEqual("bcde", "abcde".SubstringSafe(1, 12));
Assert.AreEqual("cde", "abcde".SubstringSafe(2, 12));
Assert.AreEqual("de", "abcde".SubstringSafe(3, 12));
Assert.AreEqual("e", "abcde".SubstringSafe(4, 12));
Assert.AreEqual("", "abcde".SubstringSafe(5, 12));
}
//-------------------------------------------------------------------
// --- The End ---
}
}
+1 -1
View File
@@ -15,7 +15,7 @@ Last updated: 2026-09-14
| `SacsStandardBase/Base/Utils/ImageUtils.cs` | ImageSharp wrapper | Covered for package upgrades | 2026-09-14 | Extend the suite when adding formats or changing resize policy. | Five in-memory tests cover PNG and JPEG metadata, invalid and truncated input, SVG recognition, format-preserving encoding, proportional landscape and portrait resizing, no-upscale behavior, and invalid constraints. |
| `SacsStandardBase` JSON utilities and `SysId` converter | Newtonsoft.Json integration | Covered for package upgrades | 2026-09-14 | Retain the suite for future Newtonsoft.Json updates. | Six tests cover objects, arrays, nulls, serializer settings, valid and invalid parsing paths, dynamic access, `SysId` conversion, independent deep copies, nested collections, and constructor-value replacement. |
| `SacsStandardDbas` provider and parameter creation | Microsoft.Data.SqlClient and registry integration | Initial package-upgrade coverage complete | 2026-09-14 | Expand into configured database integration tests before the planned SqlClient major upgrade. | Four database-free tests cover SQL versus forced ODBC connection selection, connection strings, values and nulls, explicit integer and binary types, SQL `DateTime2`, ODBC `DateTime`, precision normalization, and sentinel dates. The redundant Registry 5.0.0 package was removed; .NET 10 supplies the APIs and `NU1510` is gone. |
| `SacsCoreUnitTests` | Test SDK, MSTest, and coverage tooling | Current; coverage verified | 2026-09-14 | Treat MSTest 4 as a separate major-version review. | Uses Microsoft.NET.Test.Sdk 18.10.0, MSTest 3.10.1, and coverlet collector 10.0.1. New analyzer findings were corrected, all 126 tests pass, and the optional validation coverage mode verifies a non-empty Cobertura report. |
| `SacsCoreUnitTests` | Test SDK, MSTest, and coverage tooling | Current; coverage verified | 2026-09-14 | Preserve the analyzer-clean build and explicit coverage validation during future test-tool upgrades. | Uses Microsoft.NET.Test.Sdk 18.10.0, MSTest 4.4.0, and coverlet collector 10.0.1. The MSTest 4 migration corrected 39 reversed expected/actual assertions; all 126 tests pass without MSTest analyzer warnings, and the optional validation coverage mode verifies a non-empty Cobertura report. |
| `SacsMobileXamarin` | Migration disposition | Isolated; retained for reference | 2026-09-10 | Keep outside the supported build unless a separately scoped resurrection or migration is approved. | Source is unchanged and available through `SaCommonVS.LegacyXamarin.sln`; see `docs/legacy-xamarin.md`. |
| [`SacsMobileMaui`](../SacsMobileMaui/docs/component-reviews.md) | Project | .NET 10 migration complete; tracked in project docs | 2026-09-11 | Validate Apple targets on a Mac and continue API cleanup in the project tracker. | The shared project and both active mobile consumers target .NET 10. Windows runtime smoke tests pass, and Windows and Android Debug builds complete with zero errors. |
| `SacsStandardBase/Base/Procs/SaProcess_Base.cs` | Class | In progress | 2026-09-09 | Complete the Process Base actions recorded in `topics.md`; review derived processes separately for cooperative polling. | Lifecycle state ownership and cancellation lock ordering were changed. Five focused tests pass. Remaining concerns include mixed sync/async execution, durable cancellation outcome, cancellation exception handling, disposal, and status synchronization. |
+1 -1
View File
@@ -44,7 +44,7 @@ Last updated: 2026-09-14
| Topic | Date noted | Date started | Date completed | Outcome |
|---|---|---|---|---|
| Modernise Common test tooling and coverage collection | 2026-09-14 | 2026-09-14 | 2026-09-14 | Updated Microsoft.NET.Test.Sdk from 16.5.0 to 18.10.0, MSTest adapter and framework from 2.1.0 to 3.10.1, and coverlet collector from 1.2.0 to 10.0.1 with private-assets metadata. Replaced legacy exception assertions and corrected the `TestContext` property exposed by the newer analyzers. All 126 Common tests, 11 BusinessMgr Control tests, and 13 BusinessMgr Portal tests pass. The validation scripts now offer `-CollectCoverage`, which verifies non-empty Cobertura reports across Common and both BusinessMgr suites. |
| Modernise Common test tooling and coverage collection | 2026-09-14 | 2026-09-14 | 2026-09-14 | Updated Microsoft.NET.Test.Sdk from 16.5.0 to 18.10.0, MSTest adapter and framework from 2.1.0 to 4.4.0, and coverlet collector from 1.2.0 to 10.0.1 with private-assets metadata. Replaced legacy exception assertions, corrected the `TestContext` property, and fixed 39 reversed expected/actual assertions identified by the MSTest 4 analyzers. All 126 Common tests, 11 BusinessMgr Control tests, and 13 BusinessMgr Portal tests pass. The validation scripts offer `-CollectCoverage`, which verifies non-empty Cobertura reports across Common and both BusinessMgr suites. |
| Remove redundant Microsoft.Win32.Registry package | 2026-09-10 | 2026-09-14 | 2026-09-14 | Removed the direct 5.0.0 package reference from `SacsStandardDbas`; .NET 10 supplies the required registry APIs. Common and BusinessMgr restore, build, and all 126 Common, 11 Control, and 13 Portal tests pass. The `NU1510` warning no longer appears. |
| Apply low-risk Common package patches and regression coverage | 2026-09-14 | 2026-09-14 | 2026-09-14 | Updated Microsoft.Data.SqlClient from 5.2.2 to 5.2.3, Newtonsoft.Json from 13.0.3 to 13.0.4, and SixLabors.ImageSharp from 3.1.11 to 3.1.12. Added 15 in-memory tests covering image recognition, encoding and resizing; JSON serialization, parsing, dynamic access, `SysId` conversion and deep copying; and SQL/ODBC provider selection and command parameters. The Common solution builds with zero errors; all 126 Common tests, 11 BusinessMgr Control tests, and 13 BusinessMgr Portal tests pass. Existing warnings are unchanged. |
| Make asynchronous Process Base execution awaitable and retain state after a stop timeout | 2026-09-08 | 2026-09-08 | 2026-09-08 | `RunAsync()` returns `Task`; `StopProcessAsync()` reports success and leaves active state owned by a worker that has not stopped. |