Skip to content

Commit b558999

Browse files
committed
fix: MustHaveMaximumLength for ImmutableArray<T> if block is now correct, adjusted default exception message
Signed-off-by: Kenny Pflug <kenny.pflug@live.de>
1 parent f4c6da1 commit b558999

File tree

3 files changed

+88
-4
lines changed

3 files changed

+88
-4
lines changed

Code/Light.GuardClauses.Tests/CollectionAssertions/MustHaveMaximumLengthTests.cs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public static void ImmutableArrayMoreItems(int[] items, int length)
1919

2020
var assertion = act.Should().Throw<InvalidCollectionCountException>().Which;
2121
assertion.Message.Should().Contain(
22-
$"{nameof(immutableArray)} must have at most count {length}, but it actually has count {immutableArray.Length}."
22+
$"{nameof(immutableArray)} must have at most a length of {length}, but it actually has a length of {immutableArray.Length}."
2323
);
2424
assertion.ParamName.Should().BeSameAs(nameof(immutableArray));
2525
}
@@ -87,4 +87,54 @@ public static void ImmutableArrayCallerArgumentExpression()
8787
act.Should().Throw<InvalidCollectionCountException>()
8888
.WithParameterName(nameof(myImmutableArray));
8989
}
90+
91+
[Theory]
92+
[InlineData(0)]
93+
[InlineData(1)]
94+
[InlineData(5)]
95+
public static void
96+
DefaultImmutableArrayInstanceShouldNotThrowWhenLengthIsGreaterThanOrEqualToZero(int validLength) =>
97+
default(ImmutableArray<int>).MustHaveMaximumLength(validLength).IsDefault.Should().BeTrue();
98+
99+
[Theory]
100+
[InlineData(-1)]
101+
[InlineData(-5)]
102+
[InlineData(-12)]
103+
public static void DefaultImmutableArrayInstanceShouldNotThrowWhenLengthIsNegative(int negativeLength)
104+
{
105+
var act = () => default(ImmutableArray<int>).MustHaveMaximumLength(negativeLength);
106+
107+
act.Should().Throw<InvalidCollectionCountException>()
108+
.WithParameterName("default(ImmutableArray<int>)")
109+
.WithMessage(
110+
$"default(ImmutableArray<int>) must have at most a length of {negativeLength}, but it actually has no length because it is the default instance.*"
111+
);
112+
}
113+
114+
[Theory]
115+
[InlineData(0)]
116+
[InlineData(1)]
117+
[InlineData(5)]
118+
public static void DefaultImmutableArrayInstanceCustomExceptionShouldNotThrow(int validLength)
119+
{
120+
var result = default(ImmutableArray<int>).MustHaveMaximumLength(validLength, (_, _) => new Exception());
121+
result.IsDefault.Should().BeTrue();
122+
}
123+
124+
[Theory]
125+
[InlineData(-1)]
126+
[InlineData(-5)]
127+
[InlineData(-12)]
128+
public static void DefaultImmutableArrayInstanceCustomExceptionShouldThrow(int negativeLength)
129+
{
130+
var act = () => default(ImmutableArray<int>).MustHaveMaximumLength(
131+
negativeLength,
132+
(array, length) => new ArgumentException(
133+
$"Custom: Array length {(array.IsDefault ? 0 : array.Length)} exceeds maximum {length}"
134+
)
135+
);
136+
137+
act.Should().Throw<ArgumentException>()
138+
.WithMessage("Custom: Array length 0 exceeds maximum *");
139+
}
90140
}

Code/Light.GuardClauses/Check.MustHaveMaximumLength.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public static partial class Check
1616
/// <param name="parameterName">The name of the parameter (optional).</param>
1717
/// <param name="message">The message that will be passed to the resulting exception (optional).</param>
1818
/// <exception cref="InvalidCollectionCountException">Thrown when <paramref name="parameter" /> has more than the specified length.</exception>
19+
/// <remarks>The default instance of <see cref="ImmutableArray{T}"/> will be treated as having length 0.</remarks>
1920
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2021
public static ImmutableArray<T> MustHaveMaximumLength<T>(
2122
this ImmutableArray<T> parameter,
@@ -24,9 +25,10 @@ public static ImmutableArray<T> MustHaveMaximumLength<T>(
2425
string? message = null
2526
)
2627
{
27-
if (parameter.IsDefault && length < 0 || parameter.Length > length)
28+
var parameterLength = parameter.IsDefault ? 0 : parameter.Length;
29+
if (parameterLength > length)
2830
{
29-
Throw.InvalidMaximumCollectionCount(parameter, length, parameterName, message);
31+
Throw.InvalidMaximumImmutableArrayLength(parameter, length, parameterName, message);
3032
}
3133

3234
return parameter;
@@ -39,14 +41,16 @@ public static ImmutableArray<T> MustHaveMaximumLength<T>(
3941
/// <param name="length">The maximum length the <see cref="ImmutableArray{T}" /> should have.</param>
4042
/// <param name="exceptionFactory">The delegate that creates your custom exception. <paramref name="parameter" /> and <paramref name="length" /> are passed to this delegate.</param>
4143
/// <exception cref="Exception">Your custom exception thrown when <paramref name="parameter" /> has more than the specified length.</exception>
44+
/// <remarks>The default instance of <see cref="ImmutableArray{T}"/> will be treated as having length 0.</remarks>
4245
[MethodImpl(MethodImplOptions.AggressiveInlining)]
4346
public static ImmutableArray<T> MustHaveMaximumLength<T>(
4447
this ImmutableArray<T> parameter,
4548
int length,
4649
Func<ImmutableArray<T>, int, Exception> exceptionFactory
4750
)
4851
{
49-
if (parameter.IsDefault && length < 0 || parameter.Length > length)
52+
var parameterLength = parameter.IsDefault ? 0 : parameter.Length;
53+
if (parameterLength > length)
5054
{
5155
Throw.CustomException(exceptionFactory, parameter, length);
5256
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System.Collections.Immutable;
2+
using System.Diagnostics.CodeAnalysis;
3+
using System.Runtime.CompilerServices;
4+
using JetBrains.Annotations;
5+
using Light.GuardClauses.Exceptions;
6+
7+
namespace Light.GuardClauses.ExceptionFactory;
8+
9+
public static partial class Throw
10+
{
11+
/// <summary>
12+
/// Throws the default <see cref="InvalidCollectionCountException" /> indicating that an <see cref="ImmutableArray{T}" /> has more than a
13+
/// maximum number of items, using the optional parameter name and message.
14+
/// </summary>
15+
[ContractAnnotation("=> halt")]
16+
[DoesNotReturn]
17+
public static void InvalidMaximumImmutableArrayLength<T>(
18+
ImmutableArray<T> parameter,
19+
int length,
20+
[CallerArgumentExpression("parameter")] string? parameterName = null,
21+
string? message = null
22+
)
23+
{
24+
throw new InvalidCollectionCountException(
25+
parameterName,
26+
message ??
27+
$"{parameterName ?? "The immutable array"} must have at most a length of {length}, but it actually {(parameter.IsDefault ? "has no length because it is the default instance" : $"has a length of {parameter.Length}")}."
28+
);
29+
}
30+
}

0 commit comments

Comments
 (0)