Merge pull request #1944 from akoeplinger/remove-net40-ifdefs
[mono.git] / mcs / class / System.ComponentModel.DataAnnotations / Test / System.ComponentModel.DataAnnotations / ValidationAttributeTest.cs
1 //
2 // ValidationAttributeTest.cs
3 //
4 // Authors:
5 //      Marek Habersack <mhabersack@novell.com>
6 //
7 // Copyright (C) 2010 Novell, Inc. (http://novell.com/)
8 //
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:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
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.
27 //
28 using System;
29 using System.Collections.Generic;
30 using System.ComponentModel.DataAnnotations;
31 using System.Text;
32
33 using NUnit.Framework;
34 using MonoTests.Common;
35
36 namespace MonoTests.System.ComponentModel.DataAnnotations
37 {
38         [TestFixture]
39         public class ValidationAttributeTest
40         {
41                 const string TEST_ERROR_MESSAGE = "Test Error Message";
42                 string ErrorMessageAccessor ()
43                 {
44                         return TEST_ERROR_MESSAGE;
45                 }
46
47                 [Test]
48                 public void Constructor ()
49                 {
50                         var attr = new ValidateFooAttribute ();
51
52                         Assert.IsNull (attr.ErrorMessage, "#A1");
53                         Assert.IsNull (attr.ErrorMessageResourceName, "#A2");
54                         Assert.IsNull (attr.ErrorMessageResourceType, "#A3");
55                         Assert.IsNotNull (attr.GetErrorMessageString (), "#A4");
56                 }
57
58                 [Test]
59                 public void Constructor_Func ()
60                 {
61                         var attr = new ValidateFooAttribute (ErrorMessageAccessor);
62
63                         Assert.IsNull (attr.ErrorMessage, "#A1");
64                         Assert.IsNull (attr.ErrorMessageResourceName, "#A2");
65                         Assert.IsNull (attr.ErrorMessageResourceType, "#A3");
66                         Assert.IsNotNull (attr.GetErrorMessageString (), "#A4");
67                         Assert.AreEqual (TEST_ERROR_MESSAGE, attr.GetErrorMessageString (), "#A4");
68                 }
69
70                 [Test]
71                 public void Constructor_String ()
72                 {
73                         var attr = new ValidateFooAttribute ("Another Test Error Message");
74
75                         Assert.IsNull (attr.ErrorMessage, "#A1");
76                         Assert.IsNull (attr.ErrorMessageResourceName, "#A2");
77                         Assert.IsNull (attr.ErrorMessageResourceType, "#A3");
78                         Assert.IsNotNull (attr.GetErrorMessageString (), "#A4");
79                         Assert.IsNotNull (attr.GetErrorMessageString (), "#A4-1");
80                         Assert.AreEqual ("Another Test Error Message", attr.GetErrorMessageString (), "#A4-2");
81                 }
82
83                 [Test]
84                 public void ErrorMessage ()
85                 {
86                         var attr = new ValidateFooAttribute ();
87
88                         Assert.IsNull (attr.ErrorMessage, "#A1");
89
90                         attr.ErrorMessage = "Test";
91                         Assert.AreEqual ("Test", attr.ErrorMessage, "#A2");
92                         attr.ErrorMessage = String.Empty;
93                         Assert.AreEqual (String.Empty, attr.ErrorMessage, "#A3");
94
95                         attr.ErrorMessage = null;
96                         Assert.IsNull (attr.ErrorMessage, "#A4");
97                         
98                 }
99
100                 [Test]
101                 public void ErrorMessageResourceName ()
102                 {
103                         var attr = new ValidateFooAttribute ();
104
105                         Assert.IsNull (attr.ErrorMessageResourceName, "#A1");
106
107                         attr.ErrorMessageResourceName = "Test";
108                         Assert.IsNotNull (attr.ErrorMessageResourceName, "#A2-1");
109                         Assert.AreEqual ("Test", attr.ErrorMessageResourceName, "#A2-2");
110                         attr.ErrorMessageResourceName = String.Empty;
111                         Assert.IsNotNull (attr.ErrorMessageResourceName, "#A3-1");
112                         Assert.AreEqual (String.Empty, attr.ErrorMessageResourceName, "#A3-2");
113
114                         attr.ErrorMessageResourceName = null;
115                         Assert.IsNull (attr.ErrorMessageResourceName, "#A3-1");
116                 }
117
118                 [Test]
119                 public void ErrorMessageResourceType ()
120                 {
121                         var attr = new ValidateFooAttribute ();
122
123                         Assert.IsNull (attr.ErrorMessageResourceType, "#A1");
124
125                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
126                         Assert.IsNotNull (attr.ErrorMessageResourceType, "#A2-1");
127                         Assert.AreEqual (typeof (FooErrorMessageProvider), attr.ErrorMessageResourceType, "#A2-2");
128                 }
129
130                 [Test]
131                 public void ErrorMessageString ()
132                 {
133                         var attr = new ValidateFooAttribute ();
134
135                         Assert.IsNotNull (attr.GetErrorMessageString (), "#A1-1");
136                         Assert.IsTrue (attr.GetErrorMessageString ().Length > 0, "#A1-2");
137
138                         attr = new ValidateFooAttribute ();
139                         attr.ErrorMessageResourceName = "TestResource";
140                         try {
141                                 attr.GetErrorMessageString ();
142                                 Assert.Fail ("#A2-1");
143                         } catch (InvalidOperationException) {
144                                 // success
145                         }
146                         attr = new ValidateFooAttribute ();
147                         attr.ErrorMessageResourceName = String.Empty;
148                         try {
149                                 attr.GetErrorMessageString ();
150                                 Assert.Fail ("#A2-1");
151                         } catch (InvalidOperationException) {
152                                 // success
153                         }
154
155                         attr = new ValidateFooAttribute ();
156                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
157                         attr.ErrorMessageResourceName = null;
158                         
159                         try {
160                                 attr.GetErrorMessageString ();
161                                 Assert.Fail ("#A3-1");
162                         } catch (InvalidOperationException) {
163                                 // success
164                         }
165
166                         attr = new ValidateFooAttribute ();
167                         attr.ErrorMessageResourceName = String.Empty;
168                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
169                         try {
170                                 string s = attr.GetErrorMessageString ();
171                                 Assert.Fail ("#A3-2");
172                         } catch (InvalidOperationException) {
173                                 // success
174                         }
175
176                         attr = new ValidateFooAttribute ();
177                         attr.ErrorMessageResourceName = "NoSuchProperty";
178                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
179                         try {
180                                 attr.GetErrorMessageString ();
181                                 Assert.Fail ("#A4");
182                         } catch (InvalidOperationException) {
183                                 // success
184                         }
185
186                         attr = new ValidateFooAttribute ();
187                         attr.ErrorMessageResourceName = "ErrorProperty2";
188                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
189                         try {
190                                 attr.GetErrorMessageString ();
191                                 Assert.Fail ("#A5");
192                         } catch (InvalidOperationException) {
193                                 // success
194                         }
195
196                         attr = new ValidateFooAttribute ();
197                         attr.ErrorMessageResourceName = "ErrorProperty3";
198                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
199                         try {
200                                 attr.GetErrorMessageString ();
201                                 Assert.Fail ("#A5");
202                         } catch (InvalidOperationException) {
203                                 // success
204                         }
205
206                         attr = new ValidateFooAttribute ();
207                         attr.ErrorMessageResourceName = "ErrorProperty4";
208                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
209                         try {
210                                 attr.GetErrorMessageString ();
211                                 Assert.Fail ("#A6");
212                         } catch (InvalidOperationException) {
213                                 // success
214                         }
215
216                         attr = new ValidateFooAttribute ();
217                         attr.ErrorMessageResourceName = "ErrorProperty5";
218                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
219                         try {
220                                 attr.GetErrorMessageString ();
221                                 Assert.Fail ("#A7");
222                         } catch (InvalidOperationException) {
223                                 // success
224                         }
225
226                         attr = new ValidateFooAttribute ();
227                         attr.ErrorMessageResourceName = "ErrorField1";
228                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
229                         try {
230                                 attr.GetErrorMessageString ();
231                                 Assert.Fail ("#B1");
232                         } catch (InvalidOperationException) {
233                                 // success
234                         }
235
236                         attr = new ValidateFooAttribute ();
237                         attr.ErrorMessageResourceName = "ErrorField2";
238                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
239                         try {
240                                 attr.GetErrorMessageString ();
241                                 Assert.Fail ("#B2");
242                         } catch (InvalidOperationException) {
243                                 // success
244                         }
245
246                         attr = new ValidateFooAttribute ();
247                         attr.ErrorMessageResourceName = "ErrorProperty1";
248                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
249                         Assert.IsNotNull (attr.GetErrorMessageString (), "#C1-1");
250                         Assert.AreEqual ("Error Message 1", attr.GetErrorMessageString (), "#C1-2");
251
252                         attr = new ValidateFooAttribute (ErrorMessageAccessor);
253                         Assert.IsNotNull (attr.GetErrorMessageString (), "#D1-1");
254                         Assert.AreEqual (TEST_ERROR_MESSAGE, attr.GetErrorMessageString (), "#D1-2");
255
256                         attr = new ValidateFooAttribute ();
257                         attr.ErrorMessageResourceName = "ErrorProperty1";
258                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
259                         Assert.IsNotNull (attr.GetErrorMessageString (), "#D1-3");
260                         Assert.AreEqual ("Error Message 1", attr.GetErrorMessageString (), "#D1-4");
261                         attr.ErrorMessage = "Test Message";
262                         try {
263                                 attr.GetErrorMessageString ();
264                                 Assert.Fail ("#E1");
265                         } catch (InvalidOperationException) {
266                                 // success
267                         }
268                 }
269
270                 [Test]
271                 public void FormatErrorMessage ()
272                 {
273                         var attr = new ValidateFooAttribute ();
274
275                         Assert.IsNotNull (attr.FormatErrorMessage ("SomeField"), "#A1-1");
276                         Assert.AreEqual ("The field SomeField is invalid.", attr.FormatErrorMessage ("SomeField"), "#A1-2");
277
278                         attr.ErrorMessage = "Test: {0}";
279                         Assert.IsNotNull (attr.FormatErrorMessage ("SomeField"), "#A2-1");
280                         Assert.AreEqual ("Test: SomeField", attr.FormatErrorMessage ("SomeField"), "#A2-2");
281                         attr.ErrorMessage = null;
282                         attr.ErrorMessageResourceName = "ErrorProperty1";
283                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
284                         Assert.IsNotNull (attr.FormatErrorMessage ("SomeField"), "#B1-1");
285                         Assert.AreEqual ("Error Message 1", attr.FormatErrorMessage ("SomeField"), "#B1-2");
286                         attr.ErrorMessageResourceName = "ErrorProperty6";
287                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
288                         Assert.IsNotNull (attr.FormatErrorMessage ("SomeField"), "#B2-1");
289                         Assert.AreEqual ("Error Message 6: SomeField", attr.FormatErrorMessage ("SomeField"), "#B2-2");
290                         attr.ErrorMessageResourceName = "ErrorProperty6";
291                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
292                         Assert.IsNotNull (attr.FormatErrorMessage ("SomeField"), "#B3-1");
293                         Assert.AreEqual ("Error Message 6: ", attr.FormatErrorMessage (null), "#B3-2");
294                 }
295                 [Test]
296                 public void GetValidationResult ()
297                 {
298                         var attr = new ValidateBarAttribute ();
299
300                         try {
301                                 attr.GetValidationResult ("stuff", null);
302                                 Assert.Fail ("#A1");
303                         } catch (ArgumentNullException) {
304                                 // success
305                         }
306
307                         var vc = new ValidationContext ("stuff", null, null);
308                         vc.DisplayName = "MyStuff";
309                         var vr = attr.GetValidationResult ("stuff", vc);
310                         Assert.IsNull (vr, "#A2");
311
312                         vr = attr.GetValidationResult (null, vc);
313                         Assert.IsNotNull(vr, "#A3-1");
314                         Assert.IsNotNull (vr.ErrorMessage, "#A3-2");
315                         Assert.AreEqual ("The field MyStuff is invalid.", vr.ErrorMessage, "#A3-3");
316
317                         attr.ErrorMessage = "My Error Message: {0}";
318                         vr = attr.GetValidationResult (null, vc);
319                         Assert.IsNotNull (vr, "#A4-1");
320                         Assert.IsNotNull (vr.ErrorMessage, "#A4-2");
321                         Assert.AreEqual ("My Error Message: MyStuff", vr.ErrorMessage, "#A4-3");
322
323                         attr.ErrorMessage = null;
324                         attr.ErrorMessageResourceName = "ErrorProperty1";
325                         attr.ErrorMessageResourceType = typeof (FooErrorMessageProvider);
326                         vr = attr.GetValidationResult (null, vc);
327                         Assert.IsNotNull (vr, "#A5-1");
328                         Assert.IsNotNull (vr.ErrorMessage, "#A5-2");
329                         Assert.AreEqual ("Error Message 1", vr.ErrorMessage, "#A5-3");
330
331                         attr.ErrorMessage = "My Error Message: {0}";
332                         attr.ErrorMessageResourceName = null;
333                         attr.ErrorMessageResourceType = null;
334                         vr = attr.GetValidationResult (null, vc);
335                         Assert.IsNotNull (vr, "#A6-1");
336                         Assert.IsNotNull (vr.MemberNames, "#A6-2");
337                         int count = 0;
338                         foreach (string s in vr.MemberNames)
339                                 count++;
340                         Assert.AreEqual (0, count, "#A6-3");
341                         Assert.AreEqual ("My Error Message: MyStuff", vr.ErrorMessage, "#A6-4");
342
343                         attr.ValidationResultErrorMessage = "My VR message";
344                         vr = attr.GetValidationResult (null, vc);
345                         Assert.IsNotNull (vr, "#A7-1");
346                         Assert.AreEqual ("My VR message", vr.ErrorMessage, "#A7-2");
347                 }
348
349                 [Test]
350                 public void IsValid_Object ()
351                 {
352                         var attr = new ValidateFooAttribute ();
353
354                         AssertExtensions.Throws <NotImplementedException> (() => {
355                                 // It calls IsValid (object, validationContext) which throws the NIEX, but when that overload is called directly, there's
356                                 // no exception.
357                                 //
358                                 // at System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value, ValidationContext validationContext)
359                                 // at System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value)
360                                 // at MonoTests.System.ComponentModel.DataAnnotations.ValidationAttributeTest.IsValid_Object() in C:\Users\grendel\Documents\Visual Studio 2010\Projects\System.Web.Test\System.Web.Test\System.ComponentModel.DataAnnotations\ValidationAttributeTest.cs:line 450
361                                 attr.IsValid (null);
362                         }, "#A1-1");
363                         
364                         AssertExtensions.Throws <NotImplementedException> (() => {
365                                 attr.IsValid ("stuff");
366                         }, "#A1-2");
367                 }
368
369                 [Test]
370                 public void IsValid_Object_ValidationContext ()
371                 {
372                         var attr = new ValidateBarAttribute ();
373
374                         AssertExtensions.Throws <NullReferenceException> (() => {
375                                 attr.CallIsValid (null, null);
376                         }, "#A1");
377
378                         var vc = new ValidationContext ("stuff", null, null);
379                         var vr = attr.CallIsValid (null, vc);
380                         Assert.IsNotNull (vr, "#A2-1");
381                         Assert.IsNotNull (vr.ErrorMessage, "#A2-2");
382                         Assert.AreEqual ("The field String is invalid.", vr.ErrorMessage, "#A2-3");
383                         Assert.IsNotNull (vr.MemberNames, "#A2-4"); 
384                         
385                         int count = 0;
386                         foreach (string s in vr.MemberNames)
387                                 count++;
388                         Assert.AreEqual (0, count, "#A2-5");
389
390                         vc.MemberName = "SomeMember";
391                         vr = attr.CallIsValid (null, vc);
392                         Assert.IsNotNull (vr, "#A3-1");
393                         Assert.IsNotNull (vr.ErrorMessage, "#A3-2");
394                         Assert.AreEqual ("The field String is invalid.", vr.ErrorMessage, "#A3-3");
395                         Assert.IsNotNull (vr.MemberNames, "#A3-4");
396
397                         var list = new List <string> ();
398                         foreach (string s in vr.MemberNames)
399                                 list.Add (s);
400                         Assert.AreEqual (1, list.Count, "#A3-5");
401                         Assert.AreEqual ("SomeMember", list [0], "#A3-6");
402                 }
403
404                 [Test]
405                 public void IsValid_Object_ValidationContext_CrossCallsWithNIEX ()
406                 {
407                         var attr = new ValidateSomethingAttribute ();
408
409                         AssertExtensions.Throws<NotImplementedException> (() => {
410                                 // Thrown from the IsValid (object, ValidationContext) overload!
411                                 //
412                                 // MonoTests.System.ComponentModel.DataAnnotations.ValidationAttributeTest.IsValid_Object_ValidationContext_02:
413                                 // System.NotImplementedException : IsValid(object value) has not been implemented by this class.  The preferred entry point is GetValidationResult() and classes should override IsValid(object value, ValidationContext context).
414                                 //
415                                 // at System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value, ValidationContext validationContext)
416                                 // at MonoTests.System.ComponentModel.DataAnnotations.ValidateSomethingAttribute.IsValid(Object value) in C:\Users\grendel\Documents\Visual Studio 2010\Projects\System.Web.Test\System.Web.Test\System.ComponentModel.DataAnnotations\ValidationAttributeTest.cs:line 639
417                                 // at System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value, ValidationContext validationContext)
418                                 // at MonoTests.System.ComponentModel.DataAnnotations.ValidateSomethingAttribute.IsValid(Object value) in C:\Users\grendel\Documents\Visual Studio 2010\Projects\System.Web.Test\System.Web.Test\System.ComponentModel.DataAnnotations\ValidationAttributeTest.cs:line 639
419                                 // at MonoTests.System.ComponentModel.DataAnnotations.ValidationAttributeTest.IsValid_Object_ValidationContext_02() in C:\Users\grendel\Documents\Visual Studio 2010\Projects\System.Web.Test\System.Web.Test\System.ComponentModel.DataAnnotations\ValidationAttributeTest.cs:line 514
420                                 attr.IsValid ("stuff");
421                         }, "#A1");
422
423                         AssertExtensions.Throws<NotImplementedException> (() => {
424                                 // And this one is thrown from the IsValid (object) overload!
425                                 //
426                                 // MonoTests.System.ComponentModel.DataAnnotations.ValidationAttributeTest.IsValid_Object_ValidationContext_CrossCallsWithNIEX:
427                                 // System.NotImplementedException : IsValid(object value) has not been implemented by this class.  The preferred entry point is GetValidationResult() and classes should override IsValid(object value, ValidationContext context).
428                                 //
429                                 // at System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value)
430                                 // at MonoTests.System.ComponentModel.DataAnnotations.ValidateSomethingAttribute.IsValid(Object value, ValidationContext validationContext) in C:\Users\grendel\Documents\Visual Studio 2010\Projects\System.Web.Test\System.Web.Test\System.ComponentModel.DataAnnotations\ValidationAttributeTest.cs:line 660
431                                 // at System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value)
432                                 // at MonoTests.System.ComponentModel.DataAnnotations.ValidateSomethingAttribute.IsValid(Object value, ValidationContext validationContext) in C:\Users\grendel\Documents\Visual Studio 2010\Projects\System.Web.Test\System.Web.Test\System.ComponentModel.DataAnnotations\ValidationAttributeTest.cs:line 660
433                                 // at MonoTests.System.ComponentModel.DataAnnotations.ValidateSomethingAttribute.CallIsValid(Object value, ValidationContext validationContext) in C:\Users\grendel\Documents\Visual Studio 2010\Projects\System.Web.Test\System.Web.Test\System.ComponentModel.DataAnnotations\ValidationAttributeTest.cs:line 667
434                                 // at MonoTests.System.ComponentModel.DataAnnotations.ValidationAttributeTest.IsValid_Object_ValidationContext_CrossCallsWithNIEX() in C:\Users\grendel\Documents\Visual Studio 2010\Projects\System.Web.Test\System.Web.Test\System.ComponentModel.DataAnnotations\ValidationAttributeTest.cs:line 530
435
436                                 attr.CallIsValid ("stuff", null);
437                         }, "#A2");
438                 }
439                 [Test]
440                 public void Validate_Object_ValidationContext ()
441                 {
442                         var attr = new ValidateBazAttribute ();
443
444                         try {
445                                 attr.Validate ("stuff", (ValidationContext) null);
446                                 Assert.Fail ("#A1");
447                         } catch (ArgumentNullException) {
448                                 // success
449                         }
450
451                         var vc = new ValidationContext ("stuff", null, null);
452                         try {
453                                 attr.Validate (null, vc);
454                                 Assert.Fail ("#A2-1");
455                         } catch (ValidationException) {
456                                 // success
457                         }
458                         Assert.AreEqual (3, attr.Calls.Count, "#A2-1");
459                         Assert.AreEqual ("ValidationResult IsValid (object value, ValidationContext validationContext)", attr.Calls [0], "#A2-2");
460                         Assert.AreEqual ("bool IsValid (object value)", attr.Calls [1], "#A2-3");
461                         Assert.AreEqual ("string FormatErrorMessage (string name)", attr.Calls [2], "#A2-4");
462                 }
463                 [Test]
464                 public void Validate_Object_String ()
465                 {
466                         var attr = new ValidateBazAttribute ();
467
468                         try {
469                                 attr.Validate (null, (string) null);
470                                 Assert.Fail ("#A2");
471                         } catch (ValidationException) {
472                                 // success
473                         }
474
475                         Assert.AreEqual (2, attr.Calls.Count, "#A2-1");
476                         Assert.AreEqual ("bool IsValid (object value)", attr.Calls [0], "#A2-2");
477                         Assert.AreEqual ("string FormatErrorMessage (string name)", attr.Calls [1], "#A2-3");
478                 }
479         }
480
481         class ValidateFooAttribute : ValidationAttribute
482         {
483                 public ValidateFooAttribute ()
484                         : base ()
485                 { }
486
487                 public ValidateFooAttribute (Func<string> errorMessageAccessor)
488                         : base (errorMessageAccessor)
489                 { }
490
491                 public ValidateFooAttribute (string errorMessage)
492                         : base (errorMessage)
493                 { }
494
495                 public string GetErrorMessageString ()
496                 {
497                         return ErrorMessageString;
498                 }
499         }
500
501         class ValidateBarAttribute : ValidateFooAttribute
502         {
503                 public string ValidationResultErrorMessage
504                 {
505                         get;
506                         set;
507                 }
508
509                 public override bool IsValid (object value)
510                 {
511                         return value != null;
512                 }
513                 protected override ValidationResult IsValid (object value, ValidationContext validationContext)
514                 {
515                         if (!IsValid (value))
516                                 return new ValidationResult (ValidationResultErrorMessage);
517                         return null;
518                 }
519
520                 public ValidationResult CallIsValid (object value, ValidationContext validationContext)
521                 {
522                         return base.IsValid (value, validationContext);
523                 }
524         }
525
526         class ValidateBazAttribute : ValidateBarAttribute
527         {
528                 public readonly List<string> Calls = new List<string> ();
529
530                 public override bool IsValid (object value)
531                 {
532                         Calls.Add ("bool IsValid (object value)");
533                         return base.IsValid (value);
534                 }
535                 protected override ValidationResult IsValid (object value, ValidationContext validationContext)
536                 {
537                         Calls.Add ("ValidationResult IsValid (object value, ValidationContext validationContext)");
538                         return base.IsValid (value, validationContext);
539                 }
540                 public override string FormatErrorMessage (string name)
541                 {
542                         Calls.Add ("string FormatErrorMessage (string name)");
543                         return base.FormatErrorMessage (name);
544                 }
545         }
546         class ValidateSomethingAttribute : ValidationAttribute
547         {
548                 public override bool IsValid (object value)
549                 {
550                         return base.IsValid (value, null) == ValidationResult.Success;
551                 }
552
553                 protected override ValidationResult IsValid (object value, ValidationContext validationContext)
554                 {
555                         if (base.IsValid (value))
556                                 return ValidationResult.Success;
557                         return new ValidationResult ("failed to validate in base class");
558                 }
559
560                 public ValidationResult CallIsValid (object value, ValidationContext validationContext)
561                 {
562                         return IsValid (value, validationContext);
563                 }
564         }
565         class FooErrorMessageProvider
566         {
567                 public static string ErrorProperty1
568                 {
569                         get { return "Error Message 1"; }
570                 }
571
572                 public static int ErrorProperty2
573                 {
574                         get { return 1; }
575                 }
576
577                 public string ErrorProperty3
578                 {
579                         get { return "Error Message 2"; }
580                 }
581
582                 protected static string ErrorProperty4
583                 {
584                         get { return "Error Message 3"; }
585                 }
586
587                 public static string ErrorProperty5
588                 {
589                         set { }
590                 }
591
592                 public static string ErrorProperty6
593                 {
594                         get { return "Error Message 6: {0}"; }
595                 }
596
597                 public string ErrorField1 = "Error Message 4";
598                 public static string ErrorField2 = "Error Message 5";
599         }
600 }