Skip to content

Commit 4c316a8

Browse files
committed
added MustBeUnspecified
1 parent f6b3dbc commit 4c316a8

4 files changed

Lines changed: 128 additions & 0 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
using BenchmarkDotNet.Attributes;
3+
using Light.GuardClauses.Exceptions;
4+
5+
namespace Light.GuardClauses.Performance.DateTimeAssertions
6+
{
7+
public class MustBeUnspecifiedBenchmark
8+
{
9+
public DateTime DateTime = new DateTime(2018, 2, 18, 16, 43, 00, DateTimeKind.Unspecified);
10+
11+
[Benchmark(Baseline = true)]
12+
public DateTime ImperativeVersion()
13+
{
14+
if (DateTime.Kind != DateTimeKind.Unspecified) throw new InvalidDateTimeException(nameof(DateTime));
15+
return DateTime;
16+
}
17+
18+
[Benchmark]
19+
public DateTime LightGuardClausesParameterName() => DateTime.MustBeUnspecified(nameof(DateTime));
20+
21+
[Benchmark]
22+
public DateTime LightGuardClausesCustomException() => DateTime.MustBeUnspecified(dt => new Exception($"{dt} is not unspecified"));
23+
24+
[Benchmark]
25+
public DateTime OldVersion() => DateTime.OldMustBeUnspecified(nameof(DateTime));
26+
}
27+
28+
public static class MustBeUnspecifiedExtensionMethods
29+
{
30+
public static DateTime OldMustBeUnspecified(this DateTime dateTime, string parameterName = null, string message = null, Func<Exception> exception = null)
31+
{
32+
if (dateTime.Kind == DateTimeKind.Unspecified) return dateTime;
33+
34+
throw exception != null ? exception() : new InvalidDateTimeException(parameterName, message ?? $"The specified date time \"{dateTime:O}\" must be of kind {DateTimeKind.Unspecified}, but actually is {dateTime.Kind}.");
35+
}
36+
}
37+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System;
2+
using FluentAssertions;
3+
using Light.GuardClauses.Exceptions;
4+
using Xunit;
5+
6+
namespace Light.GuardClauses.Tests.DateTimeAssertions
7+
{
8+
public static class MustBeUnspecifiedTests
9+
{
10+
[Fact]
11+
public static void NotUnspecified()
12+
{
13+
var invalidDateTime = DateTime.UtcNow;
14+
15+
Action act = () => invalidDateTime.MustBeUnspecified(nameof(invalidDateTime));
16+
17+
act.Should().Throw<InvalidDateTimeException>()
18+
.And.Message.Should().Contain($"{nameof(invalidDateTime)} must use kind \"{DateTimeKind.Unspecified}\", but it actually uses \"{invalidDateTime.Kind}\" and is \"{invalidDateTime:O}\".");
19+
}
20+
21+
[Fact]
22+
public static void Unspecified()
23+
{
24+
var dateTime = DateTime.MinValue;
25+
26+
var result = dateTime.MustBeUnspecified();
27+
28+
result.Should().Be(dateTime);
29+
}
30+
31+
[Fact]
32+
public static void CustomException() =>
33+
Test.CustomException(new DateTime(2018, 2, 18, 16, 57, 00, DateTimeKind.Utc),
34+
(value, exceptionFactory) => value.MustBeUnspecified(exceptionFactory));
35+
36+
[Fact]
37+
public static void NoCustomException()
38+
{
39+
var value = new DateTime(2000, 9, 10, 15, 32, 47, DateTimeKind.Unspecified);
40+
41+
var result = value.MustBeUnspecified(dt => null);
42+
43+
result.Should().Be(value);
44+
}
45+
46+
[Fact]
47+
public static void CustomMessage() =>
48+
Test.CustomMessage<InvalidDateTimeException>(message => DateTime.UtcNow.MustBeUnspecified(message: message));
49+
}
50+
}

Code/Light.GuardClauses/Check.DateTimeAssertions.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,39 @@ public static DateTime MustBeLocal(this DateTime parameter, Func<DateTime, Excep
7676
Throw.CustomException(exceptionFactory, parameter);
7777
return parameter;
7878
}
79+
80+
/// <summary>
81+
/// Ensures that the specified <paramref name="parameter"/> uses <see cref="DateTimeKind.Unspecified"/>, or otherwise throws an <see cref="InvalidDateTimeException"/>.
82+
/// </summary>
83+
/// <param name="parameter">The date time to be checked.</param>
84+
/// <param name="parameterName">The name of the parameter (optional).</param>
85+
/// <param name="message">The message that will be passed to the <see cref="InvalidDateTimeException"/> (optional).</param>
86+
/// <exception cref="InvalidDateTimeException">Thrown when <paramref name="parameter"/> does not use <see cref="DateTimeKind.Unspecified"/>.</exception>
87+
#if (NETSTANDARD2_0 || NETSTANDARD1_0 || NET45 || SILVERLIGHT)
88+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
89+
#endif
90+
public static DateTime MustBeUnspecified(this DateTime parameter, string parameterName = null, string message = null)
91+
{
92+
if (parameter.Kind != DateTimeKind.Unspecified)
93+
Throw.MustBeUnspecifiedDateTime(parameter, parameterName, message);
94+
return parameter;
95+
}
96+
97+
/// <summary>
98+
/// Ensures that the specified <paramref name="parameter"/> uses <see cref="DateTimeKind.Unspecified"/>, or otherwise throws your custom exception.
99+
/// </summary>
100+
/// <param name="parameter">The date time to be checked.</param>
101+
/// <param name="exceptionFactory">The delegate that creates your custom exception. <paramref name="parameter"/> is passed to this delegate.</param>
102+
/// <exception cref="Exception">Your custom exception thrown when <paramref name="parameter"/> does not use <see cref="DateTimeKind.Unspecified"/>.</exception>
103+
#if (NETSTANDARD2_0 || NETSTANDARD1_0 || NET45 || SILVERLIGHT)
104+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
105+
#endif
106+
[ContractAnnotation("exceptionFactory:null => halt")]
107+
public static DateTime MustBeUnspecified(this DateTime parameter, Func<DateTime, Exception> exceptionFactory)
108+
{
109+
if (parameter.Kind != DateTimeKind.Unspecified)
110+
Throw.CustomException(exceptionFactory, parameter);
111+
return parameter;
112+
}
79113
}
80114
}

