-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathVerify.cs
341 lines (317 loc) · 14.9 KB
/
Verify.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
// This file contains general utilities to aid in development.
// Classes here generally shouldn't be exposed publicly since
// they're not particular to any library functionality.
// Because the classes here are internal, it's likely this file
// might be included in multiple assemblies.
namespace Standard
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Threading;
/// <summary>
/// A static class for retail validated assertions.
/// Instead of breaking into the debugger an exception is thrown.
/// </summary>
internal static class Verify
{
/// <summary>
/// Ensure that the current thread's apartment state is what's expected.
/// </summary>
/// <param name="requiredState">
/// The required apartment state for the current thread.
/// </param>
/// <param name="message">
/// The message string for the exception to be thrown if the state is invalid.
/// </param>
/// <exception cref="InvalidOperationException">
/// Thrown if the calling thread's apartment state is not the same as the requiredState.
/// </exception>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsApartmentState(ApartmentState requiredState, string message)
{
if (Thread.CurrentThread.GetApartmentState() != requiredState)
{
Assert.Fail();
throw new InvalidOperationException(message);
}
}
/// <summary>
/// Ensure that an argument is neither null nor empty.
/// </summary>
/// <param name="value">The string to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[SuppressMessage("Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength")]
[DebuggerStepThrough]
public static void IsNeitherNullNorEmpty(string value, string name)
{
// catch caller errors, mixing up the parameters. Name should never be empty.
Assert.IsNeitherNullNorEmpty(name);
// Notice that ArgumentNullException and ArgumentException take the parameters in opposite order :P
const string errorMessage = "The parameter can not be either null or empty.";
if (null == value)
{
Assert.Fail();
throw new ArgumentNullException(name, errorMessage);
}
if ("" == value)
{
Assert.Fail();
throw new ArgumentException(errorMessage, name);
}
}
/// <summary>
/// Ensure that an argument is neither null nor does it consist only of whitespace.
/// </summary>
/// <param name="value">The string to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[SuppressMessage("Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength")]
[DebuggerStepThrough]
public static void IsNeitherNullNorWhitespace(string value, string name)
{
// catch caller errors, mixing up the parameters. Name should never be empty.
Assert.IsNeitherNullNorEmpty(name);
// Notice that ArgumentNullException and ArgumentException take the parameters in opposite order :P
const string errorMessage = "The parameter can not be either null or empty or consist only of white space characters.";
if (null == value)
{
Assert.Fail();
throw new ArgumentNullException(name, errorMessage);
}
if ("" == value.Trim())
{
Assert.Fail();
throw new ArgumentException(errorMessage, name);
}
}
/// <summary>Verifies that an argument is not null.</summary>
/// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
/// <param name="obj">The object to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsNotDefault<T>(T obj, string name) where T : struct
{
if (default(T).Equals(obj))
{
Assert.Fail();
throw new ArgumentException("The parameter must not be the default value.", name);
}
}
/// <summary>Verifies that an argument is not null.</summary>
/// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
/// <param name="obj">The object to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsNotNull<T>(T obj, string name) where T : class
{
if (null == obj)
{
Assert.Fail();
throw new ArgumentNullException(name);
}
}
/// <summary>Verifies that an argument is not null.</summary>
/// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
/// <param name="obj">The object to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
/// <param name="message">The message to display with the exception</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsNotNull<T>(T obj, string name, string message) where T : class
{
if (null == obj)
{
Assert.Fail();
throw new ArgumentNullException(name, message);
}
}
/// <summary>Verifies that an argument is null.</summary>
/// <typeparam name="T">Type of the object to validate. Must be a class.</typeparam>
/// <param name="obj">The object to validate.</param>
/// <param name="name">The name of the parameter that will be presented if an exception is thrown.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsNull<T>(T obj, string name) where T : class
{
if (null != obj)
{
Assert.Fail();
throw new ArgumentException("The parameter must be null.", name);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void PropertyIsNotNull<T>(T obj, string name) where T : class
{
if (null == obj)
{
Assert.Fail();
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The property {0} cannot be null at this time.", name));
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void PropertyIsNull<T>(T obj, string name) where T : class
{
if (null != obj)
{
Assert.Fail();
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The property {0} must be null at this time.", name));
}
}
/// <summary>
/// Verifies the specified statement is true. Throws an ArgumentException if it's not.
/// </summary>
/// <param name="statement">The statement to be verified as true.</param>
/// <param name="name">Name of the parameter to include in the ArgumentException.</param>
/// <param name="message">The message to include in the ArgumentException.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsTrue(bool statement, string name, string message = null)
{
if (!statement)
{
Assert.Fail();
throw new ArgumentException(message ?? "", name);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void IsFalse(bool statement, string name, string message = null)
{
if (statement)
{
Assert.Fail();
throw new ArgumentException(message ?? "", name);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void AreEqual<T>(T expected, T actual, string parameterName, string message)
{
if (null == expected)
{
// Two nulls are considered equal, regardless of type semantics.
if (null != actual && !actual.Equals(expected))
{
Assert.Fail();
throw new ArgumentException(message, parameterName);
}
}
else if (!expected.Equals(actual))
{
Assert.Fail();
throw new ArgumentException(message, parameterName);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void AreNotEqual<T>(T notExpected, T actual, string parameterName, string message)
{
if (null == notExpected)
{
// Two nulls are considered equal, regardless of type semantics.
if (null == actual || actual.Equals(notExpected))
{
Assert.Fail();
throw new ArgumentException(message, parameterName);
}
}
else if (notExpected.Equals(actual))
{
Assert.Fail();
throw new ArgumentException(message, parameterName);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void UriIsAbsolute(Uri uri, string parameterName)
{
Verify.IsNotNull(uri, parameterName);
if (!uri.IsAbsoluteUri)
{
Assert.Fail();
throw new ArgumentException("The URI must be absolute.", parameterName);
}
}
/// <summary>
/// Verifies that the specified value is within the expected range. The assertion fails if it isn't.
/// </summary>
/// <param name="lowerBoundInclusive">The lower bound inclusive value.</param>
/// <param name="value">The value to verify.</param>
/// <param name="upperBoundExclusive">The upper bound exclusive value.</param>
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void BoundedInteger(int lowerBoundInclusive, int value, int upperBoundExclusive, string parameterName)
{
if (value < lowerBoundInclusive || value >= upperBoundExclusive)
{
Assert.Fail();
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The integer value must be bounded with [{0}, {1})", lowerBoundInclusive, upperBoundExclusive), parameterName);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void BoundedDoubleInc(double lowerBoundInclusive, double value, double upperBoundInclusive, string message, string parameter)
{
if (value < lowerBoundInclusive || value > upperBoundInclusive)
{
Assert.Fail();
throw new ArgumentException(message, parameter);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void TypeSupportsInterface(Type type, Type interfaceType, string parameterName)
{
Assert.IsNeitherNullNorEmpty(parameterName);
Verify.IsNotNull(type, "type");
Verify.IsNotNull(interfaceType, "interfaceType");
if (type.GetInterface(interfaceType.Name) == null)
{
Assert.Fail();
throw new ArgumentException("The type of this parameter does not support a required interface", parameterName);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
public static void FileExists(string filePath, string parameterName)
{
Verify.IsNeitherNullNorEmpty(filePath, parameterName);
if (!File.Exists(filePath))
{
Assert.Fail();
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "No file exists at \"{0}\"", filePath), parameterName);
}
}
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DebuggerStepThrough]
internal static void ImplementsInterface(object parameter, Type interfaceType, string parameterName)
{
Assert.IsNotNull(parameter);
Assert.IsNotNull(interfaceType);
Assert.IsTrue(interfaceType.IsInterface);
bool isImplemented = false;
foreach (var ifaceType in parameter.GetType().GetInterfaces())
{
if (ifaceType == interfaceType)
{
isImplemented = true;
break;
}
}
if (!isImplemented)
{
Assert.Fail();
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The parameter must implement interface {0}.", interfaceType.ToString()), parameterName);
}
}
}
}