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