Code/Light.GuardClauses/Exceptions/Throw.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,13 @@ public static void MustBeUtcDateTime(DateTime parameter, string parameterName =
363363
public static void MustBeLocalDateTime(DateTime parameter, string parameterName = null, string message = null) =>
364364
throw new InvalidDateTimeException(parameterName, message ?? $"{parameterName ?? "The date time"} must use kind \"{DateTimeKind.Local}\", but it actually uses \"{parameter.Kind}\" and is \"{parameter:O}\".");
365365

366+
/// <summary>
367+
/// Throws the default <see cref="InvalidDateTimeException" /> indicating that a date time is not using <see cref="DateTimeKind.Unspecified" />, using the optional parameter name and message.
368+
/// </summary>
369+
[ContractAnnotation("=> halt")]
370+
public static void MustBeUnspecifiedDateTime(DateTime parameter, string parameterName = null, string message = null) =>
371+
throw new InvalidDateTimeException(parameterName, message ?? $"{parameterName ?? "The date time"} must use kind \"{DateTimeKind.Unspecified}\", but it actually uses \"{parameter.Kind}\" and is \"{parameter:O}\".");
372+
366373
/// <summary>
367374
/// Throws the exception that is returned by <paramref name="exceptionFactory" />.
368375
/// </summary>

0 commit comments

Comments
 (0)