From e6388c95607a0a79ce4f794fc4de0e495aea2061 Mon Sep 17 00:00:00 2001 From: Amal Krishna Date: Mon, 31 Jul 2023 19:59:05 +0530 Subject: [PATCH 1/7] Make type parameter T of the Null() method nullable and add overload for value types. (#261) * Add nullable annotation "?" to T of Null() to supress null warnings on returned value. * Add overload of Null() with generic constraint for value types to allow assignment of return value to non-nullable value types when passed a nullable value type. * Add unit tests to ensure that Null() returns a non-nullable value type when passed a nullable value type * Update GuardClauses.csproj * Update GuardClauses.UnitTests.csproj * Revert "Update to dotnet 7.0" --------- Co-authored-by: amalkrishna Co-authored-by: Steve Smith --- .../GuardAgainstNullExtensions.cs | 41 +++++++++++++++++-- .../GuardAgainstNull.cs | 35 ++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/GuardClauses/GuardAgainstNullExtensions.cs b/src/GuardClauses/GuardAgainstNullExtensions.cs index 127b94f4..eeb79d82 100644 --- a/src/GuardClauses/GuardAgainstNullExtensions.cs +++ b/src/GuardClauses/GuardAgainstNullExtensions.cs @@ -25,12 +25,12 @@ public static partial class GuardClauseExtensions /// if the value is not null. #if NETSTANDARD || NETFRAMEWORK public static T Null(this IGuardClause guardClause, - [NotNull][ValidatedNotNull] T input, + [NotNull][ValidatedNotNull] T? input, string parameterName, string? message = null) #else public static T Null(this IGuardClause guardClause, - [NotNull][ValidatedNotNull]T input, + [NotNull][ValidatedNotNull]T? input, [CallerArgumentExpression("input")] string? parameterName = null, string? message = null) #endif @@ -47,6 +47,39 @@ public static T Null(this IGuardClause guardClause, return input; } + /// + /// Throws an if is null. + /// + /// Must be a value type. + /// + /// + /// + /// Optional. Custom error message + /// if the value is not null. +#if NETSTANDARD || NETFRAMEWORK + public static T Null(this IGuardClause guardClause, + [NotNull][ValidatedNotNull] T? input, + string parameterName, + string? message = null) where T : struct +#else + public static T Null(this IGuardClause guardClause, + [NotNull][ValidatedNotNull]T? input, + [CallerArgumentExpression("input")] string? parameterName = null, + string? message = null) where T : struct +#endif + { + if (input is null) + { + if (string.IsNullOrEmpty(message)) + { + throw new ArgumentNullException(parameterName); + } + throw new ArgumentNullException(parameterName, message); + } + + return input.Value; + } + /// /// Throws an if is null. /// Throws an if is an empty string. @@ -220,13 +253,13 @@ public static T Default(this IGuardClause guardClause, /// #if NETSTANDARD || NETFRAMEWORK public static T NullOrInvalidInput(this IGuardClause guardClause, - T input, + [NotNull] T? input, string parameterName, Func predicate, string? message = null) #else public static T NullOrInvalidInput(this IGuardClause guardClause, - T input, + [NotNull] T? input, string parameterName, Func predicate, string? message = null) diff --git a/test/GuardClauses.UnitTests/GuardAgainstNull.cs b/test/GuardClauses.UnitTests/GuardAgainstNull.cs index b889cf99..149cdaf1 100644 --- a/test/GuardClauses.UnitTests/GuardAgainstNull.cs +++ b/test/GuardClauses.UnitTests/GuardAgainstNull.cs @@ -39,6 +39,41 @@ public void ReturnsExpectedValueWhenGivenNonNullValue() Assert.Equal(obj, Guard.Against.Null(obj, "object")); } + [Fact] + public void ReturnsNonNullableValueTypeWhenGivenNullableValueTypeIsNotNull() + { + int? @int = 4; + Assert.False(IsNullableType(Guard.Against.Null(@int, "int"))); + + double? @double = 11.11; + Assert.False(IsNullableType(Guard.Against.Null(@double, "@double"))); + + DateTime? now = DateTime.Now; + Assert.False(IsNullableType(Guard.Against.Null(now, "now"))); + + Guid? guid = Guid.Empty; + Assert.False(IsNullableType(Guard.Against.Null(guid, "guid"))); + + static bool IsNullableType(T value) + { + if (value is null) + { + return false; + } + Type type = typeof(T); + if (!type.IsValueType) + { + return true; + } + if (Nullable.GetUnderlyingType(type) != null) + { + return true; + } + return false; + + } + } + [Theory] [InlineData(null, "Value cannot be null. (Parameter 'parameterName')")] [InlineData("Please provide correct value", "Please provide correct value (Parameter 'parameterName')")] From 42162fdbda2ab76ca3b98aee7e83eb0d9aac66d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:29:56 -0400 Subject: [PATCH 2/7] Bump altcover from 8.6.14 to 8.6.68 (#287) Bumps [altcover](https://github.com/SteveGilham/altcover) from 8.6.14 to 8.6.68. - [Release notes](https://github.com/SteveGilham/altcover/releases) - [Changelog](https://github.com/SteveGilham/altcover/blob/master/ReleaseNotes.md) - [Commits](https://github.com/SteveGilham/altcover/compare/release/v8.6.14...release/v8.6.68) --- updated-dependencies: - dependency-name: altcover dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Steve Smith --- test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj b/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj index f27e967e..d7f19232 100644 --- a/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj +++ b/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj @@ -7,7 +7,7 @@ - + runtime; build; native; contentfiles; analyzers all From 87948938af389d274610c812b64a0fd3ccc9d49d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:30:22 -0400 Subject: [PATCH 3/7] Bump xunit from 2.4.2 to 2.5.0 (#286) Bumps [xunit](https://github.com/xunit/xunit) from 2.4.2 to 2.5.0. - [Commits](https://github.com/xunit/xunit/compare/2.4.2...2.5.0) --- updated-dependencies: - dependency-name: xunit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Steve Smith --- test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj b/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj index d7f19232..6f74c4ae 100644 --- a/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj +++ b/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj @@ -18,7 +18,7 @@ - + From 03ca8988b246feb19b38fe98bb17375fbd3e19b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:31:11 -0400 Subject: [PATCH 4/7] Bump xunit.runner.visualstudio from 2.4.5 to 2.5.0 (#285) Bumps [xunit.runner.visualstudio](https://github.com/xunit/visualstudio.xunit) from 2.4.5 to 2.5.0. - [Release notes](https://github.com/xunit/visualstudio.xunit/releases) - [Commits](https://github.com/xunit/visualstudio.xunit/compare/v2.4.5...2.5.0) --- updated-dependencies: - dependency-name: xunit.runner.visualstudio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj b/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj index 6f74c4ae..cf9f3fdf 100644 --- a/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj +++ b/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj @@ -19,7 +19,7 @@ - + From 15df3eb720f376acc6b537179b45433341cbe3b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:31:39 -0400 Subject: [PATCH 5/7] Bump ReportGenerator from 5.1.22 to 5.1.23 (#284) Bumps [ReportGenerator](https://github.com/danielpalme/ReportGenerator) from 5.1.22 to 5.1.23. - [Release notes](https://github.com/danielpalme/ReportGenerator/releases) - [Commits](https://github.com/danielpalme/ReportGenerator/compare/v5.1.22...v5.1.23) --- updated-dependencies: - dependency-name: ReportGenerator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Steve Smith --- test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj b/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj index cf9f3fdf..5c8ab5d7 100644 --- a/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj +++ b/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj @@ -17,7 +17,7 @@ all - + From b0d105996b97d63d76e665a4ac8c18a7b724d33a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Nuno=20Mota?= Date: Mon, 31 Jul 2023 15:33:41 +0100 Subject: [PATCH 6/7] Add tests removed due to bug in previous xunit versions (#276) Co-authored-by: Steve Smith --- .../GuardAgainstOutOfRangeForInvalidInput.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/GuardClauses.UnitTests/GuardAgainstOutOfRangeForInvalidInput.cs b/test/GuardClauses.UnitTests/GuardAgainstOutOfRangeForInvalidInput.cs index 49515654..98e654ba 100644 --- a/test/GuardClauses.UnitTests/GuardAgainstOutOfRangeForInvalidInput.cs +++ b/test/GuardClauses.UnitTests/GuardAgainstOutOfRangeForInvalidInput.cs @@ -100,8 +100,6 @@ public async Task ExceptionParamNameMatchesExpectedAsync(string expectedParamNam Assert.Equal(expectedParamName, exception.ParamName); } - // TODO: Test decimal types outside of ClassData - // See: https://github.com/xunit/xunit/issues/2298 public class CorrectClassData : IEnumerable { public IEnumerator GetEnumerator() @@ -109,7 +107,7 @@ public IEnumerator GetEnumerator() yield return new object[] { 20, (Func)((x) => x > 10) }; yield return new object[] { DateAndTime.Now, (Func)((x) => x > DateTime.MinValue) }; yield return new object[] { 20.0f, (Func)((x) => x > 10.0f) }; - //yield return new object[] { 20.0m, (Func)((x) => x > 10.0m) }; + yield return new object[] { 20.0m, (Func)((x) => x > 10.0m) }; yield return new object[] { 20.0, (Func)((x) => x > 10.0) }; yield return new object[] { long.MaxValue, (Func)((x) => x > 1) }; yield return new object[] { short.MaxValue, (Func)((x) => x > 1) }; @@ -125,7 +123,7 @@ public IEnumerator GetEnumerator() yield return new object[] { 20, (Func>)((x) => Task.FromResult(x > 10)) }; yield return new object[] { DateAndTime.Now, (Func>)((x) => Task.FromResult(x > DateTime.MinValue)) }; yield return new object[] { 20.0f, (Func>)((x) => Task.FromResult(x > 10.0f)) }; - //yield return new object[] { 20.0m, (Func>)((x) => Task.FromResult(x > 10.0m)) }; + yield return new object[] { 20.0m, (Func>)((x) => Task.FromResult(x > 10.0m)) }; yield return new object[] { 20.0, (Func>)((x) => Task.FromResult(x > 10.0)) }; yield return new object[] { long.MaxValue, (Func>)((x) => Task.FromResult(x > 1)) }; yield return new object[] { short.MaxValue, (Func>)((x) => Task.FromResult(x > 1)) }; @@ -141,7 +139,7 @@ public IEnumerator GetEnumerator() yield return new object[] { 20, (Func)((x) => x < 10) }; yield return new object[] { DateAndTime.Now, (Func)((x) => x > DateTime.MaxValue) }; yield return new object[] { 20.0f, (Func)((x) => x > 30.0f) }; - //yield return new object[] { 20.0m, (Func)((x) => x > 30.0m) }; + yield return new object[] { 20.0m, (Func)((x) => x > 30.0m) }; yield return new object[] { 20.0, (Func)((x) => x > 30.0) }; yield return new object[] { long.MaxValue, (Func)((x) => x < 1) }; yield return new object[] { short.MaxValue, (Func)((x) => x < 1) }; @@ -158,7 +156,7 @@ public IEnumerator GetEnumerator() yield return new object[] { 20, (Func>)((x) => Task.FromResult(x < 10)) }; yield return new object[] { DateAndTime.Now, (Func>)((x) => Task.FromResult(x > DateTime.MaxValue)) }; yield return new object[] { 20.0f, (Func>)((x) => Task.FromResult(x > 30.0f)) }; - //yield return new object[] { 20.0m, (Func)((x) => x > 30.0m)) }; + yield return new object[] { 20.0m, (Func>)((x) => Task.FromResult(x > 30.0m)) }; yield return new object[] { 20.0, (Func>)((x) => Task.FromResult(x > 30.0)) }; yield return new object[] { long.MaxValue, (Func>)((x) => Task.FromResult(x < 1)) }; yield return new object[] { short.MaxValue, (Func>)((x) => Task.FromResult(x < 1)) }; From 322d1faadc90cffc89087c3a536dfc92d5643745 Mon Sep 17 00:00:00 2001 From: Amal Krishna Date: Mon, 31 Jul 2023 20:07:52 +0530 Subject: [PATCH 7/7] Upgrade to dotnet 7.0 (#282) * Update target framework from net6.0 to net7.0 * Update target framework from net6.0 to net7.0 * Update LangVersion to 11 * Update LangVersion from 10 to 11 --------- Co-authored-by: Steve Smith --- Directory.Build.props | 2 +- src/GuardClauses/GuardClauses.csproj | 2 +- test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 35b2f622..4591a011 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - 10 + 11 enable diff --git a/src/GuardClauses/GuardClauses.csproj b/src/GuardClauses/GuardClauses.csproj index c308a0d1..927dc56a 100644 --- a/src/GuardClauses/GuardClauses.csproj +++ b/src/GuardClauses/GuardClauses.csproj @@ -6,7 +6,7 @@ - netstandard2.0;net60 + netstandard2.0;net7.0 Ardalis.GuardClauses Ardalis.GuardClauses true diff --git a/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj b/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj index 5c8ab5d7..3cad62ff 100644 --- a/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj +++ b/test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj @@ -1,9 +1,9 @@ - net6.0 + net7.0 false - 10 + 11