From 79c8916560123fe92298be002346cff4fb80aaf3 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 28 Aug 2020 19:19:50 +0200 Subject: [PATCH 1/3] Added generic ThrowHelper APIs --- .../Diagnostics/ThrowHelper.Generic.cs | 811 ++++++++++++++++++ 1 file changed, 811 insertions(+) create mode 100644 Microsoft.Toolkit/Diagnostics/ThrowHelper.Generic.cs diff --git a/Microsoft.Toolkit/Diagnostics/ThrowHelper.Generic.cs b/Microsoft.Toolkit/Diagnostics/ThrowHelper.Generic.cs new file mode 100644 index 00000000000..9a1ed504fa6 --- /dev/null +++ b/Microsoft.Toolkit/Diagnostics/ThrowHelper.Generic.cs @@ -0,0 +1,811 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.IO; +#if !NETSTANDARD1_4 +using System.Runtime.InteropServices; +#endif +using System.Threading; + +#nullable enable + +namespace Microsoft.Toolkit.Diagnostics +{ + /// + /// Helper methods to efficiently throw exceptions. + /// + public static partial class ThrowHelper + { + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArrayTypeMismatchException(string message) + { + throw new ArrayTypeMismatchException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArrayTypeMismatchException(string message, Exception innerException) + { + throw new ArrayTypeMismatchException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArgumentException(string message) + { + throw new ArgumentException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArgumentException(string message, Exception innerException) + { + throw new ArgumentException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// The message to include in the exception. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArgumentException(string name, string message) + { + throw new ArgumentException(message, name); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArgumentException(string name, string message, Exception innerException) + { + throw new ArgumentException(message, name, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArgumentNullException(string name) + { + throw new ArgumentNullException(name); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// The inner to include. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArgumentNullException(string name, Exception innerException) + { + throw new ArgumentNullException(name, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// The message to include in the exception. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArgumentNullException(string name, string message) + { + throw new ArgumentNullException(name, message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArgumentOutOfRangeException(string name) + { + throw new ArgumentOutOfRangeException(name); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArgumentOutOfRangeException(string name, Exception innerException) + { + throw new ArgumentOutOfRangeException(name, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// The message to include in the exception. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArgumentOutOfRangeException(string name, string message) + { + throw new ArgumentOutOfRangeException(name, message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// The current argument value. + /// The message to include in the exception. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowArgumentOutOfRangeException(string name, object value, string message) + { + throw new ArgumentOutOfRangeException(name, value, message); + } + +#if !NETSTANDARD1_4 + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowExternalException(string message) + { + throw new ExternalException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// The inner to include. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowExternalException(string message, Exception innerException) + { + throw new ExternalException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// The HRESULT of the errror to include. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowExternalException(string message, int error) + { + throw new ExternalException(message, error); + } +#endif + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowFormatException(string message) + { + throw new FormatException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowFormatException(string message, Exception innerException) + { + throw new FormatException(message, innerException); + } + +#if !NETSTANDARD1_4 + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowInsufficientMemoryException(string message) + { + throw new InsufficientMemoryException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowInsufficientMemoryException(string message, Exception innerException) + { + throw new InsufficientMemoryException(message, innerException); + } +#endif + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowInvalidDataException(string message) + { + throw new InvalidDataException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowInvalidDataException(string message, Exception innerException) + { + throw new InvalidDataException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowInvalidOperationException(string message) + { + throw new InvalidOperationException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowInvalidOperationException(string message, Exception innerException) + { + throw new InvalidOperationException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowLockRecursionException(string message) + { + throw new LockRecursionException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowLockRecursionException(string message, Exception innerException) + { + throw new LockRecursionException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowMissingFieldException(string message) + { + throw new MissingFieldException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowMissingFieldException(string message, Exception innerException) + { + throw new MissingFieldException(message, innerException); + } + +#if !NETSTANDARD1_4 + /// + /// Throws a new . + /// + /// The type of expected result. + /// The target class being inspected. + /// The target field being retrieved. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowMissingFieldException(string className, string fieldName) + { + throw new MissingFieldException(className, fieldName); + } +#endif + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowMissingMemberException(string message) + { + throw new MissingMemberException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowMissingMemberException(string message, Exception innerException) + { + throw new MissingMemberException(message, innerException); + } + +#if !NETSTANDARD1_4 + /// + /// Throws a new . + /// + /// The type of expected result. + /// The target class being inspected. + /// The target member being retrieved. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowMissingMemberException(string className, string memberName) + { + throw new MissingMemberException(className, memberName); + } +#endif + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowMissingMethodException(string message) + { + throw new MissingMethodException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowMissingMethodException(string message, Exception innerException) + { + throw new MissingMethodException(message, innerException); + } + +#if !NETSTANDARD1_4 + /// + /// Throws a new . + /// + /// The type of expected result. + /// The target class being inspected. + /// The target method being retrieved. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowMissingMethodException(string className, string methodName) + { + throw new MissingMethodException(className, methodName); + } +#endif + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowNotSupportedException(string message) + { + throw new NotSupportedException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowNotSupportedException(string message, Exception innerException) + { + throw new NotSupportedException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The name of the disposed object. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowObjectDisposedException(string objectName) + { + throw new ObjectDisposedException(objectName); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The name of the disposed object. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowObjectDisposedException(string objectName, Exception innerException) + { + throw new ObjectDisposedException(objectName, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The name of the disposed object. + /// The message to include in the exception. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowObjectDisposedException(string objectName, string message) + { + throw new ObjectDisposedException(objectName, message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowOperationCanceledException(string message) + { + throw new OperationCanceledException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowOperationCanceledException(string message, Exception innerException) + { + throw new OperationCanceledException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The in use. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowOperationCanceledException(CancellationToken token) + { + throw new OperationCanceledException(token); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The in use. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowOperationCanceledException(string message, CancellationToken token) + { + throw new OperationCanceledException(message, token); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// The in use. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowOperationCanceledException(string message, Exception innerException, CancellationToken token) + { + throw new OperationCanceledException(message, innerException, token); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowPlatformNotSupportedException(string message) + { + throw new PlatformNotSupportedException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowPlatformNotSupportedException(string message, Exception innerException) + { + throw new PlatformNotSupportedException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowSynchronizationLockException(string message) + { + throw new SynchronizationLockException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowSynchronizationLockException(string message, Exception innerException) + { + throw new SynchronizationLockException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowTimeoutException(string message) + { + throw new TimeoutException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowTimeoutException(string message, Exception innerException) + { + throw new TimeoutException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowUnauthorizedAccessException(string message) + { + throw new UnauthorizedAccessException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowUnauthorizedAccessException(string message, Exception innerException) + { + throw new UnauthorizedAccessException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The Win32 error code associated with this exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowWin32Exception(int error) + { + throw new Win32Exception(error); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The Win32 error code associated with this exception. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowWin32Exception(int error, string message) + { + throw new Win32Exception(error, message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowWin32Exception(string message) + { + throw new Win32Exception(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// The inner to include. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowWin32Exception(string message, Exception innerException) + { + throw new Win32Exception(message, innerException); + } + } +} From 93ed83494a3e34cdaf7cbc9c0ca2b2d137e66505 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 28 Aug 2020 19:26:33 +0200 Subject: [PATCH 2/3] Added missing COMException throw helpers --- .../Diagnostics/ThrowHelper.Generic.cs | 41 +++++++++++++++++++ Microsoft.Toolkit/Diagnostics/ThrowHelper.cs | 35 ++++++++++++++++ .../Diagnostics/Test_ThrowHelper.cs | 1 + 3 files changed, 77 insertions(+) diff --git a/Microsoft.Toolkit/Diagnostics/ThrowHelper.Generic.cs b/Microsoft.Toolkit/Diagnostics/ThrowHelper.Generic.cs index 9a1ed504fa6..a4f0dcb7245 100644 --- a/Microsoft.Toolkit/Diagnostics/ThrowHelper.Generic.cs +++ b/Microsoft.Toolkit/Diagnostics/ThrowHelper.Generic.cs @@ -201,6 +201,47 @@ public static T ThrowArgumentOutOfRangeException(string name, object value, s } #if !NETSTANDARD1_4 + /// + /// Throws a new . + /// + /// The type of expected result. + /// The message to include in the exception. + /// Thrown with the specified parameter. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowCOMException(string message) + { + throw new COMException(message); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// The inner to include. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowCOMException(string message, Exception innerException) + { + throw new COMException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The type of expected result. + /// The argument name. + /// The HRESULT of the errror to include. + /// Thrown with the specified parameters. + /// This method always throws, so it actually never returns a value. + [DoesNotReturn] + public static T ThrowCOMException(string message, int error) + { + throw new COMException(message, error); + } + /// /// Throws a new . /// diff --git a/Microsoft.Toolkit/Diagnostics/ThrowHelper.cs b/Microsoft.Toolkit/Diagnostics/ThrowHelper.cs index 2338f17a31d..516301b434e 100644 --- a/Microsoft.Toolkit/Diagnostics/ThrowHelper.cs +++ b/Microsoft.Toolkit/Diagnostics/ThrowHelper.cs @@ -175,6 +175,41 @@ public static void ThrowArgumentOutOfRangeException(string name, object value, s } #if !NETSTANDARD1_4 + /// + /// Throws a new . + /// + /// The message to include in the exception. + /// Thrown with the specified parameter. + [DoesNotReturn] + public static void ThrowCOMException(string message) + { + throw new COMException(message); + } + + /// + /// Throws a new . + /// + /// The argument name. + /// The inner to include. + /// Thrown with the specified parameters. + [DoesNotReturn] + public static void ThrowCOMException(string message, Exception innerException) + { + throw new COMException(message, innerException); + } + + /// + /// Throws a new . + /// + /// The argument name. + /// The HRESULT of the errror to include. + /// Thrown with the specified parameters. + [DoesNotReturn] + public static void ThrowCOMException(string message, int error) + { + throw new COMException(message, error); + } + /// /// Throws a new . /// diff --git a/UnitTests/UnitTests.Shared/Diagnostics/Test_ThrowHelper.cs b/UnitTests/UnitTests.Shared/Diagnostics/Test_ThrowHelper.cs index c9ac6ec63cc..523f155ed4b 100644 --- a/UnitTests/UnitTests.Shared/Diagnostics/Test_ThrowHelper.cs +++ b/UnitTests/UnitTests.Shared/Diagnostics/Test_ThrowHelper.cs @@ -36,6 +36,7 @@ public class Test_ThrowHelper [DataRow(typeof(ArgumentException))] [DataRow(typeof(ArgumentNullException))] [DataRow(typeof(ArgumentOutOfRangeException))] + [DataRow(typeof(COMException))] [DataRow(typeof(ExternalException))] [DataRow(typeof(FormatException))] [DataRow(typeof(InsufficientMemoryException))] From 71d91657f101f9da326febcba53849d9217728ab Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 28 Aug 2020 19:28:38 +0200 Subject: [PATCH 3/3] Added ThrowHelper.Generic tests --- .../Diagnostics/Test_ThrowHelper.cs | 64 ++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/UnitTests/UnitTests.Shared/Diagnostics/Test_ThrowHelper.cs b/UnitTests/UnitTests.Shared/Diagnostics/Test_ThrowHelper.cs index 523f155ed4b..992ee7bca0f 100644 --- a/UnitTests/UnitTests.Shared/Diagnostics/Test_ThrowHelper.cs +++ b/UnitTests/UnitTests.Shared/Diagnostics/Test_ThrowHelper.cs @@ -58,7 +58,8 @@ public void Test_ThrowHelper_Throw(Type exceptionType) { var methods = ( from method in typeof(ThrowHelper).GetMethods(BindingFlags.Public | BindingFlags.Static) - where method.Name == $"Throw{exceptionType.Name}" + where method.Name == $"Throw{exceptionType.Name}" && + !method.IsGenericMethod select method).ToArray(); foreach (var method in methods) @@ -79,5 +80,66 @@ from parameter in method.GetParameters() } } } + + [TestCategory("Guard")] + [TestMethod] + [DataRow(typeof(ArrayTypeMismatchException))] + [DataRow(typeof(ArgumentException))] + [DataRow(typeof(ArgumentNullException))] + [DataRow(typeof(ArgumentOutOfRangeException))] + [DataRow(typeof(COMException))] + [DataRow(typeof(ExternalException))] + [DataRow(typeof(FormatException))] + [DataRow(typeof(InsufficientMemoryException))] + [DataRow(typeof(InvalidDataException))] + [DataRow(typeof(InvalidOperationException))] + [DataRow(typeof(LockRecursionException))] + [DataRow(typeof(MissingFieldException))] + [DataRow(typeof(MissingMemberException))] + [DataRow(typeof(MissingMethodException))] + [DataRow(typeof(NotSupportedException))] + [DataRow(typeof(ObjectDisposedException))] + [DataRow(typeof(OperationCanceledException))] + [DataRow(typeof(PlatformNotSupportedException))] + [DataRow(typeof(SynchronizationLockException))] + [DataRow(typeof(TimeoutException))] + [DataRow(typeof(UnauthorizedAccessException))] + [DataRow(typeof(Win32Exception))] + public void Test_ThrowHelper_Generic_Throw(Type exceptionType) + { + var methods = ( + from method in typeof(ThrowHelper).GetMethods(BindingFlags.Public | BindingFlags.Static) + where method.Name == $"Throw{exceptionType.Name}" && + method.IsGenericMethod + select method).ToArray(); + + foreach (var method in methods) + { + // Prepare the parameters with the default value + var parameters = ( + from parameter in method.GetParameters() + select DefaultValues[parameter.ParameterType]).ToArray(); + + // Invoke with value type + try + { + method.MakeGenericMethod(typeof(int)).Invoke(null, parameters); + } + catch (TargetInvocationException e) + { + Assert.IsInstanceOfType(e.InnerException, exceptionType); + } + + // Invoke with reference type + try + { + method.MakeGenericMethod(typeof(string)).Invoke(null, parameters); + } + catch (TargetInvocationException e) + { + Assert.IsInstanceOfType(e.InnerException, exceptionType); + } + } + } } }