PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/System.ComponentModel.DataAnnotations/Test/System.ComponentModel.DataAnnotations/ValidatorTest.cs

https://bitbucket.org/danipen/mono
C# | 1120 lines | 864 code | 179 blank | 77 comment | 16 complexity | 7a1b87b69fa8c9752614f4884f52efbf MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  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.ComponentModel.Design;
  30. using System.Text;
  31. using NUnit.Framework;
  32. using MonoTests.Common;
  33. namespace MonoTests.System.ComponentModel.DataAnnotations
  34. {
  35. #if NET_4_0
  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. AssertExtensions.Throws<ArgumentNullException> (() => {
  46. Validator.TryValidateObject (null, ctx, results);
  47. }, "#A1-1");
  48. AssertExtensions.Throws<ArgumentNullException> (() => {
  49. Validator.TryValidateObject (dummy, null, results);
  50. }, "#A1-2");
  51. bool valid = Validator.TryValidateObject (dummy, ctx, null);
  52. Assert.IsTrue (valid, "#A2-1");
  53. Assert.IsTrue (results.Count == 0, "#A2-2");
  54. }
  55. [Test]
  56. public void TryValidateObject_Object_ValidationContext_ICollection_02 ()
  57. {
  58. var dummy = new Dummy ();
  59. var ctx = new ValidationContext (dummy, null, null);
  60. var results = new List<ValidationResult> ();
  61. bool valid = Validator.TryValidateObject (dummy, ctx, results);
  62. Assert.IsTrue (valid, "#A1-1");
  63. Assert.AreEqual (0, results.Count, "#A1-2");
  64. dummy = new Dummy {
  65. NameField = null
  66. };
  67. AssertExtensions.Throws<ArgumentException> (() => {
  68. // The instance provided must match the ObjectInstance on the ValidationContext supplied.
  69. valid = Validator.TryValidateObject (dummy, ctx, results);
  70. }, "#A2");
  71. // Fields are ignored
  72. ctx = new ValidationContext (dummy, null, null);
  73. valid = Validator.TryValidateObject (dummy, ctx, results);
  74. Assert.IsTrue (valid, "#A3-1");
  75. Assert.AreEqual (0, results.Count, "#A3-2");
  76. // Required properties existence is validated
  77. dummy = new Dummy {
  78. RequiredDummyField = null
  79. };
  80. ctx = new ValidationContext (dummy, null, null);
  81. valid = Validator.TryValidateObject (dummy, ctx, results);
  82. Assert.IsTrue (valid, "#A4-1");
  83. Assert.AreEqual (0, results.Count, "#A4-2");
  84. dummy = new Dummy {
  85. RequiredDummyProperty = null
  86. };
  87. ctx = new ValidationContext (dummy, null, null);
  88. valid = Validator.TryValidateObject (dummy, ctx, results);
  89. Assert.IsFalse (valid, "#A5-1");
  90. Assert.AreEqual (1, results.Count, "#A5-2");
  91. results.Clear ();
  92. // validation attributes other than Required are ignored
  93. dummy = new Dummy {
  94. NameProperty = null
  95. };
  96. ctx = new ValidationContext (dummy, null, null);
  97. valid = Validator.TryValidateObject (dummy, ctx, results);
  98. Assert.IsTrue (valid, "#A6-1");
  99. Assert.AreEqual (0, results.Count, "#A6-2");
  100. dummy = new Dummy {
  101. MinMaxProperty = 0
  102. };
  103. ctx = new ValidationContext (dummy, null, null);
  104. valid = Validator.TryValidateObject (dummy, ctx, results);
  105. Assert.IsTrue (valid, "#A7-1");
  106. Assert.AreEqual (0, results.Count, "#A7-2");
  107. dummy = new Dummy {
  108. FailValidation = true
  109. };
  110. ctx = new ValidationContext (dummy, null, null);
  111. valid = Validator.TryValidateObject (dummy, ctx, results);
  112. Assert.IsFalse (valid, "#A8-1");
  113. Assert.AreEqual (1, results.Count, "#A8-2");
  114. }
  115. [Test]
  116. public void TryValidateObject_Object_ValidationContext_ICollection_Bool_01 ()
  117. {
  118. var dummy = new DummyNoAttributes ();
  119. var ctx = new ValidationContext (dummy, null, null);
  120. var results = new List<ValidationResult> ();
  121. AssertExtensions.Throws<ArgumentNullException> (() => {
  122. Validator.TryValidateObject (null, ctx, results, false);
  123. }, "#A1-1");
  124. AssertExtensions.Throws<ArgumentNullException> (() => {
  125. Validator.TryValidateObject (dummy, null, results, false);
  126. }, "#A1-2");
  127. bool valid = Validator.TryValidateObject (dummy, ctx, null, false);
  128. Assert.IsTrue (valid, "#A2-1");
  129. Assert.IsTrue (results.Count == 0, "#A2-2");
  130. valid = Validator.TryValidateObject (dummy, ctx, null, true);
  131. Assert.IsTrue (valid, "#A3-1");
  132. Assert.IsTrue (results.Count == 0, "#A3-2");
  133. }
  134. [Test]
  135. public void TryValidateObject_Object_ValidationContext_ICollection_Bool_02 ()
  136. {
  137. var dummy = new Dummy ();
  138. var ctx = new ValidationContext (dummy, null, null);
  139. var results = new List<ValidationResult> ();
  140. bool valid = Validator.TryValidateObject (dummy, ctx, results, false);
  141. Assert.IsTrue (valid, "#A1-1");
  142. Assert.AreEqual (0, results.Count, "#A1-2");
  143. valid = Validator.TryValidateObject (dummy, ctx, results, true);
  144. Assert.IsTrue (valid, "#A1-3");
  145. Assert.AreEqual (0, results.Count, "#A1-4");
  146. dummy = new Dummy {
  147. NameField = null
  148. };
  149. AssertExtensions.Throws<ArgumentException> (() => {
  150. // The instance provided must match the ObjectInstance on the ValidationContext supplied.
  151. valid = Validator.TryValidateObject (dummy, ctx, results, false);
  152. }, "#A2-1");
  153. AssertExtensions.Throws<ArgumentException> (() => {
  154. // The instance provided must match the ObjectInstance on the ValidationContext supplied.
  155. valid = Validator.TryValidateObject (dummy, ctx, results, true);
  156. }, "#A2-2");
  157. // Fields are ignored
  158. ctx = new ValidationContext (dummy, null, null);
  159. valid = Validator.TryValidateObject (dummy, ctx, results, false);
  160. Assert.IsTrue (valid, "#A3-1");
  161. Assert.AreEqual (0, results.Count, "#A3-2");
  162. valid = Validator.TryValidateObject (dummy, ctx, results, true);
  163. Assert.IsTrue (valid, "#A3-3");
  164. Assert.AreEqual (0, results.Count, "#A3-4");
  165. dummy = new Dummy {
  166. RequiredDummyField = null
  167. };
  168. ctx = new ValidationContext (dummy, null, null);
  169. valid = Validator.TryValidateObject (dummy, ctx, results, false);
  170. Assert.IsTrue (valid, "#A4-1");
  171. Assert.AreEqual (0, results.Count, "#A4-2");
  172. valid = Validator.TryValidateObject (dummy, ctx, results, true);
  173. Assert.IsTrue (valid, "#A4-3");
  174. Assert.AreEqual (0, results.Count, "#A4-4");
  175. // Required properties existence is validated
  176. dummy = new Dummy {
  177. RequiredDummyProperty = null
  178. };
  179. ctx = new ValidationContext (dummy, null, null);
  180. valid = Validator.TryValidateObject (dummy, ctx, results, false);
  181. Assert.IsFalse (valid, "#A5-1");
  182. Assert.AreEqual (1, results.Count, "#A5-2");
  183. results.Clear ();
  184. valid = Validator.TryValidateObject (dummy, ctx, results, true);
  185. Assert.IsFalse (valid, "#A5-3");
  186. Assert.AreEqual (1, results.Count, "#A5-4");
  187. results.Clear ();
  188. dummy = new Dummy {
  189. NameProperty = null
  190. };
  191. ctx = new ValidationContext (dummy, null, null);
  192. valid = Validator.TryValidateObject (dummy, ctx, results, false);
  193. Assert.IsTrue (valid, "#A6-1");
  194. Assert.AreEqual (0, results.Count, "#A6-2");
  195. // NameProperty is null, that causes the StringLength validator to skip its tests
  196. valid = Validator.TryValidateObject (dummy, ctx, results, true);
  197. Assert.IsTrue (valid, "#A6-3");
  198. Assert.AreEqual (0, results.Count, "#A6-4");
  199. dummy.NameProperty = "0";
  200. valid = Validator.TryValidateObject (dummy, ctx, results, true);
  201. Assert.IsFalse (valid, "#A6-5");
  202. Assert.AreEqual (1, results.Count, "#A6-6");
  203. results.Clear ();
  204. dummy.NameProperty = "name too long (invalid value)";
  205. valid = Validator.TryValidateObject (dummy, ctx, results, true);
  206. Assert.IsFalse (valid, "#A6-7");
  207. Assert.AreEqual (1, results.Count, "#A6-8");
  208. results.Clear ();
  209. dummy = new Dummy {
  210. MinMaxProperty = 0
  211. };
  212. ctx = new ValidationContext (dummy, null, null);
  213. valid = Validator.TryValidateObject (dummy, ctx, results, false);
  214. Assert.IsTrue (valid, "#A7-1");
  215. Assert.AreEqual (0, results.Count, "#A7-2");
  216. valid = Validator.TryValidateObject (dummy, ctx, results, true);
  217. Assert.IsFalse (valid, "#A7-3");
  218. Assert.AreEqual (1, results.Count, "#A7-4");
  219. results.Clear ();
  220. dummy = new Dummy {
  221. FailValidation = true
  222. };
  223. ctx = new ValidationContext (dummy, null, null);
  224. valid = Validator.TryValidateObject (dummy, ctx, results, false);
  225. Assert.IsFalse (valid, "#A8-1");
  226. Assert.AreEqual (1, results.Count, "#A8-2");
  227. results.Clear ();
  228. valid = Validator.TryValidateObject (dummy, ctx, results, true);
  229. Assert.IsFalse (valid, "#A8-3");
  230. Assert.AreEqual (1, results.Count, "#A8-4");
  231. results.Clear ();
  232. var dummy2 = new DummyWithException ();
  233. ctx = new ValidationContext (dummy2, null, null);
  234. AssertExtensions.Throws<ApplicationException> (() => {
  235. Validator.TryValidateObject (dummy2, ctx, results, true);
  236. }, "#A9");
  237. }
  238. [Test]
  239. public void TryValidateProperty ()
  240. {
  241. var dummy = new DummyNoAttributes ();
  242. var ctx = new ValidationContext (dummy, null, null) {
  243. MemberName = "NameProperty"
  244. };
  245. var results = new List<ValidationResult> ();
  246. AssertExtensions.Throws<ArgumentException> (() => {
  247. // MonoTests.System.ComponentModel.DataAnnotations.ValidatorTest.TryValidateProperty:
  248. // System.ArgumentException : The type 'DummyNoAttributes' does not contain a public property named 'NameProperty'.
  249. // Parameter name: propertyName
  250. //
  251. // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.TypeStoreItem.GetPropertyStoreItem(String propertyName)
  252. // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.GetPropertyType(ValidationContext validationContext)
  253. // at System.ComponentModel.DataAnnotations.Validator.TryValidateProperty(Object value, ValidationContext validationContext, ICollection`1 validationResults)
  254. // 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
  255. Validator.TryValidateProperty ("dummy", ctx, results);
  256. }, "#A1-1");
  257. Assert.AreEqual (0, results.Count, "#A1-2");
  258. AssertExtensions.Throws<ArgumentNullException> (() => {
  259. Validator.TryValidateProperty ("dummy", null, results);
  260. }, "#A1-2");
  261. var dummy2 = new Dummy ();
  262. ctx = new ValidationContext (dummy2, null, null) {
  263. MemberName = "NameProperty"
  264. };
  265. bool valid = Validator.TryValidateProperty (null, ctx, results);
  266. Assert.IsTrue (valid, "#A1-3");
  267. Assert.AreEqual (0, results.Count, "#A1-4");
  268. ctx = new ValidationContext (dummy2, null, null) {
  269. MemberName = "MinMaxProperty"
  270. };
  271. AssertExtensions.Throws<ArgumentException> (() => {
  272. Validator.TryValidateProperty (null, ctx, results);
  273. }, "#A1-5");
  274. ctx = new ValidationContext (dummy2, null, null);
  275. AssertExtensions.Throws<ArgumentNullException> (() => {
  276. // MonoTests.System.ComponentModel.DataAnnotations.ValidatorTest.TryValidateProperty:
  277. // System.ArgumentNullException : Value cannot be null.
  278. // Parameter name: propertyName
  279. //
  280. // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.TypeStoreItem.TryGetPropertyStoreItem(String propertyName, PropertyStoreItem& item)
  281. // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.TypeStoreItem.GetPropertyStoreItem(String propertyName)
  282. // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.GetPropertyType(ValidationContext validationContext)
  283. // at System.ComponentModel.DataAnnotations.Validator.TryValidateProperty(Object value, ValidationContext validationContext, ICollection`1 validationResults)
  284. // 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
  285. Validator.TryValidateProperty ("dummy", ctx, results);
  286. }, "#A2-1");
  287. Assert.AreEqual (0, results.Count, "#A2-2");
  288. ctx = new ValidationContext (dummy2, null, null) {
  289. MemberName = String.Empty
  290. };
  291. AssertExtensions.Throws<ArgumentNullException> (() => {
  292. // MonoTests.System.ComponentModel.DataAnnotations.ValidatorTest.TryValidateProperty:
  293. // System.ArgumentNullException : Value cannot be null.
  294. // Parameter name: propertyName
  295. //
  296. // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.TypeStoreItem.TryGetPropertyStoreItem(String propertyName, PropertyStoreItem& item)
  297. // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.TypeStoreItem.GetPropertyStoreItem(String propertyName)
  298. // at System.ComponentModel.DataAnnotations.ValidationAttributeStore.GetPropertyType(ValidationContext validationContext)
  299. // at System.ComponentModel.DataAnnotations.Validator.TryValidateProperty(Object value, ValidationContext validationContext, ICollection`1 validationResults)
  300. // 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
  301. Validator.TryValidateProperty ("dummy", ctx, results);
  302. }, "#A2-2");
  303. Assert.AreEqual (0, results.Count, "#A2-2");
  304. dummy2 = new Dummy ();
  305. ctx = new ValidationContext (dummy2, null, null) {
  306. MemberName = "NameProperty"
  307. };
  308. AssertExtensions.Throws<ArgumentException> (() => {
  309. // MonoTests.System.ComponentModel.DataAnnotations.ValidatorTest.TryValidateProperty:
  310. // System.ArgumentException : The value for property 'NameProperty' must be of type 'System.String'.
  311. // Parameter name: value
  312. //
  313. // at System.ComponentModel.DataAnnotations.Validator.EnsureValidPropertyType(String propertyName, Type propertyType, Object value)
  314. // at System.ComponentModel.DataAnnotations.Validator.TryValidateProperty(Object value, ValidationContext validationContext, ICollection`1 validationResults)
  315. // 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
  316. Validator.TryValidateProperty (1234, ctx, results);
  317. }, "#A3-1");
  318. Assert.AreEqual (0, results.Count, "#A3-2");
  319. dummy2 = new Dummy ();
  320. ctx = new ValidationContext (dummy2, null, null) {
  321. MemberName = "NameProperty"
  322. };
  323. valid = Validator.TryValidateProperty (String.Empty, ctx, results);
  324. Assert.IsFalse (valid, "#A4-1");
  325. Assert.AreEqual (1, results.Count, "#A4-2");
  326. results.Clear ();
  327. valid = Validator.TryValidateProperty ("this value is way too long", ctx, results);
  328. Assert.IsFalse (valid, "#A4-3");
  329. Assert.AreEqual (1, results.Count, "#A4-4");
  330. results.Clear ();
  331. valid = Validator.TryValidateProperty ("good value", ctx, results);
  332. Assert.IsTrue (valid, "#A4-5");
  333. Assert.AreEqual (0, results.Count, "#A4-6");
  334. dummy2 = new Dummy ();
  335. ctx = new ValidationContext (dummy2, null, null) {
  336. MemberName = "CustomValidatedProperty"
  337. };
  338. valid = Validator.TryValidateProperty (String.Empty, ctx, results);
  339. Assert.IsFalse (valid, "#A5-1");
  340. Assert.AreEqual (1, results.Count, "#A5-2");
  341. results.Clear ();
  342. valid = Validator.TryValidateProperty ("fail", ctx, results);
  343. Assert.IsFalse (valid, "#A5-3");
  344. Assert.AreEqual (1, results.Count, "#A5-4");
  345. results.Clear ();
  346. valid = Validator.TryValidateProperty ("f", ctx, results);
  347. Assert.IsFalse (valid, "#A5-5");
  348. Assert.AreEqual (2, results.Count, "#A5-6");
  349. results.Clear ();
  350. valid = Validator.TryValidateProperty ("good value", ctx, results);
  351. Assert.IsTrue (valid, "#A5-7");
  352. Assert.AreEqual (0, results.Count, "#A5-8");
  353. }
  354. [Test]
  355. public void TryValidateValue_01 ()
  356. {
  357. var dummy = new DummyNoAttributes ();
  358. var ctx = new ValidationContext (dummy, null, null) {
  359. MemberName = "NameProperty"
  360. };
  361. var results = new List<ValidationResult> ();
  362. var attributes = new List <ValidationAttribute> ();
  363. bool valid = Validator.TryValidateValue (null, ctx, results, attributes);
  364. Assert.IsTrue (valid, "#A1-1");
  365. Assert.AreEqual (0, results.Count, "#A1-2");
  366. AssertExtensions.Throws<ArgumentNullException> (() => {
  367. Validator.TryValidateValue ("dummy", null, results, attributes);
  368. }, "#A2");
  369. valid = Validator.TryValidateValue ("dummy", ctx, null, attributes);
  370. Assert.IsTrue (valid, "#A3-1");
  371. Assert.AreEqual (0, results.Count, "#A3-2");
  372. AssertExtensions.Throws<ArgumentNullException> (() => {
  373. Validator.TryValidateValue ("dummy", ctx, results, null);
  374. }, "#A4");
  375. }
  376. [Test]
  377. public void TryValidateValue_02 ()
  378. {
  379. var dummy = new DummyNoAttributes ();
  380. var ctx = new ValidationContext (dummy, null, null);
  381. var results = new List<ValidationResult> ();
  382. var log = new List<string> ();
  383. var attributes = new List<ValidationAttribute> () {
  384. new StringLengthAttributePoker (10, log) {
  385. MinimumLength = 2
  386. },
  387. new RequiredAttributePoker (log)
  388. };
  389. bool valid = Validator.TryValidateValue (null, ctx, results, attributes);
  390. Assert.IsFalse (valid, "#A1-1");
  391. Assert.AreEqual (1, results.Count, "#A1-2");
  392. Assert.AreEqual (1, log.Count, "#A1-3");
  393. Assert.IsTrue (log [0].StartsWith ("RequiredAttributePoker.IsValid (object)"), "#A1-4");
  394. results.Clear ();
  395. log.Clear ();
  396. AssertExtensions.Throws<InvalidCastException> (() => {
  397. // Thrown by StringValidatorAttribute
  398. Validator.TryValidateValue (1234, ctx, results, attributes);
  399. }, "#A2-1");
  400. Assert.AreEqual (0, results.Count, "#A2-2");
  401. Assert.AreEqual (2, log.Count, "#A2-3");
  402. Assert.IsTrue (log[0].StartsWith ("RequiredAttributePoker.IsValid (object)"), "#A2-4");
  403. Assert.IsTrue (log[1].StartsWith ("StringLengthAttributePoker.IsValid (object)"), "#A2-5");
  404. results.Clear ();
  405. log.Clear ();
  406. attributes.Add (new CustomValidationAttribute (typeof (ValidatorTest), "ValueValidationMethod"));
  407. attributes.Add (new CustomValidationAttribute (typeof (ValidatorTest), "ValueValidationMethod"));
  408. valid = Validator.TryValidateValue ("test", ctx, results, attributes);
  409. Assert.IsFalse (valid, "#A3-1");
  410. Assert.AreEqual (2, results.Count, "#A3-2");
  411. Assert.AreEqual (2, log.Count, "#A3-3");
  412. Assert.IsTrue (log[0].StartsWith ("RequiredAttributePoker.IsValid (object)"), "#A3-4");
  413. Assert.IsTrue (log[1].StartsWith ("StringLengthAttributePoker.IsValid (object)"), "#A3-5");
  414. Assert.AreEqual ("ValueValidationMethod", results[0].ErrorMessage, "#A3-6");
  415. Assert.AreEqual ("ValueValidationMethod", results[1].ErrorMessage, "#A3-7");
  416. results.Clear ();
  417. log.Clear ();
  418. attributes.RemoveAt (2);
  419. attributes.RemoveAt (2);
  420. AssertExtensions.Throws<ArgumentNullException> (() => {
  421. Validator.TryValidateValue ("dummy", null, results, attributes);
  422. }, "#B1");
  423. valid = Validator.TryValidateValue ("dummy", ctx, null, attributes);
  424. Assert.IsTrue (valid, "#B2-1");
  425. Assert.AreEqual (0, results.Count, "#B2-2");
  426. AssertExtensions.Throws<ArgumentNullException> (() => {
  427. Validator.TryValidateValue ("dummy", ctx, results, null);
  428. }, "#B3");
  429. }
  430. [Test]
  431. public void ValidateObject_Object_ValidationContext_01 ()
  432. {
  433. var dummy = new DummyNoAttributes ();
  434. var ctx = new ValidationContext (dummy, null, null);
  435. AssertExtensions.Throws<ArgumentNullException> (() => {
  436. Validator.ValidateObject (null, ctx);
  437. }, "#A1-1");
  438. AssertExtensions.Throws<ArgumentNullException> (() => {
  439. Validator.ValidateObject (dummy, null);
  440. }, "#A1-2");
  441. try {
  442. Validator.ValidateObject (dummy, ctx);
  443. } catch (Exception ex) {
  444. Assert.Fail ("#A2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  445. }
  446. }
  447. [Test]
  448. public void ValidateObject_Object_ValidationContext_02 ()
  449. {
  450. var dummy = new Dummy ();
  451. var ctx = new ValidationContext (dummy, null, null);
  452. try {
  453. Validator.ValidateObject (dummy, ctx);
  454. } catch (Exception ex) {
  455. Assert.Fail ("#A1 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  456. }
  457. dummy = new Dummy {
  458. NameField = null
  459. };
  460. AssertExtensions.Throws<ArgumentException> (() => {
  461. // The instance provided must match the ObjectInstance on the ValidationContext supplied.
  462. Validator.ValidateObject (dummy, ctx);
  463. }, "#A2");
  464. // Fields are ignored
  465. ctx = new ValidationContext (dummy, null, null);
  466. try {
  467. Validator.ValidateObject (dummy, ctx);
  468. } catch (Exception ex) {
  469. Assert.Fail ("#A3 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  470. }
  471. dummy = new Dummy {
  472. RequiredDummyField = null
  473. };
  474. ctx = new ValidationContext (dummy, null, null);
  475. try {
  476. Validator.ValidateObject (dummy, ctx);
  477. } catch (Exception ex) {
  478. Assert.Fail ("#A4 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  479. }
  480. dummy = new Dummy {
  481. RequiredDummyProperty = null
  482. };
  483. ctx = new ValidationContext (dummy, null, null);
  484. AssertExtensions.Throws<ValidationException> (() => {
  485. Validator.ValidateObject (dummy, ctx);
  486. }, "#A5");
  487. // validation attributes other than Required are ignored
  488. dummy = new Dummy {
  489. NameProperty = null
  490. };
  491. ctx = new ValidationContext (dummy, null, null);
  492. try {
  493. Validator.ValidateObject (dummy, ctx);
  494. } catch (Exception ex) {
  495. Assert.Fail ("#A6 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  496. }
  497. dummy = new Dummy {
  498. MinMaxProperty = 0
  499. };
  500. ctx = new ValidationContext (dummy, null, null);
  501. try {
  502. Validator.ValidateObject (dummy, ctx);
  503. } catch (Exception ex) {
  504. Assert.Fail ("#A7 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  505. }
  506. dummy = new Dummy {
  507. FailValidation = true
  508. };
  509. ctx = new ValidationContext (dummy, null, null);
  510. AssertExtensions.Throws<ValidationException> (() => {
  511. Validator.ValidateObject (dummy, ctx);
  512. }, "#A8");
  513. var dummy2 = new DummyMultipleCustomValidators ();
  514. ctx = new ValidationContext (dummy2, null, null);
  515. try {
  516. Validator.ValidateObject (dummy2, ctx);
  517. } catch (Exception ex) {
  518. Assert.Fail ("#A9 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  519. }
  520. }
  521. [Test]
  522. public void ValidateObject_Object_ValidationContext_Bool_01 ()
  523. {
  524. var dummy = new DummyNoAttributes ();
  525. var ctx = new ValidationContext (dummy, null, null);
  526. AssertExtensions.Throws<ArgumentNullException> (() => {
  527. Validator.ValidateObject (null, ctx, false);
  528. }, "#A1-1");
  529. AssertExtensions.Throws<ArgumentNullException> (() => {
  530. Validator.ValidateObject (dummy, null, false);
  531. }, "#A1-2");
  532. try {
  533. Validator.ValidateObject (dummy, ctx, false);
  534. } catch (Exception ex) {
  535. Assert.Fail ("#A2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  536. }
  537. try {
  538. Validator.ValidateObject (dummy, ctx, true);
  539. } catch (Exception ex) {
  540. Assert.Fail ("#A3 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  541. }
  542. }
  543. [Test]
  544. public void ValidateObject_Object_ValidationContext_Bool_02 ()
  545. {
  546. var dummy = new Dummy ();
  547. var ctx = new ValidationContext (dummy, null, null);
  548. try {
  549. Validator.ValidateObject (dummy, ctx, false);
  550. } catch (Exception ex) {
  551. Assert.Fail ("#A1 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  552. }
  553. try {
  554. Validator.ValidateObject (dummy, ctx, true);
  555. } catch (Exception ex) {
  556. Assert.Fail ("#A2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  557. }
  558. dummy = new Dummy {
  559. NameField = null
  560. };
  561. AssertExtensions.Throws<ArgumentException> (() => {
  562. // The instance provided must match the ObjectInstance on the ValidationContext supplied.
  563. Validator.ValidateObject (dummy, ctx, false);
  564. }, "#A3-1");
  565. AssertExtensions.Throws<ArgumentException> (() => {
  566. // The instance provided must match the ObjectInstance on the ValidationContext supplied.
  567. Validator.ValidateObject (dummy, ctx, true);
  568. }, "#A3-2");
  569. // Fields are ignored
  570. ctx = new ValidationContext (dummy, null, null);
  571. try {
  572. Validator.ValidateObject (dummy, ctx, false);
  573. } catch (Exception ex) {
  574. Assert.Fail ("#A4-1 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  575. }
  576. try {
  577. Validator.ValidateObject (dummy, ctx, true);
  578. } catch (Exception ex) {
  579. Assert.Fail ("#A4-2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  580. }
  581. dummy = new Dummy {
  582. RequiredDummyField = null
  583. };
  584. ctx = new ValidationContext (dummy, null, null);
  585. try {
  586. Validator.ValidateObject (dummy, ctx, false);
  587. } catch (Exception ex) {
  588. Assert.Fail ("#A5-1 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  589. }
  590. try {
  591. Validator.ValidateObject (dummy, ctx, true);
  592. } catch (Exception ex) {
  593. Assert.Fail ("#A5-2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  594. }
  595. // Required properties existence is validated
  596. dummy = new Dummy {
  597. RequiredDummyProperty = null
  598. };
  599. ctx = new ValidationContext (dummy, null, null);
  600. AssertExtensions.Throws<ValidationException> (() => {
  601. Validator.ValidateObject (dummy, ctx, false);
  602. }, "#A6-1");
  603. AssertExtensions.Throws<ValidationException> (() => {
  604. Validator.ValidateObject (dummy, ctx, true);
  605. }, "#A6-2");
  606. dummy = new Dummy {
  607. NameProperty = null
  608. };
  609. ctx = new ValidationContext (dummy, null, null);
  610. try {
  611. Validator.ValidateObject (dummy, ctx, false);
  612. } catch (Exception ex) {
  613. Assert.Fail ("#A7 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  614. }
  615. // NameProperty is null, that causes the StringLength validator to skip its tests
  616. try {
  617. Validator.ValidateObject (dummy, ctx, true);
  618. } catch (Exception ex) {
  619. Assert.Fail ("#A8 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  620. }
  621. dummy.NameProperty = "0";
  622. AssertExtensions.Throws<ValidationException> (() => {
  623. Validator.ValidateObject (dummy, ctx, true);
  624. }, "#A9");
  625. dummy.NameProperty = "name too long (invalid value)";
  626. AssertExtensions.Throws<ValidationException> (() => {
  627. Validator.ValidateObject (dummy, ctx, true);
  628. }, "#A10");
  629. dummy = new Dummy {
  630. MinMaxProperty = 0
  631. };
  632. ctx = new ValidationContext (dummy, null, null);
  633. try {
  634. Validator.ValidateObject (dummy, ctx, false);
  635. } catch (Exception ex) {
  636. Assert.Fail ("#A11 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  637. }
  638. AssertExtensions.Throws<ValidationException> (() => {
  639. Validator.ValidateObject (dummy, ctx, true);
  640. }, "#A12");
  641. dummy = new Dummy {
  642. FailValidation = true
  643. };
  644. ctx = new ValidationContext (dummy, null, null);
  645. AssertExtensions.Throws<ValidationException> (() => {
  646. Validator.ValidateObject (dummy, ctx, false);
  647. }, "#A13-1");
  648. AssertExtensions.Throws<ValidationException> (() => {
  649. Validator.ValidateObject (dummy, ctx, true);
  650. }, "#A13-2");
  651. var dummy2 = new DummyWithException ();
  652. ctx = new ValidationContext (dummy2, null, null);
  653. AssertExtensions.Throws<ApplicationException> (() => {
  654. Validator.ValidateObject (dummy2, ctx, true);
  655. }, "#A14");
  656. var dummy3 = new DummyMultipleCustomValidators ();
  657. ctx = new ValidationContext (dummy3, null, null);
  658. try {
  659. Validator.ValidateObject (dummy3, ctx, false);
  660. } catch (Exception ex) {
  661. Assert.Fail ("#A9 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  662. }
  663. try {
  664. Validator.ValidateObject (dummy3, ctx, true);
  665. } catch (ValidationException ex) {
  666. Assert.AreEqual ("FirstPropertyValidationMethod", ex.Message, "#A10");
  667. } catch (Exception ex) {
  668. Assert.Fail ("#A10 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  669. }
  670. }
  671. [Test]
  672. public void ValidateProperty ()
  673. {
  674. var dummy = new DummyNoAttributes ();
  675. var ctx = new ValidationContext (dummy, null, null) {
  676. MemberName = "NameProperty"
  677. };
  678. AssertExtensions.Throws<ArgumentException> (() => {
  679. Validator.ValidateProperty ("dummy", ctx);
  680. }, "#A1-1");
  681. AssertExtensions.Throws<ArgumentNullException> (() => {
  682. Validator.ValidateProperty ("dummy", null);
  683. }, "#A1-2");
  684. var dummy2 = new Dummy ();
  685. ctx = new ValidationContext (dummy2, null, null) {
  686. MemberName = "NameProperty"
  687. };
  688. try {
  689. Validator.ValidateProperty (null, ctx);
  690. } catch (Exception ex) {
  691. Assert.Fail ("#A2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  692. }
  693. ctx = new ValidationContext (dummy2, null, null) {
  694. MemberName = "MinMaxProperty"
  695. };
  696. AssertExtensions.Throws<ArgumentException> (() => {
  697. Validator.ValidateProperty (null, ctx);
  698. }, "#A3");
  699. ctx = new ValidationContext (dummy2, null, null);
  700. AssertExtensions.Throws<ArgumentNullException> (() => {
  701. Validator.ValidateProperty ("dummy", ctx);
  702. }, "#A4");
  703. ctx = new ValidationContext (dummy2, null, null) {
  704. MemberName = String.Empty
  705. };
  706. AssertExtensions.Throws<ArgumentNullException> (() => {
  707. Validator.ValidateProperty ("dummy", ctx);
  708. }, "#A5");
  709. dummy2 = new Dummy ();
  710. ctx = new ValidationContext (dummy2, null, null) {
  711. MemberName = "NameProperty"
  712. };
  713. AssertExtensions.Throws<ArgumentException> (() => {
  714. Validator.ValidateProperty (1234, ctx);
  715. }, "#A6");
  716. dummy2 = new Dummy ();
  717. ctx = new ValidationContext (dummy2, null, null) {
  718. MemberName = "NameProperty"
  719. };
  720. AssertExtensions.Throws<ValidationException> (() => {
  721. Validator.ValidateProperty (String.Empty, ctx);
  722. }, "#A7");
  723. AssertExtensions.Throws<ValidationException> (() => {
  724. Validator.ValidateProperty ("this value is way too long", ctx);
  725. }, "#A8");
  726. try {
  727. Validator.ValidateProperty ("good value", ctx);
  728. } catch (Exception ex) {
  729. Assert.Fail ("#A9 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  730. }
  731. dummy2 = new Dummy ();
  732. ctx = new ValidationContext (dummy2, null, null) {
  733. MemberName = "CustomValidatedProperty"
  734. };
  735. AssertExtensions.Throws<ValidationException> (() => {
  736. Validator.ValidateProperty (String.Empty, ctx);
  737. }, "#A10");
  738. AssertExtensions.Throws<ValidationException> (() => {
  739. Validator.ValidateProperty ("fail", ctx);
  740. }, "#A11");
  741. AssertExtensions.Throws<ValidationException> (() => {
  742. Validator.ValidateProperty ("f", ctx);
  743. }, "#A12");
  744. try {
  745. Validator.ValidateProperty ("good value", ctx);
  746. } catch (Exception ex) {
  747. Assert.Fail ("#A13 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  748. }
  749. }
  750. [Test]
  751. public void ValidateValue_01 ()
  752. {
  753. var dummy = new DummyNoAttributes ();
  754. var ctx = new ValidationContext (dummy, null, null) {
  755. MemberName = "NameProperty"
  756. };
  757. var attributes = new List<ValidationAttribute> ();
  758. try {
  759. Validator.ValidateValue (null, ctx, attributes);
  760. } catch (Exception ex) {
  761. Assert.Fail ("#A1 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  762. }
  763. AssertExtensions.Throws<ArgumentNullException> (() => {
  764. Validator.ValidateValue ("dummy", null, attributes);
  765. }, "#A2");
  766. try {
  767. Validator.ValidateValue ("dummy", ctx, attributes);
  768. } catch (Exception ex) {
  769. Assert.Fail ("#A3 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  770. }
  771. AssertExtensions.Throws<ArgumentNullException> (() => {
  772. Validator.ValidateValue ("dummy", ctx, null);
  773. }, "#A4");
  774. }
  775. [Test]
  776. public void ValidateValue_02 ()
  777. {
  778. var dummy = new DummyNoAttributes ();
  779. var ctx = new ValidationContext (dummy, null, null);
  780. var log = new List<string> ();
  781. var attributes = new List<ValidationAttribute> () {
  782. new StringLengthAttributePoker (10, log) {
  783. MinimumLength = 2
  784. },
  785. new RequiredAttributePoker (log)
  786. };
  787. AssertExtensions.Throws<ValidationException> (() => {
  788. Validator.ValidateValue (null, ctx, attributes);
  789. }, "#A1-1");
  790. Assert.AreEqual (1, log.Count, "#A1-2");
  791. Assert.IsTrue (log[0].StartsWith ("RequiredAttributePoker.IsValid (object)"), "#A1-3");
  792. log.Clear ();
  793. AssertExtensions.Throws<InvalidCastException> (() => {
  794. // Thrown by StringValidatorAttribute
  795. Validator.ValidateValue (1234, ctx, attributes);
  796. }, "#A2-1");;
  797. Assert.AreEqual (2, log.Count, "#A2-2");
  798. Assert.IsTrue (log[0].StartsWith ("RequiredAttributePoker.IsValid (object)"), "#A2-3");
  799. Assert.IsTrue (log[1].StartsWith ("StringLengthAttributePoker.IsValid (object)"), "#A2-4");
  800. log.Clear ();
  801. attributes.Add (new CustomValidationAttribute (typeof (ValidatorTest), "ValueValidationMethod"));
  802. attributes.Add (new CustomValidationAttribute (typeof (ValidatorTest), "ValueValidationMethod"));
  803. AssertExtensions.Throws<ValidationException> (() => {
  804. Validator.ValidateValue ("test", ctx, attributes);
  805. }, "#A3-1");
  806. Assert.AreEqual (2, log.Count, "#A3-2");
  807. Assert.IsTrue (log[0].StartsWith ("RequiredAttributePoker.IsValid (object)"), "#A3-3");
  808. Assert.IsTrue (log[1].StartsWith ("StringLengthAttributePoker.IsValid (object)"), "#A3-4");
  809. log.Clear ();
  810. attributes.RemoveAt (2);
  811. attributes.RemoveAt (2);
  812. AssertExtensions.Throws<ArgumentNullException> (() => {
  813. Validator.ValidateValue ("dummy", null, attributes);
  814. }, "#B1");
  815. try {
  816. Validator.ValidateValue ("dummy", ctx, attributes);
  817. } catch (Exception ex) {
  818. Assert.Fail ("#B2 (exception {0} thrown: {1})", ex.GetType (), ex.Message);
  819. }
  820. AssertExtensions.Throws<ArgumentNullException> (() => {
  821. Validator.ValidateValue ("dummy", ctx, null);
  822. }, "#B3");
  823. }
  824. public static ValidationResult DummyValidationMethod (object o)
  825. {
  826. var dummy = o as Dummy;
  827. if (dummy == null)
  828. return new ValidationResult ("Invalid DummyValidationMethod input - broken test?");
  829. if (dummy.FailValidation)
  830. return new ValidationResult ("Dummy validation failed.");
  831. return ValidationResult.Success;
  832. }
  833. public static ValidationResult CustomValidatedPropertyValidationMethod (object o)
  834. {
  835. var dummy = o as string;
  836. if (dummy != null && (dummy == "f" || dummy == "fail"))
  837. return new ValidationResult ("Dummy.CustomValidatedProperty validation failed.");
  838. return ValidationResult.Success;
  839. }
  840. public static ValidationResult ValidationMethodException (object o)
  841. {
  842. throw new ApplicationException ("SNAFU");
  843. }
  844. public static ValidationResult ValueValidationMethod (object o, ValidationContext validationContext)
  845. {
  846. return new ValidationResult ("ValueValidationMethod");
  847. }
  848. public static ValidationResult FirstPropertyValidationMethod (object o, ValidationContext validationContext)
  849. {
  850. return new ValidationResult ("FirstPropertyValidationMethod");
  851. }
  852. public static ValidationResult SecondPropertyValidationMethod (object o, ValidationContext validationContext)
  853. {
  854. return new ValidationResult ("SecondPropertyValidationMethod");
  855. }
  856. public class RequiredAttributePoker : RequiredAttribute
  857. {
  858. List <string> log;
  859. public RequiredAttributePoker (List<string> log)
  860. {
  861. if (log == null)
  862. throw new ArgumentNullException ("log");
  863. this.log = log;
  864. }
  865. public override bool IsValid (object value)
  866. {
  867. log.Add ("RequiredAttributePoker.IsValid (object)");
  868. return base.IsValid (value);
  869. }
  870. }
  871. public class StringLengthAttributePoker : StringLengthAttribute
  872. {
  873. List <string> log;
  874. public StringLengthAttributePoker (int maximumLength, List<string> log)
  875. : base (maximumLength)
  876. {
  877. if (log == null)
  878. throw new ArgumentNullException ("log");
  879. this.log = log;
  880. }
  881. public override bool IsValid (object value)
  882. {
  883. log.Add ("StringLengthAttributePoker.IsValid (object)");
  884. return base.IsValid (value);
  885. }
  886. }
  887. class DummyNoAttributes
  888. { }
  889. [CustomValidation (typeof (ValidatorTest), "DummyValidationMethod")]
  890. class Dummy
  891. {
  892. [StringLength (10, MinimumLength=2)]
  893. public string NameField;
  894. [Required]
  895. public DummyNoAttributes RequiredDummyField;
  896. [StringLength (10, MinimumLength = 2)]
  897. public string NameProperty { get; set; }
  898. [Required]
  899. public DummyNoAttributes RequiredDummyProperty { get; set; }
  900. [global::System.ComponentModel.DataAnnotations.RangeAttribute ((int)1, (int)10)]
  901. public int MinMaxProperty { get; set; }
  902. [StringLength (10, MinimumLength = 2)]
  903. [CustomValidation (typeof (ValidatorTest), "CustomValidatedPropertyValidationMethod")]
  904. public string CustomValidatedProperty { get; set; }
  905. [CustomValidation (typeof (ValidatorTest), "CustomValidatedPropertyValidationMethod")]
  906. [StringLength (10, MinimumLength = 2)]
  907. public string AnotherCustomValidatedProperty { get; set; }
  908. public bool FailValidation { get; set; }
  909. public Dummy ()
  910. {
  911. NameField = "name";
  912. NameProperty = "name";
  913. RequiredDummyField = new DummyNoAttributes ();
  914. RequiredDummyProperty = new DummyNoAttributes ();
  915. MinMaxProperty = 5;
  916. AnotherCustomValidatedProperty = "I'm valid";
  917. }
  918. }
  919. class DummyWithException
  920. {
  921. [CustomValidation (typeof (ValidatorTest), "ValidationMethodException")]
  922. public string AnotherCustomValidatedProperty { get; set; }
  923. }
  924. class DummyForValueValidation
  925. {
  926. public string DummyNoAttributes;
  927. public DummyForValueValidation ()
  928. {
  929. this.DummyNoAttributes = "I am valid";
  930. }
  931. }
  932. class DummyMultipleCustomValidators
  933. {
  934. [CustomValidation (typeof (ValidatorTest), "FirstPropertyValidationMethod")]
  935. public string FirstProperty { get; set; }
  936. [CustomValidation (typeof (ValidatorTest), "SecondPropertyValidationMethod")]
  937. public string SecondProperty { get; set; }
  938. }
  939. }
  940. #endif
  941. }