Skip to content

Commit 8dc370d

Browse files
Add ArgHelper utility to perform argument validation
Add `ArgHelper`, which contains methods that mimic the .NET 8+ APIs: `ArgumentNullException.Throw*`, `ArgumentException.Throw*`, and `ArgumentOutOfRangeException.Throw*`. On .NET 8+, the `ArgHelper` APIs delegate to the .NET APIs. However, on other TFMs, they provide a similar implementation.
1 parent caa579d commit 8dc370d

File tree

17 files changed

+1176
-0
lines changed

17 files changed

+1176
-0
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT license. See License.txt in the project root for license information.
3+
4+
using System;
5+
using Xunit;
6+
7+
namespace Microsoft.AspNetCore.Razor.Utilities.Shared.Test;
8+
9+
public class ArgHelperTests
10+
{
11+
[Theory]
12+
[InlineData(null, typeof(ArgumentNullException))]
13+
[InlineData("test")]
14+
public void ThrowIfNull(string? s, Type? exceptionType = null)
15+
{
16+
Verify(() => ArgHelper.ThrowIfNull(s), exceptionType);
17+
}
18+
19+
[Fact]
20+
public unsafe void ThrowIfNull_NullPtr_Throws()
21+
{
22+
byte* ptr = null;
23+
24+
Assert.Throws<ArgumentNullException>(() =>
25+
{
26+
ArgHelper.ThrowIfNull(ptr);
27+
});
28+
}
29+
30+
[Fact]
31+
public unsafe void ThrowIfNull_Ptr_DoesNotThrow()
32+
{
33+
fixed (byte* ptr = new byte[8])
34+
{
35+
ArgHelper.ThrowIfNull(ptr);
36+
}
37+
}
38+
39+
[Theory]
40+
[InlineData(null, typeof(ArgumentNullException))]
41+
[InlineData("", typeof(ArgumentException))]
42+
[InlineData(" ")]
43+
[InlineData("test")]
44+
public void ThrowIfNullOrEmpty(string? s, Type? exceptionType = null)
45+
{
46+
Verify(() => ArgHelper.ThrowIfNullOrEmpty(s), exceptionType);
47+
}
48+
49+
[Theory]
50+
[InlineData(null, typeof(ArgumentNullException))]
51+
[InlineData("", typeof(ArgumentException))]
52+
[InlineData(" ", typeof(ArgumentException))]
53+
[InlineData("test")]
54+
public void ThrowIfNullOrWhiteSpace(string? s, Type? exceptionType = null)
55+
{
56+
Verify(() => ArgHelper.ThrowIfNullOrWhiteSpace(s), exceptionType);
57+
}
58+
59+
[Theory]
60+
[InlineData(null, null, typeof(ArgumentOutOfRangeException))]
61+
[InlineData(null, "test")]
62+
[InlineData("test", null)]
63+
[InlineData("test", "test", typeof(ArgumentOutOfRangeException))]
64+
[InlineData("test", "TeSt")]
65+
public void ThrowIfEqual(string? s1, string? s2, Type? exceptionType = null)
66+
{
67+
Verify(() => ArgHelper.ThrowIfEqual(s1, s2), exceptionType);
68+
}
69+
70+
[Theory]
71+
[InlineData(null, null)]
72+
[InlineData(null, "test", typeof(ArgumentOutOfRangeException))]
73+
[InlineData("test", null, typeof(ArgumentOutOfRangeException))]
74+
[InlineData("test", "test")]
75+
[InlineData("test", "TeSt", typeof(ArgumentOutOfRangeException))]
76+
public void ThrowIfNotEqual(string? s1, string? s2, Type? exceptionType = null)
77+
{
78+
Verify(() => ArgHelper.ThrowIfNotEqual(s1, s2), exceptionType);
79+
}
80+
81+
[Theory]
82+
[InlineData(0, typeof(ArgumentOutOfRangeException))]
83+
[InlineData(-1)]
84+
[InlineData(1)]
85+
public void ThrowIfZero(int v, Type? exceptionType = null)
86+
{
87+
Verify(() => ArgHelper.ThrowIfZero(v), exceptionType);
88+
}
89+
90+
[Theory]
91+
[InlineData(0)]
92+
[InlineData(-1, typeof(ArgumentOutOfRangeException))]
93+
[InlineData(1)]
94+
public void ThrowIfNegative(int v, Type? exceptionType = null)
95+
{
96+
Verify(() => ArgHelper.ThrowIfNegative(v), exceptionType);
97+
}
98+
99+
[Theory]
100+
[InlineData(0, typeof(ArgumentOutOfRangeException))]
101+
[InlineData(-1, typeof(ArgumentOutOfRangeException))]
102+
[InlineData(1)]
103+
public void ThrowIfNegativeOrZero(int v, Type? exceptionType = null)
104+
{
105+
Verify(() => ArgHelper.ThrowIfNegativeOrZero(v), exceptionType);
106+
}
107+
108+
[Theory]
109+
[InlineData(42, 42)]
110+
[InlineData(41, 42)]
111+
[InlineData(43, 42, typeof(ArgumentOutOfRangeException))]
112+
public void ThrowIfGreaterThan(int v1, int v2, Type? exceptionType = null)
113+
{
114+
Verify(() => ArgHelper.ThrowIfGreaterThan(v1, v2), exceptionType);
115+
}
116+
117+
[Theory]
118+
[InlineData(42, 42, typeof(ArgumentOutOfRangeException))]
119+
[InlineData(41, 42)]
120+
[InlineData(43, 42, typeof(ArgumentOutOfRangeException))]
121+
public void ThrowIfGreaterThanOrEqual(int v1, int v2, Type? exceptionType = null)
122+
{
123+
Verify(() => ArgHelper.ThrowIfGreaterThanOrEqual(v1, v2), exceptionType);
124+
}
125+
126+
[Theory]
127+
[InlineData(42, 42)]
128+
[InlineData(41, 42, typeof(ArgumentOutOfRangeException))]
129+
[InlineData(43, 42)]
130+
public void ThrowIfLessThan(int v1, int v2, Type? exceptionType = null)
131+
{
132+
Verify(() => ArgHelper.ThrowIfLessThan(v1, v2), exceptionType);
133+
}
134+
135+
[Theory]
136+
[InlineData(42, 42, typeof(ArgumentOutOfRangeException))]
137+
[InlineData(41, 42, typeof(ArgumentOutOfRangeException))]
138+
[InlineData(43, 42)]
139+
public void ThrowIfLessThanOrEqual(int v1, int v2, Type? exceptionType = null)
140+
{
141+
Verify(() => ArgHelper.ThrowIfLessThanOrEqual(v1, v2), exceptionType);
142+
}
143+
144+
private static void Verify(Action a, Type? exceptionType = null)
145+
{
146+
if (exceptionType is not null)
147+
{
148+
Assert.Throws(exceptionType, a);
149+
}
150+
else
151+
{
152+
a();
153+
}
154+
}
155+
}

src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared.Test/Microsoft.AspNetCore.Razor.Utilities.Shared.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<PropertyGroup>
44
<TargetFrameworks>$(DefaultNetCoreTargetFrameworks)</TargetFrameworks>
55
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);$(DefaultNetFxTargetFramework)</TargetFrameworks>
6+
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
67
</PropertyGroup>
78

89
<ItemGroup>

0 commit comments

Comments
 (0)