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 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() { 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.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 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 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 diff --git a/NetChris.Core/Values/SimpleResult.cs b/NetChris.Core/Values/SimpleResult.cs index 40ab585..627a0ad 100644 --- a/NetChris.Core/Values/SimpleResult.cs +++ b/NetChris.Core/Values/SimpleResult.cs @@ -1,7 +1,9 @@ -namespace NetChris.Core.Values; +using System; + +namespace NetChris.Core.Values; /// -/// Lightweight object with an code and message. +/// Lightweight object with a code and message. /// A glorified key/value pair. /// /// @@ -10,34 +12,51 @@ /// or throw errors with unique-ish codes and an explanatory message. /// /// +[Obsolete] public class SimpleResult { /// - /// Gets the code + /// The result type /// - /// The result code - public string ResultCode + /// + /// This is implemented as a to communicate that the result is of a unique type + /// + public Uri ResultType { get; } /// - /// Gets the message. + /// The message /// - /// 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 code + /// The result type /// The message - public SimpleResult(string resultCode, string message) + /// Whether the message can be publicly displayed + public SimpleResult(Uri resultType, string message, bool isPublic = true) { - ResultCode = resultCode; + ResultType = resultType; Message = message; + IsPublic = isPublic; } } \ No newline at end of file diff --git a/README.md b/README.md index b7d91f3..b4a99a7 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 `5,000,000` through `5,999,999` for use by such purposes as: + +- Event IDs +- Advisory lock numbers