[bcl] Remove NET_4_0 defines from class libs
[mono.git] / mcs / class / System.ComponentModel.DataAnnotations / Test / System.ComponentModel.DataAnnotations / ValidatorTest.cs
1 //
2 // Authors:
3 //      Marek Habersack <grendel@twistedcode.net>
4 //
5 // Copyright (C) 2011 Novell, Inc. (http://novell.com/)
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining
8 // a copy of this software and associated documentation files (the
9 // "Software"), to deal in the Software without restriction, including
10 // without limitation the rights to use, copy, modify, merge, publish,
11 // distribute, sublicense, and/or sell copies of the Software, and to
12 // permit persons to whom the Software is furnished to do so, subject to
13 // the following conditions:
14 // 
15 // The above copyright notice and this permission notice shall be
16 // included in all copies or substantial portions of the Software.
17 // 
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 //
26 using System;
27 using System.Collections.Generic;
28 using System.ComponentModel.DataAnnotations;
29 using System.Text;
30
31 using NUnit.Framework;
32 using MonoTests.Common;
33
34 namespace MonoTests.System.ComponentModel.DataAnnotations
35 {
36         [TestFixture]
37         public class ValidatorTest
38         {
39                 [Test]
40                 public void TryValidateObject_Object_ValidationContext_ICollection_01 ()
41                 {
42                         var dummy = new DummyNoAttributes ();
43                         var ctx = new ValidationContext (dummy, null, null);
44                         var results = new List<ValidationResult> ();
45
46                         AssertExtensions.Throws<ArgumentNullException> (() => {
47                                 Validator.TryValidateObject (null, ctx, results);
48                         }, "#A1-1");
49
50                         AssertExtensions.Throws<ArgumentNullException> (() => {
51                                 Validator.TryValidateObject (dummy, null, results);
52                         }, "#A1-2");
53
54                         bool valid = Validator.TryValidateObject (dummy, ctx, null);
55                         Assert.IsTrue (valid, "#A2-1");
56                         Assert.IsTrue (results.Count == 0, "#A2-2");
57                 }
58
59                 [Test]
60                 public void TryValidateObject_Object_ValidationContext_ICollection_02 ()
61                 {
62                         var dummy = new Dummy ();
63                         var ctx = new ValidationContext (dummy, null, null);
64                         var results = new List<ValidationResult> ();
65
66                         bool valid = Validator.TryValidateObject (dummy, ctx, results);
67                         Assert.IsTrue (valid, "#A1-1");
68                         Assert.AreEqual (0, results.Count, "#A1-2");
69
70                         dummy = new Dummy {
71                                 NameField = null
72                         };
73                         AssertExtensions.Throws<ArgumentException> (() => {
74                                 // The instance provided must match the ObjectInstance on the ValidationContext supplied.
75                                 valid = Validator.TryValidateObject (dummy, ctx, results);
76                         }, "#A2");
77
78                         // Fields are ignored
79                         ctx = new ValidationContext (dummy, null, null);
80                         valid = Validator.TryValidateObject (dummy, ctx, results);
81                         Assert.IsTrue (valid, "#A3-1");
82                         Assert.AreEqual (0, results.Count, "#A3-2");
83
84                         // Required properties existence is validated
85                         dummy = new Dummy {
86                                 RequiredDummyField = null
87                         };
88                         ctx = new ValidationContext (dummy, null, null);
89                         valid = Validator.TryValidateObject (dummy, ctx, results);
90                         Assert.IsTrue (valid, "#A4-1");
91                         Assert.AreEqual (0, results.Count, "#A4-2");
92
93                         dummy = new Dummy {
94                                 RequiredDummyProperty = null
95                         };
96                         ctx = new ValidationContext (dummy, null, null);
97                         valid = Validator.TryValidateObject (dummy, ctx, results);
98                         Assert.IsFalse (valid, "#A5-1");
99                         Assert.AreEqual (1, results.Count, "#A5-2");
100
101                         results.Clear ();
102
103                         // validation attributes other than Required are ignored
104                         dummy = new Dummy {
105                                 NameProperty = null
106                         };
107                         ctx = new ValidationContext (dummy, null, null);
108                         valid = Validator.TryValidateObject (dummy, ctx, results);
109                         Assert.IsTrue (valid, "#A6-1");
110                         Assert.AreEqual (0, results.Count, "#A6-2");
111
112                         dummy = new Dummy {
113                                 MinMaxProperty = 0
114                         };
115                         ctx = new ValidationContext (dummy, null, null);
116                         valid = Validator.TryValidateObject (dummy, ctx, results);
117                         Assert.IsTrue (valid, "#A7-1");
118                         Assert.AreEqual (0, results.Count, "#A7-2");
119
120                         dummy = new Dummy {
121                                 FailValidation = true
122                         };
123                         ctx = new ValidationContext (dummy, null, null);
124                         valid = Validator.TryValidateObject (dummy, ctx, results);
125                         Assert.IsFalse (valid, "#A8-1");
126                         Assert.AreEqual (1, results.Count, "#A8-2");
127                 }
128
129                 [Test]
130                 public void TryValidateObject_Object_ValidationContext_ICollection_Bool_01 ()
131                 {
132                         var dummy = new DummyNoAttributes ();
133                         var ctx = new ValidationContext (dummy, null, null);
134                         var results = new List<ValidationResult> ();
135
136                         AssertExtensions.Throws<ArgumentNullException> (() => {
137                                 Validator.TryValidateObject (null, ctx, results, false);
138                         }, "#A1-1");
139
140                         AssertExtensions.Throws<ArgumentNullException> (() => {
141                                 Validator.TryValidateObject (dummy, null, results, false);
142                         }, "#A1-2");
143
144                         bool valid = Validator.TryValidateObject (dummy, ctx, null, false);
145                         Assert.IsTrue (valid, "#A2-1");
146                         Assert.IsTrue (results.Count == 0, "#A2-2");
147
148                         valid = Validator.TryValidateObject (dummy, ctx, null, true);
149                         Assert.IsTrue (valid, "#A3-1");
150                         Assert.IsTrue (results.Count == 0, "#A3-2");
151                 }
152
153                 [Test]
154                 public void TryValidateObject_Object_ValidationContext_ICollection_Bool_02 ()
155                 {
156                         var dummy = new Dummy ();
157                         var ctx = new ValidationContext (dummy, null, null);
158                         var results = new List<ValidationResult> ();
159
160                         bool valid = Validator.TryValidateObject (dummy, ctx, results, false);
161                         Assert.IsTrue (valid, "#A1-1");
162                         Assert.AreEqual (0, results.Count, "#A1-2");
163
164                         valid = Validator.TryValidateObject (dummy, ctx, results, true);
165                         Assert.IsTrue (valid, "#A1-3");
166                         Assert.AreEqual (0, results.Count, "#A1-4");
167
168                         dummy = new Dummy {
169                                 NameField = null
170                         };
171                         AssertExtensions.Throws<ArgumentException> (() => {
172                                 // The instance provided must match the ObjectInstance on the ValidationContext supplied.
173                                 valid = Validator.TryValidateObject (dummy, ctx, results, false);
174                         }, "#A2-1");
175
176                         AssertExtensions.Throws<ArgumentException> (() => {
177                                 // The instance provided must match the ObjectInstance on the ValidationContext supplied.
178                                 valid = Validator.TryValidateObject (dummy, ctx, results, true);
179                         }, "#A2-2");
180
181                         // Fields are ignored
182                         ctx = new ValidationContext (dummy, null, null);
183                         valid = Validator.TryValidateObject (dummy, ctx, results, false);
184                         Assert.IsTrue (valid, "#A3-1");
185                         Assert.AreEqual (0, results.Count, "#A3-2");
186
187                         valid = Validator.TryValidateObject (dummy, ctx, results, true);
188                         Assert.IsTrue (valid, "#A3-3");
189                         Assert.AreEqual (0, results.Count, "#A3-4");
190
191                         dummy = new Dummy {
192                                 RequiredDummyField = null
193                         };
194                         ctx = new ValidationContext (dummy, null, null);
195                         valid = Validator.TryValidateObject (dummy, ctx, results, false);
196                         Assert.IsTrue (valid, "#A4-1");
197                         Assert.AreEqual (0, results.Count, "#A4-2");
198
199                         valid = Validator.TryValidateObject (dummy, ctx, results, true);
200                         Assert.IsTrue (valid, "#A4-3");
201                         Assert.AreEqual (0, results.Count, "#A4-4");
202
203                         // Required properties existence is validated
204                         dummy = new Dummy {
205                                 RequiredDummyProperty = null
206                         };
207                         ctx = new ValidationContext (dummy, null, null);
208                         valid = Validator.TryValidateObject (dummy, ctx, results, false);
209                         Assert.IsFalse (valid, "#A5-1");
210                         Assert.AreEqual (1, results.Count, "#A5-2");
211                         results.Clear ();
212                         
213                         valid = Validator.TryValidateObject (dummy, ctx, results, true);
214                         Assert.IsFalse (valid, "#A5-3");
215                         Assert.AreEqual (1, results.Count, "#A5-4");
216                         results.Clear ();
217
218                         dummy = new Dummy {
219                                 NameProperty = null
220                         };
221                         ctx = new ValidationContext (dummy, null, null);
222                         valid = Validator.TryValidateObject (dummy, ctx, results, false);
223                         Assert.IsTrue (valid, "#A6-1");
224                         Assert.AreEqual (0, results.Count, "#A6-2");
225
226                         // NameProperty is null, that causes the StringLength validator to skip its tests
227                         valid = Validator.TryValidateObject (dummy, ctx, results, true);
228                         Assert.IsTrue (valid, "#A6-3");
229                         Assert.AreEqual (0, results.Count, "#A6-4");
230
231                         dummy.NameProperty = "0";
232                         valid = Validator.TryValidateObject (dummy, ctx, results, true);
233                         Assert.IsFalse (valid, "#A6-5");
234                         Assert.AreEqual (1, results.Count, "#A6-6");
235                         results.Clear ();
236
237                         dummy.NameProperty = "name too long (invalid value)";
238                         valid = Validator.TryValidateObject (dummy, ctx, results, true);
239                         Assert.IsFalse (valid, "#A6-7");
240                         Assert.AreEqual (1, results.Count, "#A6-8");
241                         results.Clear ();
242
243                         dummy = new Dummy {
244                                 MinMaxProperty = 0
245                         };
246                         ctx = new ValidationContext (dummy, null, null);
247                         valid = Validator.TryValidateObject (dummy, ctx, results, false);
248                         Assert.IsTrue (valid, "#A7-1");
249                         Assert.AreEqual (0, results.Count, "#A7-2");
250
251                         valid = Validator.TryValidateObject (dummy, ctx, results, true);
252                         Assert.IsFalse (valid, "#A7-3");
253                         Assert.AreEqual (1, results.Count, "#A7-4");
254                         results.Clear ();
255
256                         dummy = new Dummy {
257                                 FailValidation = true
258                         };
259                         ctx = new ValidationContext (dummy, null, null);
260                         valid = Validator.TryValidateObject (dummy, ctx, results, false);
261                         Assert.IsFalse (valid, "#A8-1");
262                         Assert.AreEqual (1, results.Count, "#A8-2");
263                         results.Clear ();
264
265                         valid = Validator.TryValidateObject (dummy, ctx, results, true);
266                         Assert.IsFalse (valid, "#A8-3");
267                         Assert.AreEqual (1, results.Count, "#A8-4");
268                         results.Clear ();
269
270                         var dummy2 = new DummyWithException ();
271                         ctx = new ValidationContext (dummy2, null, null);
272                         AssertExtensions.Throws<ApplicationException> (() => {
273                                 Validator.TryValidateObject (dummy2, ctx, results, true);
274                         }, "#A9");
275                 }
276
277                 [Test]
278                 public void TryValidateProperty ()
279                 {
280                         var dummy = new DummyNoAttributes ();
281                         var ctx = new ValidationContext (dummy, null, null) {
282                                 MemberName = "NameProperty"
283                         };
284                         var results = new List<ValidationResult> ();
285
286                         AssertExtensions.Throws<ArgumentException> (() => {
287                                 // MonoTests.System.ComponentModel.DataAnnotations.ValidatorTest.TryValidateProperty:
288                                 // System.ArgumentException : The type 'DummyNoAttributes' does not contain a public property named 'NameProperty'.
289                                 // Parameter name: propertyName
290                                 //
291                                 // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.TypeStoreItem.GetPropertyStoreItem(String propertyName)
292                                 // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.GetPropertyType(ValidationContext validationContext)
293                                 // at System.ComponentModel.DataAnnotations.Validator.TryValidateProperty(Object value, ValidationContext validationContext, ICollection`1 validationResults)
294                                 // at MonoTests.System.ComponentModel.DataAnnotations.ValidatorTest.TryValidateProperty() in C:\Users\grendel\Documents\Visual Studio 2010\Projects\System.Web.Test\System.Web.Test\System.ComponentModel.DataAnnotations\ValidatorTest.cs:line 283
295
296                                 Validator.TryValidateProperty ("dummy", ctx, results);
297                         }, "#A1-1");
298                         Assert.AreEqual (0, results.Count, "#A1-2");
299
300                         AssertExtensions.Throws<ArgumentNullException> (() => {
301                                 Validator.TryValidateProperty ("dummy", null, results);
302                         }, "#A1-2");
303
304                         var dummy2 = new Dummy ();
305                         ctx = new ValidationContext (dummy2, null, null) {
306                                 MemberName = "NameProperty"
307                         };
308                         
309                         bool valid = Validator.TryValidateProperty (null, ctx, results);
310                         Assert.IsTrue (valid, "#A1-3");
311                         Assert.AreEqual (0, results.Count, "#A1-4");
312
313                         ctx = new ValidationContext (dummy2, null, null) {
314                                 MemberName = "MinMaxProperty"
315                         };
316
317                         AssertExtensions.Throws<ArgumentException> (() => {
318                                 Validator.TryValidateProperty (null, ctx, results);
319                         }, "#A1-5");
320
321                         ctx = new ValidationContext (dummy2, null, null);
322                         AssertExtensions.Throws<ArgumentNullException> (() => {
323                                 // MonoTests.System.ComponentModel.DataAnnotations.ValidatorTest.TryValidateProperty:
324                                 // System.ArgumentNullException : Value cannot be null.
325                                 // Parameter name: propertyName
326                                 //
327                                 // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.TypeStoreItem.TryGetPropertyStoreItem(String propertyName, PropertyStoreItem& item)
328                                 // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.TypeStoreItem.GetPropertyStoreItem(String propertyName)
329                                 // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.GetPropertyType(ValidationContext validationContext)
330                                 // at System.ComponentModel.DataAnnotations.Validator.TryValidateProperty(Object value, ValidationContext validationContext, ICollection`1 validationResults)
331                                 // at MonoTests.System.ComponentModel.DataAnnotations.ValidatorTest.TryValidateProperty() in C:\Users\grendel\Documents\Visual Studio 2010\Projects\System.Web.Test\System.Web.Test\System.ComponentModel.DataAnnotations\ValidatorTest.cs:line 289
332
333                                 Validator.TryValidateProperty ("dummy", ctx, results);
334                         }, "#A2-1");
335                         Assert.AreEqual (0, results.Count, "#A2-2");
336
337                         ctx = new ValidationContext (dummy2, null, null) {
338                                 MemberName = String.Empty
339                         };
340
341                         AssertExtensions.Throws<ArgumentNullException> (() => {
342                                 // MonoTests.System.ComponentModel.DataAnnotations.ValidatorTest.TryValidateProperty:
343                                 // System.ArgumentNullException : Value cannot be null.
344                                 // Parameter name: propertyName
345                                 //
346                                 // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.TypeStoreItem.TryGetPropertyStoreItem(String propertyName, PropertyStoreItem& item)
347                                 // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.TypeStoreItem.GetPropertyStoreItem(String propertyName)
348                                 // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.GetPropertyType(ValidationContext validationContext)
349                                 // at System.ComponentModel.DataAnnotations.Validator.TryValidateProperty(Object value, ValidationContext validationContext, ICollection`1 validationResults)
350                                 // at MonoTests.System.ComponentModel.DataAnnotations.ValidatorTest.TryValidateProperty() in C:\Users\grendel\Documents\Visual Studio 2010\Projects\System.Web.Test\System.Web.Test\System.ComponentModel.DataAnnotations\ValidatorTest.cs:line 289
351
352                                 Validator.TryValidateProperty ("dummy", ctx, results);
353                         }, "#A2-2");
354                         Assert.AreEqual (0, results.Count, "#A2-2");
355
356                         dummy2 = new Dummy ();
357                         ctx = new ValidationContext (dummy2, null, null) {
358                                 MemberName = "NameProperty"
359                         };
360
361                         AssertExtensions.Throws<ArgumentException> (() => {
362                                 // MonoTests.System.ComponentModel.DataAnnotations.ValidatorTest.TryValidateProperty:
363                                 // System.ArgumentException : The value for property 'NameProperty' must be of type 'System.String'.
364                                 // Parameter name: value
365                                 //
366                                 // at System.ComponentModel.DataAnnotations.Validator.EnsureValidPropertyType(String propertyName, Type propertyType, Object value)
367                                 // at System.ComponentModel.DataAnnotations.Validator.TryValidateProperty(Object value, ValidationContext validationContext, ICollection`1 validationResults)
368                                 // at MonoTests.System.ComponentModel.DataAnnotations.ValidatorTest.TryValidateProperty() in C:\Users\grendel\Documents\Visual Studio 2010\Projects\System.Web.Test\System.Web.Test\System.ComponentModel.DataAnnotations\ValidatorTest.cs:line 315
369
370                                 Validator.TryValidateProperty (1234, ctx, results);
371                         }, "#A3-1");
372                         Assert.AreEqual (0, results.Count, "#A3-2");
373
374                         dummy2 = new Dummy ();
375                         ctx = new ValidationContext (dummy2, null, null) {
376                                 MemberName = "NameProperty"
377                         };
378                         
379                         valid = Validator.TryValidateProperty (String.Empty, ctx, results);
380                         Assert.IsFalse (valid, "#A4-1");
381                         Assert.AreEqual (1, results.Count, "#A4-2");
382                         results.Clear ();
383
384                         valid = Validator.TryValidateProperty ("this value is way too long", ctx, results);
385                         Assert.IsFalse (valid, "#A4-3");
386                         Assert.AreEqual (1, results.Count, "#A4-4");
387                         results.Clear ();
388
389                         valid = Validator.TryValidateProperty ("good value", ctx, results);
390                         Assert.IsTrue (valid, "#A4-5");
391                         Assert.AreEqual (0, results.Count, "#A4-6");
392
393                         dummy2 = new Dummy ();
394                         ctx = new ValidationContext (dummy2, null, null) {
395                                 MemberName = "CustomValidatedProperty"
396                         };
397
398                         valid = Validator.TryValidateProperty (String.Empty, ctx, results);
399                         Assert.IsFalse (valid, "#A5-1");
400                         Assert.AreEqual (1, results.Count, "#A5-2");
401                         results.Clear ();
402
403                         valid = Validator.TryValidateProperty ("fail", ctx, results);
404                         Assert.IsFalse (valid, "#A5-3");
405                         Assert.AreEqual (1, results.Count, "#A5-4");
406                         results.Clear ();
407
408                         valid = Validator.TryValidateProperty ("f", ctx, results);
409                         Assert.IsFalse (valid, "#A5-5");
410                         Assert.AreEqual (2, results.Count, "#A5-6");
411                         results.Clear ();
412
413                         valid = Validator.TryValidateProperty ("good value", ctx, results);
414                         Assert.IsTrue (valid, "#A5-7");
415                         Assert.AreEqual (0, results.Count, "#A5-8");
416                 }
417
418                 [Test]
419                 public void TryValidateValue_01 ()
420                 {
421                         var dummy = new DummyNoAttributes ();
422                         var ctx = new ValidationContext (dummy, null, null) {
423                                 MemberName = "NameProperty"
424                         };
425                         var results = new List<ValidationResult> ();
426                         var attributes = new List <ValidationAttribute> ();
427                         
428                         bool valid = Validator.TryValidateValue (null, ctx, results, attributes);
429                         Assert.IsTrue (valid, "#A1-1");
430                         Assert.AreEqual (0, results.Count, "#A1-2");
431
432                         AssertExtensions.Throws<ArgumentNullException> (() => {
433                                 Validator.TryValidateValue ("dummy", null, results, attributes);
434                         }, "#A2");
435
436                         valid = Validator.TryValidateValue ("dummy", ctx, null, attributes);
437                         Assert.IsTrue (valid, "#A3-1");
438                         Assert.AreEqual (0, results.Count, "#A3-2");
439
440                         AssertExtensions.Throws<ArgumentNullException> (() => {
441                                 Validator.TryValidateValue ("dummy", ctx, results, null);
442                         }, "#A4");
443                 }
444
445                 [Test]
446                 public void TryValidateValue_02 ()
447                 {
448                         var dummy = new DummyNoAttributes ();
449                         var ctx = new ValidationContext (dummy, null, null);
450                         var results = new List<ValidationResult> ();
451                         var log = new List<string> ();
452                         var attributes = new List<ValidationAttribute> () {
453                                 new StringLengthAttributePoker (10, log) {
454                                         MinimumLength = 2
455                                 },
456                                 new RequiredAttributePoker (log)
457                         };
458
459                         bool valid = Validator.TryValidateValue (null, ctx, results, attributes);
460                         Assert.IsFalse (valid, "#A1-1");
461                         Assert.AreEqual (1, results.Count, "#A1-2");
462                         Assert.AreEqual (1, log.Count, "#A1-3");
463                         Assert.IsTrue (log [0].StartsWith ("RequiredAttributePoker.IsValid (object)"), "#A1-4");
464                         results.Clear ();
465                         log.Clear ();
466
467                         AssertExtensions.Throws<InvalidCastException> (() => {
468                                 // Thrown by StringValidatorAttribute
469                                 Validator.TryValidateValue (1234, ctx, results, attributes);
470                         }, "#A2-1");
471                         Assert.AreEqual (0, results.Count, "#A2-2");
472                         Assert.AreEqual (2, log.Count, "#A2-3");
473                         Assert.IsTrue (log[0].StartsWith ("RequiredAttributePoker.IsValid (object)"), "#A2-4");
474                         Assert.IsTrue (log[1].StartsWith ("StringLengthAttributePoker.IsValid (object)"), "#A2-5");
475                         results.Clear ();
476                         log.Clear ();
477
478                         attributes.Add (new CustomValidationAttribute (typeof (ValidatorTest), "ValueValidationMethod"));
479                         attributes.Add (new CustomValidationAttribute (typeof (ValidatorTest), "ValueValidationMethod"));
480                         valid = Validator.TryValidateValue ("test", ctx, results, attributes);
481                         Assert.IsFalse (valid, "#A3-1");
482                         Assert.AreEqual (2, results.Count, "#A3-2");
483                         Assert.AreEqual (2, log.Count, "#A3-3");
484                         Assert.IsTrue (log[0].StartsWith ("RequiredAttributePoker.IsValid (object)"), "#A3-4");
485                         Assert.IsTrue (log[1].StartsWith ("StringLengthAttributePoker.IsValid (object)"), "#A3-5");
486                         Assert.AreEqual ("ValueValidationMethod", results[0].ErrorMessage, "#A3-6");
487                         Assert.AreEqual ("ValueValidationMethod", results[1].ErrorMessage, "#A3-7");
488                         results.Clear ();
489                         log.Clear ();
490                         attributes.RemoveAt (2);
491                         attributes.RemoveAt (2);
492
493                         AssertExtensions.Throws<ArgumentNullException> (() => {
494                                 Validator.TryValidateValue ("dummy", null, results, attributes);
495                         }, "#B1");
496
497                         valid = Validator.TryValidateValue ("dummy", ctx, null, attributes);
498                         Assert.IsTrue (valid, "#B2-1");
499                         Assert.AreEqual (0, results.Count, "#B2-2");
500
501                         AssertExtensions.Throws<ArgumentNullException> (() => {
502                                 Validator.TryValidateValue ("dummy", ctx, results, null);
503                         }, "#B3");
504                 }
505
506                 [Test]
507                 public void ValidateObject_Object_ValidationContext_01 ()
508                 {
509                         var dummy = new DummyNoAttributes ();
510                         var ctx = new ValidationContext (dummy, null, null);
511                         
512                         AssertExtensions.Throws<ArgumentNullException> (() => {
513                                 Validator.ValidateObject (null, ctx);
514                         }, "#A1-1");
515
516                         AssertExtensions.Throws<ArgumentNullException> (() => {
517                                 Validator.ValidateObject (dummy, null);
518                         }, "#A1-2");
519
520                         try {
521                                 Validator.ValidateObject (dummy, ctx);
522                         } catch (Exception ex) {
523                                 Assert.Fail ("#A2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
524                         }
525                 }
526
527                 [Test]
528                 public void ValidateObject_Object_ValidationContext_02 ()
529                 {
530                         var dummy = new Dummy ();
531                         var ctx = new ValidationContext (dummy, null, null);
532
533                         try {
534                                 Validator.ValidateObject (dummy, ctx);
535                         } catch (Exception ex) {
536                                 Assert.Fail ("#A1 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
537                         }
538
539                         dummy = new Dummy {
540                                 NameField = null
541                         };
542                         AssertExtensions.Throws<ArgumentException> (() => {
543                                 // The instance provided must match the ObjectInstance on the ValidationContext supplied.
544                                 Validator.ValidateObject (dummy, ctx);
545                         }, "#A2");
546
547                         // Fields are ignored
548                         ctx = new ValidationContext (dummy, null, null);
549                         try {
550                                 Validator.ValidateObject (dummy, ctx);
551                         }  catch (Exception ex) {
552                                 Assert.Fail ("#A3 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
553                         }
554                         
555                         dummy = new Dummy {
556                                 RequiredDummyField = null
557                         };
558                         ctx = new ValidationContext (dummy, null, null);
559                         try {
560                                 Validator.ValidateObject (dummy, ctx);
561                         } catch (Exception ex) {
562                                 Assert.Fail ("#A4 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
563                         }
564
565                         dummy = new Dummy {
566                                 RequiredDummyProperty = null
567                         };
568                         ctx = new ValidationContext (dummy, null, null);
569                         AssertExtensions.Throws<ValidationException> (() => {
570                                 Validator.ValidateObject (dummy, ctx);
571                         }, "#A5");
572
573                         // validation attributes other than Required are ignored
574                         dummy = new Dummy {
575                                 NameProperty = null
576                         };
577                         ctx = new ValidationContext (dummy, null, null);
578                         try {
579                                 Validator.ValidateObject (dummy, ctx);
580                         } catch (Exception ex) {
581                                 Assert.Fail ("#A6 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
582                         }
583                         
584                         dummy = new Dummy {
585                                 MinMaxProperty = 0
586                         };
587                         ctx = new ValidationContext (dummy, null, null);
588                         try {
589                                 Validator.ValidateObject (dummy, ctx);
590                         } catch (Exception ex) {
591                                 Assert.Fail ("#A7 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
592                         }
593
594                         dummy = new Dummy {
595                                 FailValidation = true
596                         };
597                         ctx = new ValidationContext (dummy, null, null);
598                         AssertExtensions.Throws<ValidationException> (() => {
599                                 Validator.ValidateObject (dummy, ctx);
600                         }, "#A8");
601
602                         var dummy2 = new DummyMultipleCustomValidators ();
603                         ctx = new ValidationContext (dummy2, null, null);
604                         try {
605                                 Validator.ValidateObject (dummy2, ctx);
606                         } catch (Exception ex) {
607                                 Assert.Fail ("#A9 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
608                         }
609                 }
610
611                 [Test]
612                 public void ValidateObject_Object_ValidationContext_Bool_01 ()
613                 {
614                         var dummy = new DummyNoAttributes ();
615                         var ctx = new ValidationContext (dummy, null, null);
616
617                         AssertExtensions.Throws<ArgumentNullException> (() => {
618                                 Validator.ValidateObject (null, ctx, false);
619                         }, "#A1-1");
620
621                         AssertExtensions.Throws<ArgumentNullException> (() => {
622                                 Validator.ValidateObject (dummy, null, false);
623                         }, "#A1-2");
624
625                         try {
626                                 Validator.ValidateObject (dummy, ctx, false);
627                         } catch (Exception ex) {
628                                 Assert.Fail ("#A2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
629                         }
630
631                         try {
632                                 Validator.ValidateObject (dummy, ctx, true);
633                         } catch (Exception ex) {
634                                 Assert.Fail ("#A3 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
635                         }
636                 }
637
638                 [Test]
639                 public void ValidateObject_Object_ValidationContext_Bool_02 ()
640                 {
641                         var dummy = new Dummy ();
642                         var ctx = new ValidationContext (dummy, null, null);
643
644                         try {
645                                 Validator.ValidateObject (dummy, ctx, false);
646                         } catch (Exception ex) {
647                                 Assert.Fail ("#A1 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
648                         }
649
650                         try {
651                                 Validator.ValidateObject (dummy, ctx, true);
652                         } catch (Exception ex) {
653                                 Assert.Fail ("#A2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
654                         }
655
656                         dummy = new Dummy {
657                                 NameField = null
658                         };
659                         AssertExtensions.Throws<ArgumentException> (() => {
660                                 // The instance provided must match the ObjectInstance on the ValidationContext supplied.
661                                 Validator.ValidateObject (dummy, ctx, false);
662                         }, "#A3-1");
663
664                         AssertExtensions.Throws<ArgumentException> (() => {
665                                 // The instance provided must match the ObjectInstance on the ValidationContext supplied.
666                                 Validator.ValidateObject (dummy, ctx, true);
667                         }, "#A3-2");
668
669                         // Fields are ignored
670                         ctx = new ValidationContext (dummy, null, null);
671                         try {
672                                 Validator.ValidateObject (dummy, ctx, false);
673                         } catch (Exception ex) {
674                                 Assert.Fail ("#A4-1 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
675                         }
676
677                         try {
678                                 Validator.ValidateObject (dummy, ctx, true);
679                         } catch (Exception ex) {
680                                 Assert.Fail ("#A4-2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
681                         }
682
683                         dummy = new Dummy {
684                                 RequiredDummyField = null
685                         };
686                         ctx = new ValidationContext (dummy, null, null);
687                         try {
688                                 Validator.ValidateObject (dummy, ctx, false);
689                         } catch (Exception ex) {
690                                 Assert.Fail ("#A5-1 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
691                         }
692
693                         try {
694                                 Validator.ValidateObject (dummy, ctx, true);
695                         } catch (Exception ex) {
696                                 Assert.Fail ("#A5-2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
697                         }
698
699                         // Required properties existence is validated
700                         dummy = new Dummy {
701                                 RequiredDummyProperty = null
702                         };
703                         ctx = new ValidationContext (dummy, null, null);
704                         AssertExtensions.Throws<ValidationException> (() => {
705                                 Validator.ValidateObject (dummy, ctx, false);
706                         }, "#A6-1");
707
708                         AssertExtensions.Throws<ValidationException> (() => {
709                                 Validator.ValidateObject (dummy, ctx, true);
710                         }, "#A6-2");
711
712                         dummy = new Dummy {
713                                 NameProperty = null
714                         };
715                         ctx = new ValidationContext (dummy, null, null);
716                         try {
717                                 Validator.ValidateObject (dummy, ctx, false);
718                         } catch (Exception ex) {
719                                 Assert.Fail ("#A7 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
720                         }
721
722                         // NameProperty is null, that causes the StringLength validator to skip its tests
723                         try {
724                                 Validator.ValidateObject (dummy, ctx, true);
725                         } catch (Exception ex) {
726                                 Assert.Fail ("#A8 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
727                         }
728
729                         dummy.NameProperty = "0";
730                         AssertExtensions.Throws<ValidationException> (() => {
731                                 Validator.ValidateObject (dummy, ctx, true);
732                         }, "#A9");
733
734                         dummy.NameProperty = "name too long (invalid value)";
735                         AssertExtensions.Throws<ValidationException> (() => {
736                                 Validator.ValidateObject (dummy, ctx, true);
737                         }, "#A10");
738
739                         dummy = new Dummy {
740                                 MinMaxProperty = 0
741                         };
742                         ctx = new ValidationContext (dummy, null, null);
743                         try {
744                                 Validator.ValidateObject (dummy, ctx, false);
745                         } catch (Exception ex) {
746                                 Assert.Fail ("#A11 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
747                         }
748
749                         AssertExtensions.Throws<ValidationException> (() => {
750                                 Validator.ValidateObject (dummy, ctx, true);
751                         }, "#A12");
752
753                         dummy = new Dummy {
754                                 FailValidation = true
755                         };
756                         ctx = new ValidationContext (dummy, null, null);
757                         AssertExtensions.Throws<ValidationException> (() => {
758                                 Validator.ValidateObject (dummy, ctx, false);
759                         }, "#A13-1");
760
761                         AssertExtensions.Throws<ValidationException> (() => {
762                                 Validator.ValidateObject (dummy, ctx, true);
763                         }, "#A13-2");
764
765                         var dummy2 = new DummyWithException ();
766                         ctx = new ValidationContext (dummy2, null, null);
767                         AssertExtensions.Throws<ApplicationException> (() => {
768                                 Validator.ValidateObject (dummy2, ctx, true);
769                         }, "#A14");
770
771                         var dummy3 = new DummyMultipleCustomValidators ();
772                         ctx = new ValidationContext (dummy3, null, null);
773                         try {
774                                 Validator.ValidateObject (dummy3, ctx, false);
775                         } catch (Exception ex) {
776                                 Assert.Fail ("#A9 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
777                         }
778
779                         try {
780                                 Validator.ValidateObject (dummy3, ctx, true);
781                         } catch (ValidationException ex) {
782                                 Assert.AreEqual ("FirstPropertyValidationMethod", ex.Message, "#A10");
783                         } catch (Exception ex) {
784                                 Assert.Fail ("#A10 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
785                         }
786                 }
787
788                 [Test]
789                 public void ValidateProperty ()
790                 {
791                         var dummy = new DummyNoAttributes ();
792                         var ctx = new ValidationContext (dummy, null, null) {
793                                 MemberName = "NameProperty"
794                         };
795
796                         AssertExtensions.Throws<ArgumentException> (() => {
797                                 Validator.ValidateProperty ("dummy", ctx);
798                         }, "#A1-1");
799
800                         AssertExtensions.Throws<ArgumentNullException> (() => {
801                                 Validator.ValidateProperty ("dummy", null);
802                         }, "#A1-2");
803
804                         var dummy2 = new Dummy ();
805                         ctx = new ValidationContext (dummy2, null, null) {
806                                 MemberName = "NameProperty"
807                         };
808
809                         try {
810                                 Validator.ValidateProperty (null, ctx);
811                         } catch (Exception ex) {
812                                 Assert.Fail ("#A2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
813                         }
814
815                         ctx = new ValidationContext (dummy2, null, null) {
816                                 MemberName = "MinMaxProperty"
817                         };
818
819                         AssertExtensions.Throws<ArgumentException> (() => {
820                                 Validator.ValidateProperty (null, ctx);
821                         }, "#A3");
822
823                         ctx = new ValidationContext (dummy2, null, null);
824                         AssertExtensions.Throws<ArgumentNullException> (() => {
825                                 Validator.ValidateProperty ("dummy", ctx);
826                         }, "#A4");
827
828                         ctx = new ValidationContext (dummy2, null, null) {
829                                 MemberName = String.Empty
830                         };
831
832                         AssertExtensions.Throws<ArgumentNullException> (() => {
833                                 Validator.ValidateProperty ("dummy", ctx);
834                         }, "#A5");
835
836                         dummy2 = new Dummy ();
837                         ctx = new ValidationContext (dummy2, null, null) {
838                                 MemberName = "NameProperty"
839                         };
840
841                         AssertExtensions.Throws<ArgumentException> (() => {
842                                 Validator.ValidateProperty (1234, ctx);
843                         }, "#A6");
844
845                         dummy2 = new Dummy ();
846                         ctx = new ValidationContext (dummy2, null, null) {
847                                 MemberName = "NameProperty"
848                         };
849
850                         AssertExtensions.Throws<ValidationException> (() => {
851                                 Validator.ValidateProperty (String.Empty, ctx);
852                         }, "#A7");
853
854                         AssertExtensions.Throws<ValidationException> (() => {
855                                 Validator.ValidateProperty ("this value is way too long", ctx);
856                         }, "#A8");
857
858                         try {
859                                 Validator.ValidateProperty ("good value", ctx);
860                         } catch (Exception ex) {
861                                 Assert.Fail ("#A9 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
862                         }
863
864                         dummy2 = new Dummy ();
865                         ctx = new ValidationContext (dummy2, null, null) {
866                                 MemberName = "CustomValidatedProperty"
867                         };
868
869                         AssertExtensions.Throws<ValidationException> (() => {
870                                 Validator.ValidateProperty (String.Empty, ctx);
871                         }, "#A10");
872
873                         AssertExtensions.Throws<ValidationException> (() => {
874                                 Validator.ValidateProperty ("fail", ctx);
875                         }, "#A11");
876
877                         AssertExtensions.Throws<ValidationException> (() => {
878                                 Validator.ValidateProperty ("f", ctx);
879                         }, "#A12");
880
881                         try {
882                                 Validator.ValidateProperty ("good value", ctx);
883                         } catch (Exception ex) {
884                                 Assert.Fail ("#A13 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
885                         }
886                 }
887
888                 [Test]
889                 public void ValidateValue_01 ()
890                 {
891                         var dummy = new DummyNoAttributes ();
892                         var ctx = new ValidationContext (dummy, null, null) {
893                                 MemberName = "NameProperty"
894                         };
895                         var attributes = new List<ValidationAttribute> ();
896
897                         try {
898                                 Validator.ValidateValue (null, ctx, attributes);
899                         } catch (Exception ex) {
900                                 Assert.Fail ("#A1 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
901                         }
902
903                         AssertExtensions.Throws<ArgumentNullException> (() => {
904                                 Validator.ValidateValue ("dummy", null, attributes);
905                         }, "#A2");
906
907                         try {
908                                 Validator.ValidateValue ("dummy", ctx, attributes);
909                         } catch (Exception ex) {
910                                 Assert.Fail ("#A3 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
911                         }
912
913                         AssertExtensions.Throws<ArgumentNullException> (() => {
914                                 Validator.ValidateValue ("dummy", ctx, null);
915                         }, "#A4");
916                 }
917
918                 [Test]
919                 public void ValidateValue_02 ()
920                 {
921                         var dummy = new DummyNoAttributes ();
922                         var ctx = new ValidationContext (dummy, null, null);
923                         var log = new List<string> ();
924                         var attributes = new List<ValidationAttribute> () {
925                                 new StringLengthAttributePoker (10, log) {
926                                         MinimumLength = 2
927                                 },
928                                 new RequiredAttributePoker (log)
929                         };
930
931                         AssertExtensions.Throws<ValidationException> (() => {
932                                 Validator.ValidateValue (null, ctx, attributes);
933                         }, "#A1-1");
934                         Assert.AreEqual (1, log.Count, "#A1-2");
935                         Assert.IsTrue (log[0].StartsWith ("RequiredAttributePoker.IsValid (object)"), "#A1-3");
936                         log.Clear ();
937
938                         AssertExtensions.Throws<InvalidCastException> (() => {
939                                 // Thrown by StringValidatorAttribute
940                                 Validator.ValidateValue (1234, ctx, attributes);
941                         }, "#A2-1");;
942                         Assert.AreEqual (2, log.Count, "#A2-2");
943                         Assert.IsTrue (log[0].StartsWith ("RequiredAttributePoker.IsValid (object)"), "#A2-3");
944                         Assert.IsTrue (log[1].StartsWith ("StringLengthAttributePoker.IsValid (object)"), "#A2-4");
945                         log.Clear ();
946
947                         attributes.Add (new CustomValidationAttribute (typeof (ValidatorTest), "ValueValidationMethod"));
948                         attributes.Add (new CustomValidationAttribute (typeof (ValidatorTest), "ValueValidationMethod"));
949                         AssertExtensions.Throws<ValidationException> (() => {
950                                 Validator.ValidateValue ("test", ctx, attributes);
951                         }, "#A3-1");
952                         Assert.AreEqual (2, log.Count, "#A3-2");
953                         Assert.IsTrue (log[0].StartsWith ("RequiredAttributePoker.IsValid (object)"), "#A3-3");
954                         Assert.IsTrue (log[1].StartsWith ("StringLengthAttributePoker.IsValid (object)"), "#A3-4");
955                         log.Clear ();
956                         attributes.RemoveAt (2);
957                         attributes.RemoveAt (2);
958
959                         AssertExtensions.Throws<ArgumentNullException> (() => {
960                                 Validator.ValidateValue ("dummy", null, attributes);
961                         }, "#B1");
962
963                         try {
964                                 Validator.ValidateValue ("dummy", ctx, attributes);
965                         } catch (Exception ex) {
966                                 Assert.Fail ("#B2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
967                         }
968
969                         AssertExtensions.Throws<ArgumentNullException> (() => {
970                                 Validator.ValidateValue ("dummy", ctx, null);
971                         }, "#B3");
972                 }
973                 
974                 [Test]
975                 public void TryValidateValue_Throws_ValidationException_When_Property_Is_NullableAndRequired_And_Value_Is_Null ()
976                 {
977                         EntityMock entity = new EntityMock ();
978                         ICollection<ValidationResult> result = new List<ValidationResult>();
979
980                         ICollection<ValidationAttribute> attributes = new List<ValidationAttribute> ();
981                         attributes.Add (new RequiredAttribute ());
982
983                         // Year = null
984                         bool isValid = Validator.TryValidateValue (null, new ValidationContext (entity, null, null) { MemberName = "Year" }, result, attributes);
985
986                         Assert.IsFalse (isValid, "#A1-1");
987                         Assert.AreEqual (1, result.Count, "#A1-2");
988
989                         // Name = null, string
990                         result.Clear ();
991
992                         isValid = Validator.TryValidateValue (null, new ValidationContext (entity, null, null) { MemberName =  "Name" }, result, attributes);
993
994                         Assert.IsFalse (isValid, "#A2-1");
995                         Assert.AreEqual (1, result.Count, "#A2-2");
996
997                         // Name = string.Empty, string
998                         result.Clear ();
999
1000                         isValid = Validator.TryValidateValue (String.Empty, new ValidationContext (entity, null, null) { MemberName = "Name" }, result, attributes);
1001
1002                         Assert.IsFalse (isValid, "#A3-1");
1003                         Assert.AreEqual (1, result.Count, "#A3-2");
1004                 }
1005
1006                 [Test]
1007                 public void TryValidateProperty_Throws_ValidationException_When_Property_Is_NullableAndRequired_And_Value_Is_Null ()
1008                 {
1009                         EntityMock entity = new EntityMock ();
1010                         ICollection<ValidationResult> result = new List<ValidationResult> ();
1011
1012                         // Year = null
1013                         bool isValid = Validator.TryValidateProperty (null, new ValidationContext (entity, null, null) { MemberName = "Year" }, result);
1014
1015                         Assert.IsFalse (isValid, "#A1-1");
1016                         Assert.AreEqual (1, result.Count, "#A1-2");
1017
1018                         // Name = null, string
1019                         result.Clear ();
1020
1021                         isValid = Validator.TryValidateProperty (null, new ValidationContext (entity, null, null) { MemberName = "Name" }, result);
1022
1023                         Assert.IsFalse (isValid, "#A2-1");
1024                         Assert.AreEqual (1, result.Count, "#A2-2");
1025
1026                         // Name = string.Empty, string
1027                         result.Clear ();
1028
1029                         isValid = Validator.TryValidateProperty (String.Empty, new ValidationContext (entity, null, null) { MemberName = "Name" }, result);
1030
1031                         Assert.IsFalse (isValid, "#A3-1");
1032                         Assert.AreEqual (1, result.Count, "#A3-2");
1033                 }
1034
1035                 [Test]
1036                 public void TryValidateObject_Throws_ValidationException_When_Property_Is_NullableAndRequired_And_Value_Is_Null ()
1037                 {
1038                         EntityMock entity = new EntityMock ();
1039                         ICollection<ValidationResult> result = new List<ValidationResult> ();
1040
1041                         // Year = null
1042                         bool isValid = Validator.TryValidateObject (entity, new ValidationContext (entity, null, null), result);
1043
1044                         Assert.IsFalse (isValid, "#A1-1");
1045                         Assert.AreEqual (2, result.Count, "#A1-2");
1046
1047                         // Name = null, string
1048                         result.Clear ();
1049
1050                         isValid = Validator.TryValidateObject (entity, new ValidationContext (entity, null, null), result);
1051
1052                         Assert.IsFalse (isValid, "#A2-1");
1053                         Assert.AreEqual (2, result.Count, "#A2-2");
1054
1055                         // Name = string.Empty, string
1056                         result.Clear ();
1057
1058                         entity.Name = String.Empty;
1059                         isValid = Validator.TryValidateObject (entity, new ValidationContext (entity, null, null), result);
1060
1061                         Assert.IsFalse (isValid, "#A3-1");
1062                         Assert.AreEqual (2, result.Count, "#A3-2");
1063                 }
1064
1065                 public static ValidationResult DummyValidationMethod (object o)
1066                 {
1067                         var dummy = o as Dummy;
1068                         if (dummy == null)
1069                                 return new ValidationResult ("Invalid DummyValidationMethod input - broken test?");
1070
1071                         if (dummy.FailValidation)
1072                                 return new ValidationResult ("Dummy validation failed.");
1073                         return ValidationResult.Success;
1074                 }
1075
1076                 public static ValidationResult CustomValidatedPropertyValidationMethod (object o)
1077                 {
1078                         var dummy = o as string;
1079                         if (dummy != null && (dummy == "f" || dummy == "fail"))
1080                                 return new ValidationResult ("Dummy.CustomValidatedProperty validation failed.");
1081                         return ValidationResult.Success;
1082                 }
1083
1084                 public static ValidationResult ValidationMethodException (object o)
1085                 {
1086                         throw new ApplicationException ("SNAFU");
1087                 }
1088
1089                 public static ValidationResult ValueValidationMethod (object o, ValidationContext validationContext)
1090                 {
1091                         return new ValidationResult ("ValueValidationMethod");
1092                 }
1093
1094                 public static ValidationResult FirstPropertyValidationMethod (object o, ValidationContext validationContext)
1095                 {
1096                         return new ValidationResult ("FirstPropertyValidationMethod");
1097                 }
1098
1099                 public static ValidationResult SecondPropertyValidationMethod (object o, ValidationContext validationContext)
1100                 {
1101                         return new ValidationResult ("SecondPropertyValidationMethod");
1102                 }
1103
1104                 public class RequiredAttributePoker : RequiredAttribute
1105                 {
1106                         List <string> log;
1107
1108                         public RequiredAttributePoker (List<string> log)
1109                         {
1110                                 if (log == null)
1111                                         throw new ArgumentNullException ("log");
1112                                 this.log = log;
1113                         }
1114
1115                         public override bool IsValid (object value)
1116                         {
1117                                 log.Add ("RequiredAttributePoker.IsValid (object)");
1118                                 return base.IsValid (value);
1119                         }
1120                 }
1121
1122                 public class StringLengthAttributePoker : StringLengthAttribute
1123                 {
1124                         List <string> log;
1125
1126                         public StringLengthAttributePoker (int maximumLength, List<string> log)
1127                                 : base (maximumLength)
1128                         {
1129                                 if (log == null)
1130                                         throw new ArgumentNullException ("log");
1131                                 this.log = log;
1132                         }
1133
1134                         public override bool IsValid (object value)
1135                         {
1136                                 log.Add ("StringLengthAttributePoker.IsValid (object)");
1137                                 return base.IsValid (value);
1138                         }
1139                 }
1140
1141                 class DummyNoAttributes
1142                 { }
1143
1144                 [CustomValidation (typeof (ValidatorTest), "DummyValidationMethod")]
1145                 class Dummy
1146                 {
1147                         [StringLength (10, MinimumLength=2)]
1148                         public string NameField;
1149
1150                         [Required]
1151                         public DummyNoAttributes RequiredDummyField;
1152
1153                         [StringLength (10, MinimumLength = 2)]
1154                         public string NameProperty { get; set; }
1155
1156                         [Required]
1157                         public DummyNoAttributes RequiredDummyProperty { get; set; }
1158                         
1159                         [global::System.ComponentModel.DataAnnotations.RangeAttribute ((int)1, (int)10)]
1160                         public int MinMaxProperty { get; set; }
1161
1162                         [StringLength (10, MinimumLength = 2)]
1163                         [CustomValidation (typeof (ValidatorTest), "CustomValidatedPropertyValidationMethod")]
1164                         public string CustomValidatedProperty { get; set; }
1165
1166                         [CustomValidation (typeof (ValidatorTest), "CustomValidatedPropertyValidationMethod")]
1167                         [StringLength (10, MinimumLength = 2)]
1168                         public string AnotherCustomValidatedProperty { get; set; }
1169
1170                         public bool FailValidation { get; set; }
1171
1172                         public Dummy ()
1173                         {
1174                                 NameField = "name";
1175                                 NameProperty = "name";
1176                                 RequiredDummyField = new DummyNoAttributes ();
1177                                 RequiredDummyProperty = new DummyNoAttributes ();
1178                                 MinMaxProperty = 5;
1179                                 AnotherCustomValidatedProperty = "I'm valid";
1180                         }
1181                 }
1182
1183                 class DummyWithException
1184                 {
1185                         [CustomValidation (typeof (ValidatorTest), "ValidationMethodException")]
1186                         public string AnotherCustomValidatedProperty { get; set; }
1187                 }
1188
1189                 class DummyForValueValidation
1190                 {
1191                         public string DummyNoAttributes;
1192
1193                         public DummyForValueValidation ()
1194                         {
1195                                 this.DummyNoAttributes = "I am valid";
1196                         }
1197                 }
1198
1199                 class DummyMultipleCustomValidators
1200                 {
1201                         [CustomValidation (typeof (ValidatorTest), "FirstPropertyValidationMethod")]
1202                         public string FirstProperty { get; set; }
1203
1204                         [CustomValidation (typeof (ValidatorTest), "SecondPropertyValidationMethod")]
1205                         public string SecondProperty { get; set; }
1206                 }
1207                 
1208                 class EntityMock
1209                 {
1210                         private int? _year;
1211
1212                         [Required]
1213                         public int? Year
1214                         {
1215                                 get { return _year; }
1216                                 set
1217                                 {
1218                                         _year = value;
1219                                 }
1220                         }
1221
1222                         private string _name;
1223
1224                         [Required]
1225                         public string Name
1226                         {
1227                                 get { return _name; }
1228                                 set
1229                                 {
1230                                         _name = value;
1231                                 }
1232                         }
1233                 }
1234         }
1235 }