Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/nuget/Microsoft.NET.Test.Sdk-17.6.3
Browse files Browse the repository at this point in the history
  • Loading branch information
ardalis committed Jul 31, 2023
2 parents a80d3b9 + 322d1fa commit b7c80e9
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>

<PropertyGroup>
<LangVersion>10</LangVersion>
<LangVersion>11</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

Expand Down
41 changes: 37 additions & 4 deletions src/GuardClauses/GuardAgainstNullExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ public static partial class GuardClauseExtensions
/// <returns><paramref name="input" /> if the value is not null.</returns>
#if NETSTANDARD || NETFRAMEWORK
public static T Null<T>(this IGuardClause guardClause,
[NotNull][ValidatedNotNull] T input,
[NotNull][ValidatedNotNull] T? input,
string parameterName,
string? message = null)
#else
public static T Null<T>(this IGuardClause guardClause,
[NotNull][ValidatedNotNull]T input,
[NotNull][ValidatedNotNull]T? input,
[CallerArgumentExpression("input")] string? parameterName = null,
string? message = null)
#endif
Expand All @@ -47,6 +47,39 @@ public static T Null<T>(this IGuardClause guardClause,
return input;
}

/// <summary>
/// Throws an <see cref="ArgumentNullException" /> if <paramref name="input" /> is null.
/// </summary>
/// <typeparam name="T">Must be a value type.</typeparam>
/// <param name="guardClause"></param>
/// <param name="input"></param>
/// <param name="parameterName"></param>
/// <param name="message">Optional. Custom error message</param>
/// <returns><paramref name="input" /> if the value is not null.</returns>
#if NETSTANDARD || NETFRAMEWORK
public static T Null<T>(this IGuardClause guardClause,
[NotNull][ValidatedNotNull] T? input,
string parameterName,
string? message = null) where T : struct
#else
public static T Null<T>(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;
}

