2 // ValidationAttributeTest.cs
5 // Marek Habersack <mhabersack@novell.com>
7 // Copyright (C) 2010 Novell, Inc. (http://novell.com/)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Collections.Generic;
30 using System.ComponentModel.DataAnnotations;
33 using NUnit.Framework;
35 namespace MonoTests.System.ComponentModel.DataAnnotations
38 public class ValidationAttributeTest
40 const string TEST_ERROR_MESSAGE = "Test Error Message";
41 string ErrorMessageAccessor ()
43 return TEST_ERROR_MESSAGE;
47 public void Constructor ()
49 var attr = new ValidateFooAttribute ();
51 Assert.IsNull (attr.ErrorMessage, "#A1");
52 Assert.IsNull (attr.ErrorMessageResourceName, "#A2");
53 Assert.IsNull (attr.ErrorMessageResourceType, "#A3");
54 Assert.IsNotNull (attr.GetErrorMessageString (), "#A4");
58 public void Constructor_Func ()
60 var attr = new ValidateFooAttribute (ErrorMessageAccessor);
62 Assert.IsNull (attr.ErrorMessage, "#A1");
63 Assert.IsNull (attr.ErrorMessageResourceName, "#A2");
64 Assert.IsNull (attr.ErrorMessageResourceType, "#A3");
65 Assert.IsNotNull (attr.GetErrorMessageString (), "#A4");
66 Assert.AreEqual (TEST_ERROR_MESSAGE, attr.GetErrorMessageString (), "#A4");
70 public void Constructor_String ()
72 var attr = new ValidateFooAttribute ("Another Test Error Message");
74 Assert.IsNull (attr.ErrorMessage, "#A1");
75 Assert.IsNull (attr.ErrorMessageResourceName, "#A2");
76 Assert.IsNull (attr.ErrorMessageResourceType, "#A3");
77 Assert.IsNotNull (attr.GetErrorMessageString (), "#A4");
78 Assert.IsNotNull (attr.GetErrorMessageString (), "#A4-1");
79 Assert.AreEqual ("Another Test Error Message", attr.GetErrorMessageString (), "#A4-2");
83 public void ErrorMessage ()
85 var attr = new ValidateFooAttribute ();
87 Assert.IsNull (attr.ErrorMessage, "#A1");
89 attr.ErrorMessage = "Test";
90 Assert.AreEqual ("Test", attr.ErrorMessage, "#A2");
92 attr.ErrorMessage = String.Empty;
93 Assert.AreEqual (String.Empty, attr.ErrorMessage, "#A3");
95 attr.ErrorMessage = null;
96 Assert.IsNull (attr.ErrorMessage, "#A4");
99 attr.ErrorMessage = String.Empty;
101 } catch (InvalidOperationException) {
105 attr = new ValidateFooAttribute ("Test");
107 attr.ErrorMessage = null;
109 } catch (ArgumentException) {
113 attr = new ValidateFooAttribute ("Test");
115 attr.ErrorMessage = String.Empty;
117 } catch (ArgumentException) {
121 attr = new ValidateFooAttribute ();
122 attr.ErrorMessageResourceName = "ErrorProperty1";
125 attr.ErrorMessage = "Test Message";
127 } catch (InvalidOperationException) {
135 public void ErrorMessageResourceName ()
137 var attr = new ValidateFooAttribute ();
139 Assert.IsNull (attr.ErrorMessageResourceName, "#A1");
141 attr.ErrorMessageResourceName = "Test";
142 Assert.IsNotNull (attr.ErrorMessageResourceName, "#A2-1");
143 Assert.AreEqual ("Test", attr.ErrorMessageResourceName, "#A2-2");
145 attr.ErrorMessageResourceName = String.Empty;
146 Assert.IsNotNull (attr.ErrorMessageResourceName, "#A3-1");
147 Assert.AreEqual (String.Empty, attr.ErrorMessageResourceName, "#A3-2");
149 attr.ErrorMessageResourceName = null;
150 Assert.IsNull (attr.ErrorMessageResourceName, "#A3-1");
153 attr.ErrorMessageResourceName = String.Empty;
154 Assert.Fail ("#A3-1");
155 } catch (InvalidOperationException) {
159 attr = new ValidateFooAttribute ("Test");
161 attr.ErrorMessageResourceName = String.Empty;
162 Assert.Fail ("#A3-2");
163 } catch (ArgumentException) {
167 attr = new ValidateFooAttribute ("Test");
169 attr.ErrorMessageResourceName = null;
170 Assert.Fail ("#A3-3");
171 } catch (ArgumentException) {
175 attr = new ValidateFooAttribute ();
176 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
179 attr.ErrorMessageResourceName = "NoSuchProperty";
180 Assert.Fail ("#A3-4");
181 } catch (InvalidOperationException) {
188 public void ErrorMessageResourceType ()
190 var attr = new ValidateFooAttribute ();
192 Assert.IsNull (attr.ErrorMessageResourceType, "#A1");
194 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
195 Assert.IsNotNull (attr.ErrorMessageResourceType, "#A2-1");
196 Assert.AreEqual (typeof (FooErrorMessageProvider), attr.ErrorMessageResourceType, "#A2-2");
198 attr = new ValidateFooAttribute ();
199 attr.ErrorMessageResourceName = "NoSuchProperty";
202 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
204 } catch (InvalidOperationException) {
211 public void ErrorMessageString ()
213 var attr = new ValidateFooAttribute ();
215 Assert.IsNotNull (attr.GetErrorMessageString (), "#A1-1");
216 Assert.IsTrue (attr.GetErrorMessageString ().Length > 0, "#A1-2");
218 attr = new ValidateFooAttribute ();
219 attr.ErrorMessageResourceName = "TestResource";
221 attr.GetErrorMessageString ();
222 Assert.Fail ("#A2-1");
223 } catch (InvalidOperationException) {
227 attr = new ValidateFooAttribute ();
228 attr.ErrorMessageResourceName = String.Empty;
230 attr.GetErrorMessageString ();
231 Assert.Fail ("#A2-1");
232 } catch (InvalidOperationException) {
236 attr = new ValidateFooAttribute ();
237 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
238 attr.ErrorMessageResourceName = null;
241 attr.GetErrorMessageString ();
242 Assert.Fail ("#A3-1");
243 } catch (InvalidOperationException) {
247 attr = new ValidateFooAttribute ();
248 attr.ErrorMessageResourceName = String.Empty;
249 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
251 string s = attr.GetErrorMessageString ();
252 Assert.Fail ("#A3-2");
253 } catch (InvalidOperationException) {
257 attr = new ValidateFooAttribute ();
258 attr.ErrorMessageResourceName = "NoSuchProperty";
259 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
261 attr.GetErrorMessageString ();
263 } catch (InvalidOperationException) {
267 attr = new ValidateFooAttribute ();
268 attr.ErrorMessageResourceName = "ErrorProperty2";
269 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
271 attr.GetErrorMessageString ();
273 } catch (InvalidOperationException) {
277 attr = new ValidateFooAttribute ();
278 attr.ErrorMessageResourceName = "ErrorProperty3";
279 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
281 attr.GetErrorMessageString ();
283 } catch (InvalidOperationException) {
287 attr = new ValidateFooAttribute ();
288 attr.ErrorMessageResourceName = "ErrorProperty4";
289 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
291 attr.GetErrorMessageString ();
293 } catch (InvalidOperationException) {
297 attr = new ValidateFooAttribute ();
298 attr.ErrorMessageResourceName = "ErrorProperty5";
299 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
301 attr.GetErrorMessageString ();
303 } catch (InvalidOperationException) {
307 attr = new ValidateFooAttribute ();
308 attr.ErrorMessageResourceName = "ErrorField1";
309 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
311 attr.GetErrorMessageString ();
313 } catch (InvalidOperationException) {
317 attr = new ValidateFooAttribute ();
318 attr.ErrorMessageResourceName = "ErrorField2";
319 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
321 attr.GetErrorMessageString ();
323 } catch (InvalidOperationException) {
328 attr = new ValidateFooAttribute ();
329 attr.ErrorMessageResourceName = "ErrorProperty1";
330 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
331 Assert.IsNotNull (attr.GetErrorMessageString (), "#C1-1");
332 Assert.AreEqual ("Error Message 1", attr.GetErrorMessageString (), "#C1-2");
334 attr = new ValidateFooAttribute (ErrorMessageAccessor);
335 Assert.IsNotNull (attr.GetErrorMessageString (), "#D1-1");
336 Assert.AreEqual (TEST_ERROR_MESSAGE, attr.GetErrorMessageString (), "#D1-2");
338 attr = new ValidateFooAttribute ();
339 attr.ErrorMessageResourceName = "ErrorProperty1";
340 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
341 Assert.IsNotNull (attr.GetErrorMessageString (), "#D1-3");
342 Assert.AreEqual ("Error Message 1", attr.GetErrorMessageString (), "#D1-4");
344 attr.ErrorMessage = "Test Message";
346 attr.GetErrorMessageString ();
348 } catch (InvalidOperationException) {
355 public void FormatErrorMessage ()
357 var attr = new ValidateFooAttribute ();
359 Assert.IsNotNull (attr.FormatErrorMessage ("SomeField"), "#A1-1");
360 Assert.AreEqual ("The field SomeField is invalid.", attr.FormatErrorMessage ("SomeField"), "#A1-2");
362 attr.ErrorMessage = "Test: {0}";
363 Assert.IsNotNull (attr.FormatErrorMessage ("SomeField"), "#A2-1");
364 Assert.AreEqual ("Test: SomeField", attr.FormatErrorMessage ("SomeField"), "#A2-2");
366 attr = new ValidateFooAttribute ();
368 attr.ErrorMessage = null;
370 attr.ErrorMessageResourceName = "ErrorProperty1";
371 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
372 Assert.IsNotNull (attr.FormatErrorMessage ("SomeField"), "#B1-1");
373 Assert.AreEqual ("Error Message 1", attr.FormatErrorMessage ("SomeField"), "#B1-2");
375 attr = new ValidateFooAttribute ();
377 attr.ErrorMessageResourceName = "ErrorProperty6";
378 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
379 Assert.IsNotNull (attr.FormatErrorMessage ("SomeField"), "#B2-1");
380 Assert.AreEqual ("Error Message 6: SomeField", attr.FormatErrorMessage ("SomeField"), "#B2-2");
382 attr = new ValidateFooAttribute ();
384 attr.ErrorMessageResourceName = "ErrorProperty6";
385 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
386 Assert.IsNotNull (attr.FormatErrorMessage ("SomeField"), "#B3-1");
387 Assert.AreEqual ("Error Message 6: ", attr.FormatErrorMessage (null), "#B3-2");
391 public void GetValidationResult ()
393 var attr = new ValidateBarAttribute ();
396 attr.GetValidationResult ("stuff", null);
398 } catch (ArgumentNullException) {
402 var vc = new ValidationContext ("stuff", null, null);
403 vc.DisplayName = "MyStuff";
404 var vr = attr.GetValidationResult ("stuff", vc);
405 Assert.IsNull (vr, "#A2");
407 vr = attr.GetValidationResult (null, vc);
408 Assert.IsNotNull(vr, "#A3-1");
409 Assert.IsNotNull (vr.ErrorMessage, "#A3-2");
410 Assert.AreEqual ("The field MyStuff is invalid.", vr.ErrorMessage, "#A3-3");
412 attr.ErrorMessage = "My Error Message: {0}";
413 vr = attr.GetValidationResult (null, vc);
414 Assert.IsNotNull (vr, "#A4-1");
415 Assert.IsNotNull (vr.ErrorMessage, "#A4-2");
416 Assert.AreEqual ("My Error Message: MyStuff", vr.ErrorMessage, "#A4-3");
418 attr.ErrorMessage = null;
419 attr.ErrorMessageResourceName = "ErrorProperty1";
420 attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
421 vr = attr.GetValidationResult (null, vc);
422 Assert.IsNotNull (vr, "#A5-1");
423 Assert.IsNotNull (vr.ErrorMessage, "#A5-2");
424 Assert.AreEqual ("Error Message 1", vr.ErrorMessage, "#A5-3");
426 attr.ErrorMessage = "My Error Message: {0}";
427 attr.ErrorMessageResourceName = null;
428 attr.ErrorMessageResourceType = null;
429 vr = attr.GetValidationResult (null, vc);
430 Assert.IsNotNull (vr, "#A6-1");
431 Assert.IsNotNull (vr.MemberNames, "#A6-2");
433 foreach (string s in vr.MemberNames)
435 Assert.AreEqual (0, count, "#A6-3");
436 Assert.AreEqual ("My Error Message: MyStuff", vr.ErrorMessage, "#A6-4");
438 attr.ValidationResultErrorMessage = "My VR message";
439 vr = attr.GetValidationResult (null, vc);
440 Assert.IsNotNull (vr, "#A7-1");
441 Assert.AreEqual ("My VR message", vr.ErrorMessage, "#A7-2");
445 public void IsValid_Object ()
447 var attr = new ValidateFooAttribute ();
451 Assert.Fail ("#A1-1");
452 } catch (NotImplementedException) {
457 attr.IsValid ("stuff");
458 Assert.Fail ("#A1-2");
459 } catch (NotImplementedException) {
465 public void IsValid_Object_ValidationContext ()
467 var attr = new ValidateBarAttribute ();
471 attr.CallIsValid (null, null);
473 } catch (NullReferenceException) {
477 var vc = new ValidationContext ("stuff", null, null);
478 var vr = attr.CallIsValid (null, vc);
479 Assert.IsNotNull (vr, "#A2-1");
480 Assert.IsNotNull (vr.ErrorMessage, "#A2-2");
481 Assert.AreEqual ("The field String is invalid.", vr.ErrorMessage, "#A2-3");
482 Assert.IsNotNull (vr.MemberNames, "#A2-4");
485 foreach (string s in vr.MemberNames)
487 Assert.AreEqual (0, count, "#A2-5");
489 vc.MemberName = "SomeMember";
490 vr = attr.CallIsValid (null, vc);
491 Assert.IsNotNull (vr, "#A3-1");
492 Assert.IsNotNull (vr.ErrorMessage, "#A3-2");
493 Assert.AreEqual ("The field String is invalid.", vr.ErrorMessage, "#A3-3");
494 Assert.IsNotNull (vr.MemberNames, "#A3-4");
496 var list = new List <string> ();
497 foreach (string s in vr.MemberNames)
499 Assert.AreEqual (1, list.Count, "#A3-5");
500 Assert.AreEqual ("SomeMember", list [0], "#A3-6");
504 public void Validate_Object_ValidationContext ()
506 var attr = new ValidateBazAttribute ();
509 attr.Validate ("stuff", (ValidationContext) null);
511 } catch (ArgumentNullException) {
515 var vc = new ValidationContext ("stuff", null, null);
517 attr.Validate (null, vc);
518 Assert.Fail ("#A2-1");
519 } catch (ValidationException) {
522 Assert.AreEqual (3, attr.Calls.Count, "#A2-1");
523 Assert.AreEqual ("ValidationResult IsValid (object value, ValidationContext validationContext)", attr.Calls [0], "#A2-2");
524 Assert.AreEqual ("bool IsValid (object value)", attr.Calls [1], "#A2-3");
525 Assert.AreEqual ("string FormatErrorMessage (string name)", attr.Calls [2], "#A2-4");
529 public void Validate_Object_String ()
531 var attr = new ValidateBazAttribute ();
534 attr.Validate (null, (string) null);
536 } catch (ValidationException) {
540 Assert.AreEqual (2, attr.Calls.Count, "#A2-1");
541 Assert.AreEqual ("bool IsValid (object value)", attr.Calls [0], "#A2-2");
542 Assert.AreEqual ("string FormatErrorMessage (string name)", attr.Calls [1], "#A2-3");
546 class ValidateFooAttribute : ValidationAttribute
548 public ValidateFooAttribute ()
552 public ValidateFooAttribute (Func<string> errorMessageAccessor)
553 : base (errorMessageAccessor)
556 public ValidateFooAttribute (string errorMessage)
557 : base (errorMessage)
560 public string GetErrorMessageString ()
562 return ErrorMessageString;
565 public override bool IsValid (object value)
567 return value != null;
572 class ValidateBarAttribute : ValidateFooAttribute
574 public string ValidationResultErrorMessage
580 public override bool IsValid (object value)
582 return value != null;
585 protected override ValidationResult IsValid (object value, ValidationContext validationContext)
587 if (!IsValid (value))
588 return new ValidationResult (ValidationResultErrorMessage);
592 public ValidationResult CallIsValid (object value, ValidationContext validationContext)
594 return base.IsValid (value, validationContext);
599 class ValidateBazAttribute : ValidateBarAttribute
601 public readonly List<string> Calls = new List<string> ();
603 public override bool IsValid (object value)
605 Calls.Add ("bool IsValid (object value)");
606 return base.IsValid (value);
609 protected override ValidationResult IsValid (object value, ValidationContext validationContext)
611 Calls.Add ("ValidationResult IsValid (object value, ValidationContext validationContext)");
612 return base.IsValid (value, validationContext);
615 public override string FormatErrorMessage (string name)
617 Calls.Add ("string FormatErrorMessage (string name)");
618 return base.FormatErrorMessage (name);
622 class FooErrorMessageProvider
624 public static string ErrorProperty1
626 get { return "Error Message 1"; }
629 public static int ErrorProperty2
634 public string ErrorProperty3
636 get { return "Error Message 2"; }
639 protected static string ErrorProperty4
641 get { return "Error Message 3"; }
644 public static string ErrorProperty5
649 public static string ErrorProperty6
651 get { return "Error Message 6: {0}"; }
654 public string ErrorField1 = "Error Message 4";
655 public static string ErrorField2 = "Error Message 5";