From f43aa1fdc3bfb63a5742a39f3648363999ff91d4 Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Sun, 25 May 2025 12:40:38 -0700 Subject: [PATCH 01/13] MapTo page extension --- NetChris.Core.UnitTests/Paging/MapToTests.cs | 80 ++++++++++++++++++++ NetChris.Core/Paging/Extensions.cs | 27 +++++++ 2 files changed, 107 insertions(+) create mode 100644 NetChris.Core.UnitTests/Paging/MapToTests.cs create mode 100644 NetChris.Core/Paging/Extensions.cs diff --git a/NetChris.Core.UnitTests/Paging/MapToTests.cs b/NetChris.Core.UnitTests/Paging/MapToTests.cs new file mode 100644 index 0000000..eaa7b5d --- /dev/null +++ b/NetChris.Core.UnitTests/Paging/MapToTests.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using NetChris.Core.Paging; +using Xunit; + +namespace NetChris.Core.UnitTests.Paging; + +public class MapToTests +{ + private class FromType + { + public string Name { get; set; } = null!; + public int Age { get; set; } + } + + private class ToType + { + public string PersonName { get; set; } = null!; + public TimeSpan Age { get; set; } + } + + + private readonly List _fromTypes = new() + { + new FromType { Name = "Alice", Age = 30 }, + new FromType { Name = "Bob", Age = 25 }, + new FromType { Name = "Charlie", Age = 35 }, + new FromType { Name = "Diana", Age = 28 } + }; + + + private readonly Page _sourcePage; + private readonly Page _targetPage; + + private static ToType MappingFunction(FromType from) + { + return new ToType + { + PersonName = from.Name, + Age = TimeSpan.FromDays(from.Age * 365.25), + }; + } + + public MapToTests() + { + _sourcePage = new Page(_fromTypes, 2, 4, 500); + _targetPage = _sourcePage.MapTo(MappingFunction); + } + + [Fact] + public void TotalPagesShouldBeCorrect() + { + _targetPage.TotalPages.Should().Be(_sourcePage.TotalPages); + } + + [Fact] + public void CurrentPageShouldBeCorrect() + { + _targetPage.CurrentPage.Should().Be(_sourcePage.CurrentPage); + } + + [Fact] + public void PageSizeShouldBeCorrect() + { + _targetPage.PageSize.Should().Be(_sourcePage.PageSize); + } + + [Fact] + public void MappedItemShouldMatch() + { + var charlieFromSourcePage = _sourcePage.Items.ElementAt(2); + var charlieFromTargetPage = _targetPage.Items.ElementAt(2); + + charlieFromTargetPage.PersonName.Should().Be(charlieFromSourcePage.Name); + charlieFromTargetPage.Age.Should().Be( + TimeSpan.FromDays(charlieFromSourcePage.Age * 365.25)); + } +} \ No newline at end of file diff --git a/NetChris.Core/Paging/Extensions.cs b/NetChris.Core/Paging/Extensions.cs new file mode 100644 index 0000000..efa358a --- /dev/null +++ b/NetChris.Core/Paging/Extensions.cs @@ -0,0 +1,27 @@ +using System; +using System.Linq; + +namespace NetChris.Core.Paging; + +/// +/// Extension methods for paging +/// +public static class Extensions +{ + /// + /// Get a page of items of type + /// mapped from a page of items of type + /// + /// The source page + /// The mapping function from to + public static Page MapTo(this Page sourcePage, Func mappingFunction) + { + var resultItems = sourcePage.Items.Select(mappingFunction).ToList(); + + return new Page( + resultItems, + sourcePage.CurrentPage, + sourcePage.PageSize, + sourcePage.TotalItems); + } +} \ No newline at end of file From d62f99b283e70a31535e356e0d228aa986fbd1a2 Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Mon, 26 May 2025 12:58:59 -0700 Subject: [PATCH 02/13] XML Doc spelling --- NetChris.Core/Values/SimpleResult.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NetChris.Core/Values/SimpleResult.cs b/NetChris.Core/Values/SimpleResult.cs index 40ab585..ed898bf 100644 --- a/NetChris.Core/Values/SimpleResult.cs +++ b/NetChris.Core/Values/SimpleResult.cs @@ -1,7 +1,7 @@ namespace NetChris.Core.Values; /// -/// Lightweight object with an code and message. +/// Lightweight object with a code and message. /// A glorified key/value pair. /// /// From a4308d3d584d3269770c80dca8231002adc3a20b Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Tue, 27 May 2025 21:51:31 -0700 Subject: [PATCH 03/13] Add SimpleResult.IsPublic --- NetChris.Core/Values/SimpleResult.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/NetChris.Core/Values/SimpleResult.cs b/NetChris.Core/Values/SimpleResult.cs index ed898bf..dceabaf 100644 --- a/NetChris.Core/Values/SimpleResult.cs +++ b/NetChris.Core/Values/SimpleResult.cs @@ -30,14 +30,26 @@ public string Message get; } + /// + /// Whether the message can be publicly displayed + /// (e.g. in a RFC 9457 Problem Details from a web API). + /// + /// The message + public bool IsPublic + { + get; + } + /// /// Initializes a new instance of the class. /// /// The result code /// The message - public SimpleResult(string resultCode, string message) + /// Whether the message can be publicly displayed + public SimpleResult(string resultCode, string message, bool isPublic = true) { ResultCode = resultCode; Message = message; + IsPublic = isPublic; } } \ No newline at end of file From ae64039d446ab43628bf0485f5981025cd2358d0 Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Tue, 27 May 2025 21:53:20 -0700 Subject: [PATCH 04/13] XML docs --- NetChris.Core/Values/SimpleResult.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/NetChris.Core/Values/SimpleResult.cs b/NetChris.Core/Values/SimpleResult.cs index dceabaf..9ac1ba7 100644 --- a/NetChris.Core/Values/SimpleResult.cs +++ b/NetChris.Core/Values/SimpleResult.cs @@ -13,18 +13,16 @@ public class SimpleResult { /// - /// Gets the code + /// The result code /// - /// The result code public string ResultCode { get; } /// - /// Gets the message. + /// The message /// - /// The message public string Message { get; @@ -34,7 +32,10 @@ public string Message /// Whether the message can be publicly displayed /// (e.g. in a RFC 9457 Problem Details from a web API). /// - /// The message + /// + /// It is implementation dependent how this is used. + /// The default is true, meaning the message can be displayed publicly. + /// public bool IsPublic { get; From 8fae97e21699aaaaf334cdb4d011f7f35173f6bb Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Wed, 28 May 2025 18:12:02 -0700 Subject: [PATCH 05/13] ResultCode -> ResultType and change to Uri --- NetChris.Core/Values/SimpleResult.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/NetChris.Core/Values/SimpleResult.cs b/NetChris.Core/Values/SimpleResult.cs index 9ac1ba7..abf2339 100644 --- a/NetChris.Core/Values/SimpleResult.cs +++ b/NetChris.Core/Values/SimpleResult.cs @@ -1,4 +1,6 @@ -namespace NetChris.Core.Values; +using System; + +namespace NetChris.Core.Values; /// /// Lightweight object with a code and message. @@ -13,9 +15,12 @@ public class SimpleResult { /// - /// The result code + /// The result type /// - public string ResultCode + /// + /// This is implemented as a to communicate that the result is of a unique type + /// + public Uri ResultType { get; } @@ -44,12 +49,12 @@ public bool IsPublic /// /// Initializes a new instance of the class. /// - /// The result code + /// The result type /// The message /// Whether the message can be publicly displayed - public SimpleResult(string resultCode, string message, bool isPublic = true) + public SimpleResult(Uri resultType, string message, bool isPublic = true) { - ResultCode = resultCode; + ResultType = resultType; Message = message; IsPublic = isPublic; } From e751279b9590fdba2c4d32ccca798f03c6a717bb Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Wed, 28 May 2025 18:16:51 -0700 Subject: [PATCH 06/13] Get rid of SimpleResult --- NetChris.Core/Values/SimpleResult.cs | 61 ---------------------------- 1 file changed, 61 deletions(-) delete mode 100644 NetChris.Core/Values/SimpleResult.cs diff --git a/NetChris.Core/Values/SimpleResult.cs b/NetChris.Core/Values/SimpleResult.cs deleted file mode 100644 index abf2339..0000000 --- a/NetChris.Core/Values/SimpleResult.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; - -namespace NetChris.Core.Values; - -/// -/// Lightweight object with a code and message. -/// A glorified key/value pair. -/// -/// -/// -/// Ideal use is in systems and APIs that, for example, return messages -/// or throw errors with unique-ish codes and an explanatory message. -/// -/// -public class SimpleResult -{ - /// - /// The result type - /// - /// - /// This is implemented as a to communicate that the result is of a unique type - /// - public Uri ResultType - { - get; - } - - /// - /// The message - /// - public string Message - { - get; - } - - /// - /// Whether the message can be publicly displayed - /// (e.g. in a RFC 9457 Problem Details from a web API). - /// - /// - /// It is implementation dependent how this is used. - /// The default is true, meaning the message can be displayed publicly. - /// - public bool IsPublic - { - get; - } - - /// - /// Initializes a new instance of the class. - /// - /// The result type - /// The message - /// Whether the message can be publicly displayed - public SimpleResult(Uri resultType, string message, bool isPublic = true) - { - ResultType = resultType; - Message = message; - IsPublic = isPublic; - } -} \ No newline at end of file From 303c1db77add2784d44301a31c0e8ae059fbce86 Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Sat, 31 May 2025 12:59:38 -0700 Subject: [PATCH 07/13] Include GitHub files in SLN --- NetChris.Core.sln | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/NetChris.Core.sln b/NetChris.Core.sln index 6e73915..c1d6246 100644 --- a/NetChris.Core.sln +++ b/NetChris.Core.sln @@ -7,12 +7,22 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Files", "Solution ProjectSection(SolutionItems) = preProject README.md = README.md Directory.Build.props = Directory.Build.props + .github\.DS_Store = .github\.DS_Store EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetChris.Core", "NetChris.Core\NetChris.Core.csproj", "{24F1F7DC-1F68-4F45-BD2B-97CD9A1BF532}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetChris.Core.UnitTests", "NetChris.Core.UnitTests\NetChris.Core.UnitTests.csproj", "{18EFFC4F-2289-4469-B930-8E6F500F1BCE}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "github", "github", "{F173C738-53A9-459E-A0C9-DF7F791A3AE5}" + ProjectSection(SolutionItems) = preProject + .github\workflows\publish-github-pre-release.yml = .github\workflows\publish-github-pre-release.yml + .github\workflows\publish-github-release.yml = .github\workflows\publish-github-release.yml + .github\workflows\publish-nuget-org-pre-release.yml = .github\workflows\publish-nuget-org-pre-release.yml + .github\workflows\publish-nuget-org-release.yml = .github\workflows\publish-nuget-org-release.yml + .github\workflows\push.yml = .github\workflows\push.yml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -32,5 +42,6 @@ Global {18EFFC4F-2289-4469-B930-8E6F500F1BCE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution + {F173C738-53A9-459E-A0C9-DF7F791A3AE5} = {0B8D2CDC-5BCE-45C8-8928-4EFE52528923} EndGlobalSection EndGlobal From fcfbaf8ca7f047a626d34b38caa1966204ca395a Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Sun, 8 Jun 2025 11:57:13 -0700 Subject: [PATCH 08/13] Reserved Numeric Range [skip ci] --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index b7d91f3..073a5dc 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ # NetChris.Core Base metadata and operational classes for .NET Core development. + +## [Reserved Numeric Range](https://github.com/NetChris/reference/wiki/Number-reservations) + +The `NetChris.Core` library reserves `0` through `999,999` for use by such purposes as: + +- Event IDs +- Advisory lock numbers From 8bbddf95813cb98445959bb9f0f3c34a5dca838d Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Sat, 22 Nov 2025 19:14:35 -0800 Subject: [PATCH 09/13] Reserved range --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 073a5dc..b4a99a7 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Base metadata and operational classes for .NET Core development. ## [Reserved Numeric Range](https://github.com/NetChris/reference/wiki/Number-reservations) -The `NetChris.Core` library reserves `0` through `999,999` for use by such purposes as: +The `NetChris.Core` library reserves `5,000,000` through `5,999,999` for use by such purposes as: - Event IDs - Advisory lock numbers From e844281d1a49d2c8c72602a310a85110c0b85620 Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Sat, 22 Nov 2025 19:15:33 -0800 Subject: [PATCH 10/13] Restore, make SimpleResult obsolete --- NetChris.Core/Values/SimpleResult.cs | 62 ++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 NetChris.Core/Values/SimpleResult.cs diff --git a/NetChris.Core/Values/SimpleResult.cs b/NetChris.Core/Values/SimpleResult.cs new file mode 100644 index 0000000..627a0ad --- /dev/null +++ b/NetChris.Core/Values/SimpleResult.cs @@ -0,0 +1,62 @@ +using System; + +namespace NetChris.Core.Values; + +/// +/// Lightweight object with a code and message. +/// A glorified key/value pair. +/// +/// +/// +/// Ideal use is in systems and APIs that, for example, return messages +/// or throw errors with unique-ish codes and an explanatory message. +/// +/// +[Obsolete] +public class SimpleResult +{ + /// + /// The result type + /// + /// + /// This is implemented as a to communicate that the result is of a unique type + /// + public Uri ResultType + { + get; + } + + /// + /// The message + /// + public string Message + { + get; + } + + /// + /// Whether the message can be publicly displayed + /// (e.g. in a RFC 9457 Problem Details from a web API). + /// + /// + /// It is implementation dependent how this is used. + /// The default is true, meaning the message can be displayed publicly. + /// + public bool IsPublic + { + get; + } + + /// + /// Initializes a new instance of the class. + /// + /// The result type + /// The message + /// Whether the message can be publicly displayed + public SimpleResult(Uri resultType, string message, bool isPublic = true) + { + ResultType = resultType; + Message = message; + IsPublic = isPublic; + } +} \ No newline at end of file From 68e6a62a6f1a47d7c2517c1c77ca184c30ed6778 Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Sat, 22 Nov 2025 19:18:30 -0800 Subject: [PATCH 11/13] Modernize GitHub actions --- .github/workflows/publish-github-pre-release.yml | 3 ++- .github/workflows/publish-github-release.yml | 3 ++- .github/workflows/publish-nuget-org-pre-release.yml | 3 ++- .github/workflows/publish-nuget-org-release.yml | 3 ++- .github/workflows/push.yml | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish-github-pre-release.yml b/.github/workflows/publish-github-pre-release.yml index 98dcb7b..05fb328 100644 --- a/.github/workflows/publish-github-pre-release.yml +++ b/.github/workflows/publish-github-pre-release.yml @@ -7,7 +7,8 @@ on: jobs: push: permissions: + checks: write contents: read packages: write - uses: NetChris/workflows/.github/workflows/pre-release-nuget-github.yml@v0.0 + uses: NetChris/workflows/.github/workflows/pre-release-nuget-github.yml@v2 secrets: inherit diff --git a/.github/workflows/publish-github-release.yml b/.github/workflows/publish-github-release.yml index 36a5ffd..e463f73 100644 --- a/.github/workflows/publish-github-release.yml +++ b/.github/workflows/publish-github-release.yml @@ -7,7 +7,8 @@ on: jobs: push: permissions: + checks: write contents: read packages: write - uses: NetChris/workflows/.github/workflows/release-nuget-github.yml@v0.0 + uses: NetChris/workflows/.github/workflows/release-nuget-github.yml@v2 secrets: inherit diff --git a/.github/workflows/publish-nuget-org-pre-release.yml b/.github/workflows/publish-nuget-org-pre-release.yml index d015a6a..490d454 100644 --- a/.github/workflows/publish-nuget-org-pre-release.yml +++ b/.github/workflows/publish-nuget-org-pre-release.yml @@ -7,7 +7,8 @@ on: jobs: push: permissions: + checks: write contents: read packages: write - uses: NetChris/workflows/.github/workflows/pre-release-nuget-org.yml@v0.0 + uses: NetChris/workflows/.github/workflows/pre-release-nuget-org.yml@v2 secrets: inherit diff --git a/.github/workflows/publish-nuget-org-release.yml b/.github/workflows/publish-nuget-org-release.yml index 2c8ef3f..2b11985 100644 --- a/.github/workflows/publish-nuget-org-release.yml +++ b/.github/workflows/publish-nuget-org-release.yml @@ -7,7 +7,8 @@ on: jobs: push: permissions: + checks: write contents: read packages: write - uses: NetChris/workflows/.github/workflows/release-nuget-org.yml@v0.0 + uses: NetChris/workflows/.github/workflows/release-nuget-org.yml@v2 secrets: inherit diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index fa7fea9..1d23ddc 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -8,4 +8,4 @@ jobs: checks: write contents: read packages: write - uses: NetChris/workflows/.github/workflows/push-dotnet-build-test-pack-push-default.yml@v1 + uses: NetChris/workflows/.github/workflows/push-dotnet-build-test-pack-push-default.yml@v2 From 3937900e34b6e018b6b009f581014d97a19055e9 Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Sat, 22 Nov 2025 19:39:24 -0800 Subject: [PATCH 12/13] StoppedTimeProvider.GetTimestamp --- NetChris.Core/Time/StoppedTimeProvider.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NetChris.Core/Time/StoppedTimeProvider.cs b/NetChris.Core/Time/StoppedTimeProvider.cs index 6156114..264b3a0 100644 --- a/NetChris.Core/Time/StoppedTimeProvider.cs +++ b/NetChris.Core/Time/StoppedTimeProvider.cs @@ -34,4 +34,10 @@ public override DateTimeOffset GetUtcNow() { return _stoppedTime.ToUniversalTime(); } + + /// + public override long GetTimestamp() + { + return _stoppedTime.Ticks; + } } \ No newline at end of file From 6f300c168f3888ea5812144709a3d1d0c14b114f Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Sat, 22 Nov 2025 19:45:38 -0800 Subject: [PATCH 13/13] Remove test --- NetChris.Core.UnitTests/ApplicationMetadataTests.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/NetChris.Core.UnitTests/ApplicationMetadataTests.cs b/NetChris.Core.UnitTests/ApplicationMetadataTests.cs index d96352b..42a3080 100644 --- a/NetChris.Core.UnitTests/ApplicationMetadataTests.cs +++ b/NetChris.Core.UnitTests/ApplicationMetadataTests.cs @@ -88,17 +88,6 @@ public void ApplicationComponentShort_should_flow_through() applicationAggregate.Should().Be("eac"); } - [Fact] - public void ApplicationVersion_is_formatted_correctly() - { - // Arrange - // Act - var applicationVersion = _appMetadata.ApplicationVersion; - - // Assert - applicationVersion.Should().Be(new Version("1.2.3.0")); - } - [Fact] public void InformationalVersion_is_formatted_correctly() {