From f43aa1fdc3bfb63a5742a39f3648363999ff91d4 Mon Sep 17 00:00:00 2001 From: Chris Simmons Date: Sun, 25 May 2025 12:40:38 -0700 Subject: [PATCH 1/6] 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 2/6] 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 3/6] 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 4/6] 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 5/6] 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 6/6] 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