/// <summary>
/// Throws an <see cref="ArgumentNullException" /> if <paramref name="input" /> is null.
/// Throws an <see cref="ArgumentException" /> if <paramref name="input" /> is an empty string.
Expand Down Expand Up @@ -220,13 +253,13 @@ public static T Default<T>(this IGuardClause guardClause,
/// <exception cref="ArgumentNullException"></exception>
#if NETSTANDARD || NETFRAMEWORK
public static T NullOrInvalidInput<T>(this IGuardClause guardClause,
T input,
[NotNull] T? input,
string parameterName,
Func<T, bool> predicate,
string? message = null)
#else
public static T NullOrInvalidInput<T>(this IGuardClause guardClause,
T input,
[NotNull] T? input,
string parameterName,
Func<T, bool> predicate,
string? message = null)
Expand Down
2 changes: 1 addition & 1 deletion src/GuardClauses/GuardClauses.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<None Include="..\..\LICENSE" Pack="true" PackagePath="" />
</ItemGroup>
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net60</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net7.0</TargetFrameworks>
<PackageId>Ardalis.GuardClauses</PackageId>
<Title>Ardalis.GuardClauses</Title>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
Expand Down
35 changes: 35 additions & 0 deletions test/GuardClauses.UnitTests/GuardAgainstNull.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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>(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')")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,14 @@ 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<object[]>
{
public IEnumerator<object[]> GetEnumerator()
{
yield return new object[] { 20, (Func<int, bool>)((x) => x > 10) };
yield return new object[] { DateAndTime.Now, (Func<DateTime, bool>)((x) => x > DateTime.MinValue) };
yield return new object[] { 20.0f, (Func<float, bool>)((x) => x > 10.0f) };
//yield return new object[] { 20.0m, (Func<decimal, bool>)((x) => x > 10.0m) };
yield return new object[] { 20.0m, (Func<decimal, bool>)((x) => x > 10.0m) };
yield return new object[] { 20.0, (Func<double, bool>)((x) => x > 10.0) };
yield return new object[] { long.MaxValue, (Func<long, bool>)((x) => x > 1) };
yield return new object[] { short.MaxValue, (Func<short, bool>)((x) => x > 1) };
Expand All @@ -125,7 +123,7 @@ public IEnumerator<object[]> GetEnumerator()
yield return new object[] { 20, (Func<int, Task<bool>>)((x) => Task.FromResult(x > 10)) };
yield return new object[] { DateAndTime.Now, (Func<DateTime, Task<bool>>)((x) => Task.FromResult(x > DateTime.MinValue)) };
yield return new object[] { 20.0f, (Func<float, Task<bool>>)((x) => Task.FromResult(x > 10.0f)) };
//yield return new object[] { 20.0m, (Func<decimal, Task<bool>>)((x) => Task.FromResult(x > 10.0m)) };
yield return new object[] { 20.0m, (Func<decimal, Task<bool>>)((x) => Task.FromResult(x > 10.0m)) };
yield return new object[] { 20.0, (Func<double, Task<bool>>)((x) => Task.FromResult(x > 10.0)) };
yield return new object[] { long.MaxValue, (Func<long, Task<bool>>)((x) => Task.FromResult(x > 1)) };
yield return new object[] { short.MaxValue, (Func<short, Task<bool>>)((x) => Task.FromResult(x > 1)) };
Expand All @@ -141,7 +139,7 @@ public IEnumerator<object[]> GetEnumerator()
yield return new object[] { 20, (Func<int, bool>)((x) => x < 10) };
yield return new object[] { DateAndTime.Now, (Func<DateTime, bool>)((x) => x > DateTime.MaxValue) };
yield return new object[] { 20.0f, (Func<float, bool>)((x) => x > 30.0f) };
//yield return new object[] { 20.0m, (Func<decimal, bool>)((x) => x > 30.0m) };
yield return new object[] { 20.0m, (Func<decimal, bool>)((x) => x > 30.0m) };
yield return new object[] { 20.0, (Func<double, bool>)((x) => x > 30.0) };
yield return new object[] { long.MaxValue, (Func<long, bool>)((x) => x < 1) };
yield return new object[] { short.MaxValue, (Func<short, bool>)((x) => x < 1) };
Expand All @@ -158,7 +156,7 @@ public IEnumerator<object[]> GetEnumerator()
yield return new object[] { 20, (Func<int, Task<bool>>)((x) => Task.FromResult(x < 10)) };
yield return new object[] { DateAndTime.Now, (Func<DateTime, Task<bool>>)((x) => Task.FromResult(x > DateTime.MaxValue)) };
yield return new object[] { 20.0f, (Func<float, Task<bool>>)((x) => Task.FromResult(x > 30.0f)) };
//yield return new object[] { 20.0m, (Func<decimal, bool>)((x) => x > 30.0m)) };
yield return new object[] { 20.0m, (Func<decimal, Task<bool>>)((x) => Task.FromResult(x > 30.0m)) };
yield return new object[] { 20.0, (Func<double, Task<bool>>)((x) => Task.FromResult(x > 30.0)) };
yield return new object[] { long.MaxValue, (Func<long, Task<bool>>)((x) => Task.FromResult(x < 1)) };
yield return new object[] { short.MaxValue, (Func<short, Task<bool>>)((x) => Task.FromResult(x < 1)) };
Expand Down
14 changes: 8 additions & 6 deletions test/GuardClauses.UnitTests/GuardClauses.UnitTests.csproj
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>10</LangVersion>
<LangVersion>11</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="altcover" Version="8.6.14" />
<PackageReference Include="altcover" Version="8.6.68" />
<PackageReference Include="coverlet.msbuild" Version="3.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand All @@ -16,10 +16,12 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>

<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageReference Include="ReportGenerator" Version="5.1.22" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" />
<PackageReference Include="ReportGenerator" Version="5.1.23" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0" />

</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit b7c80e9

Please sign in to comment.