PageRenderTime 61ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/Json45r7/Source/Src/Newtonsoft.Json.Tests/JsonValidatingReaderTests.cs

https://bitbucket.org/wantstudios/bitbucketclient
C# | 1590 lines | 1275 code | 293 blank | 22 comment | 1 complexity | 22b1c3142f9d3db0a54c5fbebaf22b8c MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. #region License
  2. // Copyright (c) 2007 James Newton-King
  3. //
  4. // Permission is hereby granted, free of charge, to any person
  5. // obtaining a copy of this software and associated documentation
  6. // files (the "Software"), to deal in the Software without
  7. // restriction, including without limitation the rights to use,
  8. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following
  11. // conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. // OTHER DEALINGS IN THE SOFTWARE.
  24. #endregion
  25. using System;
  26. using System.Collections.Generic;
  27. using System.IO;
  28. #if NET20
  29. using Newtonsoft.Json.Utilities.LinqBridge;
  30. #endif
  31. using System.Text;
  32. #if !NETFX_CORE
  33. using NUnit.Framework;
  34. #else
  35. using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
  36. using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
  37. using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
  38. #endif
  39. using System.Xml;
  40. using System.Xml.Schema;
  41. using Newtonsoft.Json.Schema;
  42. using Newtonsoft.Json.Utilities;
  43. using ValidationEventArgs = Newtonsoft.Json.Schema.ValidationEventArgs;
  44. namespace Newtonsoft.Json.Tests
  45. {
  46. [TestFixture]
  47. public class JsonValidatingReaderTests : TestFixtureBase
  48. {
  49. [Test]
  50. public void CheckInnerReader()
  51. {
  52. string json = "{'name':'James','hobbies':['pie','cake']}";
  53. JsonReader reader = new JsonTextReader(new StringReader(json));
  54. JsonValidatingReader validatingReader = new JsonValidatingReader(reader);
  55. Assert.AreEqual(reader, validatingReader.Reader);
  56. }
  57. [Test]
  58. public void ValidateTypes()
  59. {
  60. string schemaJson = @"{
  61. ""description"":""A person"",
  62. ""type"":""object"",
  63. ""properties"":
  64. {
  65. ""name"":{""type"":""string""},
  66. ""hobbies"":
  67. {
  68. ""type"":""array"",
  69. ""items"": {""type"":""string""}
  70. }
  71. }
  72. }";
  73. string json = @"{'name':""James"",'hobbies':[""pie"",'cake']}";
  74. Json.Schema.ValidationEventArgs validationEventArgs = null;
  75. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  76. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  77. JsonSchema schema = JsonSchema.Parse(schemaJson);
  78. reader.Schema = schema;
  79. Assert.AreEqual(schema, reader.Schema);
  80. Assert.AreEqual(0, reader.Depth);
  81. Assert.AreEqual("", reader.Path);
  82. Assert.IsTrue(reader.Read());
  83. Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
  84. Assert.AreEqual("", reader.Path);
  85. Assert.IsTrue(reader.Read());
  86. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  87. Assert.AreEqual("name", reader.Value.ToString());
  88. Assert.AreEqual("name", reader.Path);
  89. Assert.AreEqual(1, reader.Depth);
  90. Assert.IsTrue(reader.Read());
  91. Assert.AreEqual(JsonToken.String, reader.TokenType);
  92. Assert.AreEqual("James", reader.Value.ToString());
  93. Assert.AreEqual(typeof (string), reader.ValueType);
  94. Assert.AreEqual('"', reader.QuoteChar);
  95. Assert.AreEqual("name", reader.Path);
  96. Assert.IsTrue(reader.Read());
  97. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  98. Assert.AreEqual("hobbies", reader.Value.ToString());
  99. Assert.AreEqual('\'', reader.QuoteChar);
  100. Assert.AreEqual("hobbies", reader.Path);
  101. Assert.IsTrue(reader.Read());
  102. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  103. Assert.AreEqual("hobbies", reader.Path);
  104. Assert.IsTrue(reader.Read());
  105. Assert.AreEqual(JsonToken.String, reader.TokenType);
  106. Assert.AreEqual("pie", reader.Value.ToString());
  107. Assert.AreEqual('"', reader.QuoteChar);
  108. Assert.AreEqual("hobbies[0]", reader.Path);
  109. Assert.IsTrue(reader.Read());
  110. Assert.AreEqual(JsonToken.String, reader.TokenType);
  111. Assert.AreEqual("cake", reader.Value.ToString());
  112. Assert.AreEqual("hobbies[1]", reader.Path);
  113. Assert.IsTrue(reader.Read());
  114. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  115. Assert.AreEqual("hobbies", reader.Path);
  116. Assert.IsTrue(reader.Read());
  117. Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
  118. Assert.AreEqual("", reader.Path);
  119. Assert.IsFalse(reader.Read());
  120. Assert.IsNull(validationEventArgs);
  121. }
  122. [Test]
  123. public void ValidateUnrestrictedArray()
  124. {
  125. string schemaJson = @"{
  126. ""type"":""array""
  127. }";
  128. string json = "['pie','cake',['nested1','nested2'],{'nestedproperty1':1.1,'nestedproperty2':[null]}]";
  129. Json.Schema.ValidationEventArgs validationEventArgs = null;
  130. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  131. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  132. reader.Schema = JsonSchema.Parse(schemaJson);
  133. Assert.IsTrue(reader.Read());
  134. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  135. Assert.IsTrue(reader.Read());
  136. Assert.AreEqual(JsonToken.String, reader.TokenType);
  137. Assert.AreEqual("pie", reader.Value.ToString());
  138. Assert.IsTrue(reader.Read());
  139. Assert.AreEqual(JsonToken.String, reader.TokenType);
  140. Assert.AreEqual("cake", reader.Value.ToString());
  141. Assert.IsTrue(reader.Read());
  142. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  143. Assert.IsTrue(reader.Read());
  144. Assert.AreEqual(JsonToken.String, reader.TokenType);
  145. Assert.AreEqual("nested1", reader.Value.ToString());
  146. Assert.IsTrue(reader.Read());
  147. Assert.AreEqual(JsonToken.String, reader.TokenType);
  148. Assert.AreEqual("nested2", reader.Value.ToString());
  149. Assert.IsTrue(reader.Read());
  150. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  151. Assert.IsTrue(reader.Read());
  152. Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
  153. Assert.IsTrue(reader.Read());
  154. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  155. Assert.AreEqual("nestedproperty1", reader.Value.ToString());
  156. Assert.IsTrue(reader.Read());
  157. Assert.AreEqual(JsonToken.Float, reader.TokenType);
  158. Assert.AreEqual(1.1, reader.Value);
  159. Assert.IsTrue(reader.Read());
  160. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  161. Assert.AreEqual("nestedproperty2", reader.Value.ToString());
  162. Assert.IsTrue(reader.Read());
  163. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  164. Assert.IsTrue(reader.Read());
  165. Assert.AreEqual(JsonToken.Null, reader.TokenType);
  166. Assert.IsTrue(reader.Read());
  167. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  168. Assert.IsTrue(reader.Read());
  169. Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
  170. Assert.IsTrue(reader.Read());
  171. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  172. Assert.IsNull(validationEventArgs);
  173. }
  174. [Test]
  175. public void StringLessThanMinimumLength()
  176. {
  177. string schemaJson = @"{
  178. ""type"":""string"",
  179. ""minLength"":5,
  180. ""maxLength"":50,
  181. }";
  182. string json = "'pie'";
  183. Json.Schema.ValidationEventArgs validationEventArgs = null;
  184. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  185. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  186. reader.Schema = JsonSchema.Parse(schemaJson);
  187. Assert.IsTrue(reader.Read());
  188. Assert.AreEqual(JsonToken.String, reader.TokenType);
  189. Assert.AreEqual("String 'pie' is less than minimum length of 5. Line 1, position 5.", validationEventArgs.Message);
  190. Assert.IsNotNull(validationEventArgs);
  191. }
  192. [Test]
  193. public void StringGreaterThanMaximumLength()
  194. {
  195. string schemaJson = @"{
  196. ""type"":""string"",
  197. ""minLength"":5,
  198. ""maxLength"":10
  199. }";
  200. string json = "'The quick brown fox jumps over the lazy dog.'";
  201. Json.Schema.ValidationEventArgs validationEventArgs = null;
  202. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  203. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  204. reader.Schema = JsonSchema.Parse(schemaJson);
  205. Assert.IsTrue(reader.Read());
  206. Assert.AreEqual(JsonToken.String, reader.TokenType);
  207. Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' exceeds maximum length of 10. Line 1, position 46.", validationEventArgs.Message);
  208. Assert.IsNotNull(validationEventArgs);
  209. }
  210. [Test]
  211. public void StringIsNotInEnum()
  212. {
  213. string schemaJson = @"{
  214. ""type"":""array"",
  215. ""items"":{
  216. ""type"":""string"",
  217. ""enum"":[""one"",""two""]
  218. },
  219. ""maxItems"":3
  220. }";
  221. string json = "['one','two','THREE']";
  222. Json.Schema.ValidationEventArgs validationEventArgs = null;
  223. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  224. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  225. reader.Schema = JsonSchema.Parse(schemaJson);
  226. Assert.IsTrue(reader.Read());
  227. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  228. Assert.IsTrue(reader.Read());
  229. Assert.AreEqual(JsonToken.String, reader.TokenType);
  230. Assert.IsTrue(reader.Read());
  231. Assert.AreEqual(JsonToken.String, reader.TokenType);
  232. Assert.AreEqual(null, validationEventArgs);
  233. Assert.IsTrue(reader.Read());
  234. Assert.AreEqual(JsonToken.String, reader.TokenType);
  235. Assert.AreEqual(@"Value ""THREE"" is not defined in enum. Line 1, position 20.", validationEventArgs.Message);
  236. Assert.AreEqual("[2]", validationEventArgs.Path);
  237. Assert.IsTrue(reader.Read());
  238. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  239. Assert.IsNotNull(validationEventArgs);
  240. }
  241. [Test]
  242. public void StringDoesNotMatchPattern()
  243. {
  244. string schemaJson = @"{
  245. ""type"":""string"",
  246. ""pattern"":""foo""
  247. }";
  248. string json = "'The quick brown fox jumps over the lazy dog.'";
  249. Json.Schema.ValidationEventArgs validationEventArgs = null;
  250. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  251. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  252. reader.Schema = JsonSchema.Parse(schemaJson);
  253. Assert.IsTrue(reader.Read());
  254. Assert.AreEqual(JsonToken.String, reader.TokenType);
  255. Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' does not match regex pattern 'foo'. Line 1, position 46.", validationEventArgs.Message);
  256. Assert.AreEqual("", validationEventArgs.Path);
  257. Assert.IsNotNull(validationEventArgs);
  258. }
  259. [Test]
  260. public void IntegerGreaterThanMaximumValue()
  261. {
  262. string schemaJson = @"{
  263. ""type"":""integer"",
  264. ""maximum"":5
  265. }";
  266. string json = "10";
  267. Json.Schema.ValidationEventArgs validationEventArgs = null;
  268. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  269. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  270. reader.Schema = JsonSchema.Parse(schemaJson);
  271. Assert.IsTrue(reader.Read());
  272. Assert.AreEqual(JsonToken.Integer, reader.TokenType);
  273. Assert.AreEqual("Integer 10 exceeds maximum value of 5. Line 1, position 2.", validationEventArgs.Message);
  274. Assert.AreEqual("", validationEventArgs.Path);
  275. Assert.IsNotNull(validationEventArgs);
  276. }
  277. [Test]
  278. public void ThrowExceptionWhenNoValidationEventHandler()
  279. {
  280. ExceptionAssert.Throws<JsonSchemaException>("Integer 10 exceeds maximum value of 5. Line 1, position 2.",
  281. () =>
  282. {
  283. string schemaJson = @"{
  284. ""type"":""integer"",
  285. ""maximum"":5
  286. }";
  287. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader("10")));
  288. reader.Schema = JsonSchema.Parse(schemaJson);
  289. Assert.IsTrue(reader.Read());
  290. });
  291. }
  292. [Test]
  293. public void IntegerLessThanMinimumValue()
  294. {
  295. string schemaJson = @"{
  296. ""type"":""integer"",
  297. ""minimum"":5
  298. }";
  299. string json = "1";
  300. Json.Schema.ValidationEventArgs validationEventArgs = null;
  301. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  302. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  303. reader.Schema = JsonSchema.Parse(schemaJson);
  304. Assert.IsTrue(reader.Read());
  305. Assert.AreEqual(JsonToken.Integer, reader.TokenType);
  306. Assert.AreEqual("Integer 1 is less than minimum value of 5. Line 1, position 1.", validationEventArgs.Message);
  307. Assert.IsNotNull(validationEventArgs);
  308. }
  309. [Test]
  310. public void IntegerIsNotInEnum()
  311. {
  312. string schemaJson = @"{
  313. ""type"":""array"",
  314. ""items"":{
  315. ""type"":""integer"",
  316. ""enum"":[1,2]
  317. },
  318. ""maxItems"":3
  319. }";
  320. string json = "[1,2,3]";
  321. Json.Schema.ValidationEventArgs validationEventArgs = null;
  322. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  323. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  324. reader.Schema = JsonSchema.Parse(schemaJson);
  325. Assert.IsTrue(reader.Read());
  326. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  327. Assert.IsTrue(reader.Read());
  328. Assert.AreEqual(JsonToken.Integer, reader.TokenType);
  329. Assert.IsTrue(reader.Read());
  330. Assert.AreEqual(JsonToken.Integer, reader.TokenType);
  331. Assert.AreEqual(null, validationEventArgs);
  332. Assert.IsTrue(reader.Read());
  333. Assert.AreEqual(JsonToken.Integer, reader.TokenType);
  334. Assert.AreEqual(@"Value 3 is not defined in enum. Line 1, position 6.", validationEventArgs.Message);
  335. Assert.AreEqual("[2]", validationEventArgs.Path);
  336. Assert.IsTrue(reader.Read());
  337. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  338. Assert.IsNotNull(validationEventArgs);
  339. }
  340. [Test]
  341. public void FloatGreaterThanMaximumValue()
  342. {
  343. string schemaJson = @"{
  344. ""type"":""number"",
  345. ""maximum"":5
  346. }";
  347. string json = "10.0";
  348. Json.Schema.ValidationEventArgs validationEventArgs = null;
  349. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  350. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  351. reader.Schema = JsonSchema.Parse(schemaJson);
  352. Assert.IsTrue(reader.Read());
  353. Assert.AreEqual(JsonToken.Float, reader.TokenType);
  354. Assert.AreEqual("Float 10.0 exceeds maximum value of 5. Line 1, position 4.", validationEventArgs.Message);
  355. Assert.IsNotNull(validationEventArgs);
  356. }
  357. [Test]
  358. public void FloatLessThanMinimumValue()
  359. {
  360. string schemaJson = @"{
  361. ""type"":""number"",
  362. ""minimum"":5
  363. }";
  364. string json = "1.1";
  365. Json.Schema.ValidationEventArgs validationEventArgs = null;
  366. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  367. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  368. reader.Schema = JsonSchema.Parse(schemaJson);
  369. Assert.IsTrue(reader.Read());
  370. Assert.AreEqual(JsonToken.Float, reader.TokenType);
  371. Assert.AreEqual("Float 1.1 is less than minimum value of 5. Line 1, position 3.", validationEventArgs.Message);
  372. Assert.IsNotNull(validationEventArgs);
  373. }
  374. [Test]
  375. public void FloatIsNotInEnum()
  376. {
  377. string schemaJson = @"{
  378. ""type"":""array"",
  379. ""items"":{
  380. ""type"":""number"",
  381. ""enum"":[1.1,2.2]
  382. },
  383. ""maxItems"":3
  384. }";
  385. string json = "[1.1,2.2,3.0]";
  386. Json.Schema.ValidationEventArgs validationEventArgs = null;
  387. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  388. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  389. reader.Schema = JsonSchema.Parse(schemaJson);
  390. Assert.IsTrue(reader.Read());
  391. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  392. Assert.IsTrue(reader.Read());
  393. Assert.AreEqual(JsonToken.Float, reader.TokenType);
  394. Assert.IsTrue(reader.Read());
  395. Assert.AreEqual(JsonToken.Float, reader.TokenType);
  396. Assert.AreEqual(null, validationEventArgs);
  397. Assert.IsTrue(reader.Read());
  398. Assert.AreEqual(JsonToken.Float, reader.TokenType);
  399. Assert.AreEqual(@"Value 3.0 is not defined in enum. Line 1, position 12.", validationEventArgs.Message);
  400. Assert.AreEqual("[2]", validationEventArgs.Path);
  401. Assert.IsTrue(reader.Read());
  402. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  403. Assert.IsNotNull(validationEventArgs);
  404. }
  405. [Test]
  406. public void FloatExceedsMaxDecimalPlaces()
  407. {
  408. string schemaJson = @"{
  409. ""type"":""array"",
  410. ""items"":{
  411. ""type"":""number"",
  412. ""divisibleBy"":0.1
  413. }
  414. }";
  415. string json = "[1.1,2.2,4.001]";
  416. Json.Schema.ValidationEventArgs validationEventArgs = null;
  417. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  418. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  419. reader.Schema = JsonSchema.Parse(schemaJson);
  420. Assert.IsTrue(reader.Read());
  421. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  422. Assert.IsTrue(reader.Read());
  423. Assert.AreEqual(JsonToken.Float, reader.TokenType);
  424. Assert.IsTrue(reader.Read());
  425. Assert.AreEqual(JsonToken.Float, reader.TokenType);
  426. Assert.AreEqual(null, validationEventArgs);
  427. Assert.IsTrue(reader.Read());
  428. Assert.AreEqual(JsonToken.Float, reader.TokenType);
  429. Assert.AreEqual(@"Float 4.001 is not evenly divisible by 0.1. Line 1, position 14.", validationEventArgs.Message);
  430. Assert.AreEqual("[2]", validationEventArgs.Path);
  431. Assert.IsTrue(reader.Read());
  432. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  433. Assert.IsNotNull(validationEventArgs);
  434. }
  435. [Test]
  436. public void IntValidForNumber()
  437. {
  438. string schemaJson = @"{
  439. ""type"":""array"",
  440. ""items"":{
  441. ""type"":""number""
  442. }
  443. }";
  444. string json = "[1]";
  445. Json.Schema.ValidationEventArgs validationEventArgs = null;
  446. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  447. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  448. reader.Schema = JsonSchema.Parse(schemaJson);
  449. Assert.IsTrue(reader.Read());
  450. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  451. Assert.IsTrue(reader.Read());
  452. Assert.AreEqual(JsonToken.Integer, reader.TokenType);
  453. Assert.IsTrue(reader.Read());
  454. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  455. Assert.IsNull(validationEventArgs);
  456. }
  457. [Test]
  458. public void NullNotInEnum()
  459. {
  460. string schemaJson = @"{
  461. ""type"":""array"",
  462. ""items"":{
  463. ""type"":""null"",
  464. ""enum"":[]
  465. },
  466. ""maxItems"":3
  467. }";
  468. string json = "[null]";
  469. Json.Schema.ValidationEventArgs validationEventArgs = null;
  470. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  471. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  472. reader.Schema = JsonSchema.Parse(schemaJson);
  473. Assert.IsTrue(reader.Read());
  474. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  475. Assert.IsTrue(reader.Read());
  476. Assert.AreEqual(JsonToken.Null, reader.TokenType);
  477. Assert.AreEqual(@"Value null is not defined in enum. Line 1, position 5.", validationEventArgs.Message);
  478. Assert.AreEqual("[0]", validationEventArgs.Path);
  479. Assert.IsTrue(reader.Read());
  480. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  481. Assert.IsNotNull(validationEventArgs);
  482. }
  483. [Test]
  484. public void BooleanNotInEnum()
  485. {
  486. string schemaJson = @"{
  487. ""type"":""array"",
  488. ""items"":{
  489. ""type"":""boolean"",
  490. ""enum"":[true]
  491. },
  492. ""maxItems"":3
  493. }";
  494. string json = "[true,false]";
  495. Json.Schema.ValidationEventArgs validationEventArgs = null;
  496. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  497. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  498. reader.Schema = JsonSchema.Parse(schemaJson);
  499. Assert.IsTrue(reader.Read());
  500. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  501. Assert.IsTrue(reader.Read());
  502. Assert.AreEqual(JsonToken.Boolean, reader.TokenType);
  503. Assert.AreEqual(null, validationEventArgs);
  504. Assert.IsTrue(reader.Read());
  505. Assert.AreEqual(JsonToken.Boolean, reader.TokenType);
  506. Assert.AreEqual(@"Value false is not defined in enum. Line 1, position 11.", validationEventArgs.Message);
  507. Assert.AreEqual("[1]", validationEventArgs.Path);
  508. Assert.IsTrue(reader.Read());
  509. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  510. Assert.IsNotNull(validationEventArgs);
  511. }
  512. [Test]
  513. public void ArrayCountGreaterThanMaximumItems()
  514. {
  515. string schemaJson = @"{
  516. ""type"":""array"",
  517. ""minItems"":2,
  518. ""maxItems"":3
  519. }";
  520. string json = "[null,null,null,null]";
  521. Json.Schema.ValidationEventArgs validationEventArgs = null;
  522. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  523. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  524. reader.Schema = JsonSchema.Parse(schemaJson);
  525. Assert.IsTrue(reader.Read());
  526. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  527. Assert.IsTrue(reader.Read());
  528. Assert.AreEqual(JsonToken.Null, reader.TokenType);
  529. Assert.IsTrue(reader.Read());
  530. Assert.AreEqual(JsonToken.Null, reader.TokenType);
  531. Assert.IsTrue(reader.Read());
  532. Assert.AreEqual(JsonToken.Null, reader.TokenType);
  533. Assert.IsTrue(reader.Read());
  534. Assert.AreEqual(JsonToken.Null, reader.TokenType);
  535. Assert.IsTrue(reader.Read());
  536. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  537. Assert.AreEqual("Array item count 4 exceeds maximum count of 3. Line 1, position 21.", validationEventArgs.Message);
  538. Assert.IsNotNull(validationEventArgs);
  539. }
  540. [Test]
  541. public void ArrayCountLessThanMinimumItems()
  542. {
  543. string schemaJson = @"{
  544. ""type"":""array"",
  545. ""minItems"":2,
  546. ""maxItems"":3
  547. }";
  548. string json = "[null]";
  549. Json.Schema.ValidationEventArgs validationEventArgs = null;
  550. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  551. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  552. reader.Schema = JsonSchema.Parse(schemaJson);
  553. Assert.IsTrue(reader.Read());
  554. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  555. Assert.IsTrue(reader.Read());
  556. Assert.AreEqual(JsonToken.Null, reader.TokenType);
  557. Assert.IsTrue(reader.Read());
  558. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  559. Assert.AreEqual("Array item count 1 is less than minimum count of 2. Line 1, position 6.", validationEventArgs.Message);
  560. Assert.IsNotNull(validationEventArgs);
  561. }
  562. [Test]
  563. public void InvalidDataType()
  564. {
  565. string schemaJson = @"{
  566. ""type"":""string"",
  567. ""minItems"":2,
  568. ""maxItems"":3,
  569. ""items"":{}
  570. }";
  571. string json = "[null,null,null,null]";
  572. Json.Schema.ValidationEventArgs validationEventArgs = null;
  573. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  574. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  575. reader.Schema = JsonSchema.Parse(schemaJson);
  576. Assert.IsTrue(reader.Read());
  577. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  578. Assert.AreEqual(@"Invalid type. Expected String but got Array. Line 1, position 1.", validationEventArgs.Message);
  579. Assert.IsNotNull(validationEventArgs);
  580. }
  581. [Test]
  582. public void StringDisallowed()
  583. {
  584. string schemaJson = @"{
  585. ""type"":""array"",
  586. ""items"":{
  587. ""disallow"":[""number""]
  588. },
  589. ""maxItems"":3
  590. }";
  591. string json = "['pie',1.1]";
  592. Json.Schema.ValidationEventArgs validationEventArgs = null;
  593. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  594. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  595. reader.Schema = JsonSchema.Parse(schemaJson);
  596. Assert.IsTrue(reader.Read());
  597. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  598. Assert.IsTrue(reader.Read());
  599. Assert.AreEqual(JsonToken.String, reader.TokenType);
  600. Assert.AreEqual(null, validationEventArgs);
  601. Assert.IsTrue(reader.Read());
  602. Assert.AreEqual(JsonToken.Float, reader.TokenType);
  603. Assert.AreEqual(@"Type Float is disallowed. Line 1, position 10.", validationEventArgs.Message);
  604. Assert.IsTrue(reader.Read());
  605. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  606. Assert.IsNotNull(validationEventArgs);
  607. }
  608. [Test]
  609. public void MissingRequiredProperties()
  610. {
  611. string schemaJson = @"{
  612. ""description"":""A person"",
  613. ""type"":""object"",
  614. ""properties"":
  615. {
  616. ""name"":{""type"":""string""},
  617. ""hobbies"":{""type"":""string"",""required"":true},
  618. ""age"":{""type"":""integer"",""required"":true}
  619. }
  620. }";
  621. string json = "{'name':'James'}";
  622. Json.Schema.ValidationEventArgs validationEventArgs = null;
  623. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  624. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  625. reader.Schema = JsonSchema.Parse(schemaJson);
  626. Assert.IsTrue(reader.Read());
  627. Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
  628. Assert.IsTrue(reader.Read());
  629. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  630. Assert.AreEqual("name", reader.Value.ToString());
  631. Assert.IsTrue(reader.Read());
  632. Assert.AreEqual(JsonToken.String, reader.TokenType);
  633. Assert.AreEqual("James", reader.Value.ToString());
  634. Assert.AreEqual(null, validationEventArgs);
  635. Assert.IsTrue(reader.Read());
  636. Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
  637. Assert.AreEqual("Required properties are missing from object: hobbies, age. Line 1, position 16.", validationEventArgs.Message);
  638. Assert.AreEqual("", validationEventArgs.Path);
  639. Assert.IsNotNull(validationEventArgs);
  640. }
  641. [Test]
  642. public void MissingNonRequiredProperties()
  643. {
  644. string schemaJson = @"{
  645. ""description"":""A person"",
  646. ""type"":""object"",
  647. ""properties"":
  648. {
  649. ""name"":{""type"":""string"",""required"":true},
  650. ""hobbies"":{""type"":""string"",""required"":false},
  651. ""age"":{""type"":""integer""}
  652. }
  653. }";
  654. string json = "{'name':'James'}";
  655. Json.Schema.ValidationEventArgs validationEventArgs = null;
  656. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  657. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  658. reader.Schema = JsonSchema.Parse(schemaJson);
  659. Assert.IsTrue(reader.Read());
  660. Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
  661. Assert.IsTrue(reader.Read());
  662. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  663. Assert.AreEqual("name", reader.Value.ToString());
  664. Assert.IsTrue(reader.Read());
  665. Assert.AreEqual(JsonToken.String, reader.TokenType);
  666. Assert.AreEqual("James", reader.Value.ToString());
  667. Assert.IsNull(validationEventArgs);
  668. Assert.IsTrue(reader.Read());
  669. Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
  670. Assert.IsNull(validationEventArgs);
  671. }
  672. [Test]
  673. public void DisableAdditionalProperties()
  674. {
  675. string schemaJson = @"{
  676. ""description"":""A person"",
  677. ""type"":""object"",
  678. ""properties"":
  679. {
  680. ""name"":{""type"":""string""}
  681. },
  682. ""additionalProperties"":false
  683. }";
  684. string json = "{'name':'James','additionalProperty1':null,'additionalProperty2':null}";
  685. Json.Schema.ValidationEventArgs validationEventArgs = null;
  686. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  687. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  688. reader.Schema = JsonSchema.Parse(schemaJson);
  689. Assert.IsTrue(reader.Read());
  690. Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
  691. Assert.IsTrue(reader.Read());
  692. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  693. Assert.AreEqual("name", reader.Value.ToString());
  694. Assert.IsTrue(reader.Read());
  695. Assert.AreEqual(JsonToken.String, reader.TokenType);
  696. Assert.AreEqual("James", reader.Value.ToString());
  697. Assert.AreEqual(null, validationEventArgs);
  698. Assert.IsTrue(reader.Read());
  699. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  700. Assert.AreEqual("additionalProperty1", reader.Value.ToString());
  701. Assert.IsTrue(reader.Read());
  702. Assert.AreEqual(JsonToken.Null, reader.TokenType);
  703. Assert.AreEqual(null, reader.Value);
  704. Assert.AreEqual("Property 'additionalProperty1' has not been defined and the schema does not allow additional properties. Line 1, position 38.", validationEventArgs.Message);
  705. Assert.IsTrue(reader.Read());
  706. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  707. Assert.AreEqual("additionalProperty2", reader.Value.ToString());
  708. Assert.IsTrue(reader.Read());
  709. Assert.AreEqual(JsonToken.Null, reader.TokenType);
  710. Assert.AreEqual(null, reader.Value);
  711. Assert.AreEqual("Property 'additionalProperty2' has not been defined and the schema does not allow additional properties. Line 1, position 65.", validationEventArgs.Message);
  712. Assert.IsTrue(reader.Read());
  713. Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
  714. Assert.IsNotNull(validationEventArgs);
  715. }
  716. [Test]
  717. public void ExtendsStringGreaterThanMaximumLength()
  718. {
  719. string schemaJson = @"{
  720. ""extends"":{
  721. ""type"":""string"",
  722. ""minLength"":5,
  723. ""maxLength"":10
  724. },
  725. ""maxLength"":9
  726. }";
  727. List<string> errors = new List<string>();
  728. string json = "'The quick brown fox jumps over the lazy dog.'";
  729. Json.Schema.ValidationEventArgs validationEventArgs = null;
  730. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  731. reader.ValidationEventHandler += (sender, args) =>
  732. {
  733. validationEventArgs = args;
  734. errors.Add(validationEventArgs.Message);
  735. };
  736. reader.Schema = JsonSchema.Parse(schemaJson);
  737. Assert.IsTrue(reader.Read());
  738. Assert.AreEqual(JsonToken.String, reader.TokenType);
  739. Assert.AreEqual(1, errors.Count);
  740. Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' exceeds maximum length of 9. Line 1, position 46.", errors[0]);
  741. Assert.IsNotNull(validationEventArgs);
  742. }
  743. private JsonSchema GetExtendedSchema()
  744. {
  745. string first = @"{
  746. ""id"":""first"",
  747. ""type"":""object"",
  748. ""properties"":
  749. {
  750. ""firstproperty"":{""type"":""string"",""required"":true}
  751. },
  752. ""additionalProperties"":{}
  753. }";
  754. string second = @"{
  755. ""id"":""second"",
  756. ""type"":""object"",
  757. ""extends"":{""$ref"":""first""},
  758. ""properties"":
  759. {
  760. ""secondproperty"":{""type"":""string"",""required"":true}
  761. },
  762. ""additionalProperties"":false
  763. }";
  764. JsonSchemaResolver resolver = new JsonSchemaResolver();
  765. JsonSchema firstSchema = JsonSchema.Parse(first, resolver);
  766. JsonSchema secondSchema = JsonSchema.Parse(second, resolver);
  767. return secondSchema;
  768. }
  769. [Test]
  770. public void ExtendsDisallowAdditionProperties()
  771. {
  772. string json = "{'firstproperty':'blah','secondproperty':'blah2','additional':'blah3','additional2':'blah4'}";
  773. Json.Schema.ValidationEventArgs validationEventArgs = null;
  774. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  775. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  776. reader.Schema = GetExtendedSchema();
  777. Assert.IsTrue(reader.Read());
  778. Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
  779. Assert.IsTrue(reader.Read());
  780. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  781. Assert.AreEqual("firstproperty", reader.Value.ToString());
  782. Assert.AreEqual(null, validationEventArgs);
  783. Assert.IsTrue(reader.Read());
  784. Assert.AreEqual(JsonToken.String, reader.TokenType);
  785. Assert.AreEqual("blah", reader.Value.ToString());
  786. Assert.AreEqual(null, validationEventArgs);
  787. Assert.IsTrue(reader.Read());
  788. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  789. Assert.AreEqual("secondproperty", reader.Value.ToString());
  790. Assert.AreEqual(null, validationEventArgs);
  791. Assert.IsTrue(reader.Read());
  792. Assert.AreEqual(JsonToken.String, reader.TokenType);
  793. Assert.AreEqual("blah2", reader.Value.ToString());
  794. Assert.AreEqual(null, validationEventArgs);
  795. Assert.IsTrue(reader.Read());
  796. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  797. Assert.AreEqual("additional", reader.Value.ToString());
  798. Assert.AreEqual("Property 'additional' has not been defined and the schema does not allow additional properties. Line 1, position 62.", validationEventArgs.Message);
  799. Assert.IsTrue(reader.Read());
  800. Assert.AreEqual(JsonToken.String, reader.TokenType);
  801. Assert.AreEqual("blah3", reader.Value.ToString());
  802. Assert.IsTrue(reader.Read());
  803. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  804. Assert.AreEqual("additional2", reader.Value.ToString());
  805. Assert.AreEqual("Property 'additional2' has not been defined and the schema does not allow additional properties. Line 1, position 84.", validationEventArgs.Message);
  806. Assert.IsTrue(reader.Read());
  807. Assert.AreEqual(JsonToken.String, reader.TokenType);
  808. Assert.AreEqual("blah4", reader.Value.ToString());
  809. Assert.IsTrue(reader.Read());
  810. Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
  811. Assert.IsFalse(reader.Read());
  812. }
  813. [Test]
  814. public void ExtendsMissingRequiredProperties()
  815. {
  816. string json = "{}";
  817. List<string> errors = new List<string>();
  818. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  819. reader.ValidationEventHandler += (sender, args) => { errors.Add(args.Message); };
  820. reader.Schema = GetExtendedSchema();
  821. Assert.IsTrue(reader.Read());
  822. Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
  823. Assert.IsTrue(reader.Read());
  824. Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
  825. Assert.AreEqual(1, errors.Count);
  826. Assert.AreEqual("Required properties are missing from object: secondproperty, firstproperty. Line 1, position 2.", errors[0]);
  827. }
  828. [Test]
  829. public void NoAdditionalProperties()
  830. {
  831. string schemaJson = @"{
  832. ""type"":""array"",
  833. ""items"": [{""type"":""string""},{""type"":""integer""}],
  834. ""additionalProperties"": false
  835. }";
  836. string json = @"[1, 'a', null]";
  837. Json.Schema.ValidationEventArgs validationEventArgs = null;
  838. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  839. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  840. reader.Schema = JsonSchema.Parse(schemaJson);
  841. Assert.IsTrue(reader.Read());
  842. Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
  843. Assert.IsTrue(reader.Read());
  844. Assert.AreEqual(JsonToken.Integer, reader.TokenType);
  845. Assert.AreEqual("Invalid type. Expected String but got Integer. Line 1, position 2.", validationEventArgs.Message);
  846. Assert.IsTrue(reader.Read());
  847. Assert.AreEqual(JsonToken.String, reader.TokenType);
  848. Assert.AreEqual("Invalid type. Expected Integer but got String. Line 1, position 7.", validationEventArgs.Message);
  849. Assert.IsTrue(reader.Read());
  850. Assert.AreEqual(JsonToken.Null, reader.TokenType);
  851. Assert.AreEqual("Index 3 has not been defined and the schema does not allow additional items. Line 1, position 13.", validationEventArgs.Message);
  852. Assert.IsTrue(reader.Read());
  853. Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
  854. Assert.IsFalse(reader.Read());
  855. }
  856. [Test]
  857. public void PatternPropertiesNoAdditionalProperties()
  858. {
  859. string schemaJson = @"{
  860. ""type"":""object"",
  861. ""patternProperties"": {
  862. ""hi"": {""type"":""string""},
  863. ""ho"": {""type"":""string""}
  864. },
  865. ""additionalProperties"": false
  866. }";
  867. string json = @"{
  868. ""hi"": ""A string!"",
  869. ""hide"": ""A string!"",
  870. ""ho"": 1,
  871. ""hey"": ""A string!""
  872. }";
  873. Json.Schema.ValidationEventArgs validationEventArgs = null;
  874. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  875. reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
  876. reader.Schema = JsonSchema.Parse(schemaJson);
  877. Assert.IsTrue(reader.Read());
  878. Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
  879. Assert.IsTrue(reader.Read());
  880. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  881. Assert.AreEqual(null, validationEventArgs);
  882. Assert.IsTrue(reader.Read());
  883. Assert.AreEqual(JsonToken.String, reader.TokenType);
  884. Assert.IsTrue(reader.Read());
  885. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  886. Assert.AreEqual(null, validationEventArgs);
  887. Assert.IsTrue(reader.Read());
  888. Assert.AreEqual(JsonToken.String, reader.TokenType);
  889. Assert.IsTrue(reader.Read());
  890. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  891. Assert.AreEqual(null, validationEventArgs);
  892. Assert.IsTrue(reader.Read());
  893. Assert.AreEqual(JsonToken.Integer, reader.TokenType);
  894. Assert.AreEqual("Invalid type. Expected String but got Integer. Line 4, position 10.", validationEventArgs.Message);
  895. Assert.IsTrue(reader.Read());
  896. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  897. Assert.AreEqual("Property 'hey' has not been defined and the schema does not allow additional properties. Line 5, position 9.", validationEventArgs.Message);
  898. Assert.IsTrue(reader.Read());
  899. Assert.AreEqual(JsonToken.String, reader.TokenType);
  900. Assert.IsTrue(reader.Read());
  901. Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
  902. Assert.IsFalse(reader.Read());
  903. }
  904. [Test]
  905. public void ExtendedComplex()
  906. {
  907. string first = @"{
  908. ""id"":""first"",
  909. ""type"":""object"",
  910. ""properties"":
  911. {
  912. ""firstproperty"":{""type"":""string""},
  913. ""secondproperty"":{""type"":""string"",""maxLength"":10},
  914. ""thirdproperty"":{
  915. ""type"":""object"",
  916. ""properties"":
  917. {
  918. ""thirdproperty_firstproperty"":{""type"":""string"",""maxLength"":10,""minLength"":7}
  919. }
  920. }
  921. },
  922. ""additionalProperties"":{}
  923. }";
  924. string second = @"{
  925. ""id"":""second"",
  926. ""type"":""object"",
  927. ""extends"":{""$ref"":""first""},
  928. ""properties"":
  929. {
  930. ""secondproperty"":{""type"":""any""},
  931. ""thirdproperty"":{
  932. ""extends"":{
  933. ""properties"":
  934. {
  935. ""thirdproperty_firstproperty"":{""maxLength"":9,""minLength"":6,""pattern"":""hi2u""}
  936. },
  937. ""additionalProperties"":{""maxLength"":9,""minLength"":6,""enum"":[""one"",""two""]}
  938. },
  939. ""type"":""object"",
  940. ""properties"":
  941. {
  942. ""thirdproperty_firstproperty"":{""pattern"":""hi""}
  943. },
  944. ""additionalProperties"":{""type"":""string"",""enum"":[""two"",""three""]}
  945. },
  946. ""fourthproperty"":{""type"":""string""}
  947. },
  948. ""additionalProperties"":false
  949. }";
  950. JsonSchemaResolver resolver = new JsonSchemaResolver();
  951. JsonSchema firstSchema = JsonSchema.Parse(first, resolver);
  952. JsonSchema secondSchema = JsonSchema.Parse(second, resolver);
  953. JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder();
  954. string json = @"{
  955. 'firstproperty':'blahblahblahblahblahblah',
  956. 'secondproperty':'secasecasecasecaseca',
  957. 'thirdproperty':{
  958. 'thirdproperty_firstproperty':'aaa',
  959. 'additional':'three'
  960. }
  961. }";
  962. Json.Schema.ValidationEventArgs validationEventArgs = null;
  963. List<string> errors = new List<string>();
  964. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  965. reader.ValidationEventHandler += (sender, args) =>
  966. {
  967. validationEventArgs = args;
  968. errors.Add(validationEventArgs.Path + " - " + validationEventArgs.Message);
  969. };
  970. reader.Schema = secondSchema;
  971. Assert.IsTrue(reader.Read());
  972. Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
  973. Assert.IsTrue(reader.Read());
  974. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  975. Assert.AreEqual("firstproperty", reader.Value.ToString());
  976. Assert.AreEqual(null, validationEventArgs);
  977. Assert.IsTrue(reader.Read());
  978. Assert.AreEqual(JsonToken.String, reader.TokenType);
  979. Assert.AreEqual("blahblahblahblahblahblah", reader.Value.ToString());
  980. Assert.IsTrue(reader.Read());
  981. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  982. Assert.AreEqual("secondproperty", reader.Value.ToString());
  983. Assert.IsTrue(reader.Read());
  984. Assert.AreEqual(JsonToken.String, reader.TokenType);
  985. Assert.AreEqual("secasecasecasecaseca", reader.Value.ToString());
  986. Assert.AreEqual(1, errors.Count);
  987. Assert.AreEqual("secondproperty - String 'secasecasecasecaseca' exceeds maximum length of 10. Line 3, position 42.", errors[0]);
  988. Assert.IsTrue(reader.Read());
  989. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  990. Assert.AreEqual("thirdproperty", reader.Value.ToString());
  991. Assert.AreEqual(1, errors.Count);
  992. Assert.IsTrue(reader.Read());
  993. Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
  994. Assert.AreEqual(1, errors.Count);
  995. Assert.IsTrue(reader.Read());
  996. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  997. Assert.AreEqual("thirdproperty_firstproperty", reader.Value.ToString());
  998. Assert.AreEqual(1, errors.Count);
  999. Assert.IsTrue(reader.Read());
  1000. Assert.AreEqual(JsonToken.String, reader.TokenType);
  1001. Assert.AreEqual("aaa", reader.Value.ToString());
  1002. Assert.AreEqual(4, errors.Count);
  1003. Assert.AreEqual("thirdproperty.thirdproperty_firstproperty - String 'aaa' is less than minimum length of 7. Line 5, position 40.", errors[1]);
  1004. Assert.AreEqual("thirdproperty.thirdproperty_firstproperty - String 'aaa' does not match regex pattern 'hi'. Line 5, position 40.", errors[2]);
  1005. Assert.AreEqual("thirdproperty.thirdproperty_firstproperty - String 'aaa' does not match regex pattern 'hi2u'. Line 5, position 40.", errors[3]);
  1006. Assert.IsTrue(reader.Read());
  1007. Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
  1008. Assert.AreEqual("additional", reader.Value.ToString());
  1009. Assert.AreEqual(4, errors.Count);
  1010. Assert.IsTrue(reader.Read());
  1011. Assert.AreEqual(JsonToken.String, reader.TokenType);
  1012. Assert.AreEqual("three", reader.Value.ToString());
  1013. Assert.AreEqual(5, errors.Count);
  1014. Assert.AreEqual("thirdproperty.additional - String 'three' is less than minimum length of 6. Line 6, position 25.", errors[4]);
  1015. Assert.IsTrue(reader.Read());
  1016. Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
  1017. Assert.IsTrue(reader.Read());
  1018. Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
  1019. Assert.IsFalse(reader.Read());
  1020. }
  1021. [Test]
  1022. public void DuplicateErrorsTest()
  1023. {
  1024. string schema = @"{
  1025. ""id"":""ErrorDemo.Database"",
  1026. ""properties"":{
  1027. ""ErrorDemoDatabase"":{
  1028. ""type"":""object"",
  1029. ""required"":true,
  1030. ""properties"":{
  1031. ""URL"":{
  1032. ""type"":""string"",
  1033. ""required"":true
  1034. },
  1035. ""Version"":{
  1036. ""type"":""string"",
  1037. ""required"":true
  1038. },
  1039. ""Date"":{
  1040. ""type"":""string"",
  1041. ""format"":""date-time"",
  1042. ""required"":true
  1043. },
  1044. ""MACLevels"":{
  1045. ""type"":""object"",
  1046. ""required"":true,
  1047. ""properties"":{
  1048. ""MACLevel"":{
  1049. ""type"":""array"",
  1050. ""required"":true,
  1051. ""items"":[
  1052. {
  1053. ""required"":true,
  1054. ""properties"":{
  1055. ""IDName"":{
  1056. ""type"":""string"",
  1057. ""required"":true
  1058. },
  1059. ""Order"":{
  1060. ""type"":""string"",
  1061. ""required"":true
  1062. },
  1063. ""IDDesc"":{
  1064. ""type"":""string"",
  1065. ""required"":true
  1066. },
  1067. ""IsActive"":{
  1068. ""type"":""string"",
  1069. ""required"":true
  1070. }
  1071. }
  1072. }
  1073. ]
  1074. }
  1075. }
  1076. }
  1077. }
  1078. }
  1079. }
  1080. }";
  1081. string json = @"{
  1082. ""ErrorDemoDatabase"":{
  1083. ""URL"":""localhost:3164"",
  1084. ""Version"":""1.0"",
  1085. ""Date"":""6.23.2010, 9:35:18.121"",
  1086. ""MACLevels"":{
  1087. ""MACLevel"":[
  1088. {
  1089. ""@IDName"":""Developer"",
  1090. ""Order"":""0"",
  1091. ""IDDesc"":""DeveloperDesc"",
  1092. ""IsActive"":""True""
  1093. },
  1094. {
  1095. ""IDName"":""Technician"",
  1096. ""Order"":""1"",
  1097. ""IDDesc"":""TechnicianDesc"",
  1098. ""IsActive"":""True""
  1099. },
  1100. {
  1101. ""IDName"":""Administrator"",
  1102. ""Order"":""2"",
  1103. ""IDDesc"":""AdministratorDesc"",
  1104. ""IsActive"":""True""
  1105. },
  1106. {
  1107. ""IDName"":""PowerUser"",
  1108. ""Order"":""3"",
  1109. ""IDDesc"":""PowerUserDesc"",
  1110. ""IsActive"":""True""
  1111. },
  1112. {
  1113. ""IDName"":""Operator"",
  1114. ""Order"":""4"",
  1115. ""IDDesc"":""OperatorDesc"",
  1116. ""IsActive"":""True""
  1117. }
  1118. ]
  1119. }
  1120. }
  1121. }";
  1122. IList<ValidationEventArgs> validationEventArgs = new List<ValidationEventArgs>();
  1123. JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
  1124. reader.ValidationEventHandler += (sender, args) =>
  1125. {
  1126. validationEventArgs.Add(args);
  1127. };
  1128. reader.Schema = JsonSchema.Parse(schema);
  1129. while (reader.Read())
  1130. {
  1131. }
  1132. Assert.AreEqual(1, validationEventArgs.Count);
  1133. }
  1134. [Test]
  1135. public void ReadAsBytes()
  1136. {
  1137. JsonSchema s = new JsonSchemaGenerator().Generate(typeof (byte[]));
  1138. byte[] data = Encoding.UTF8.GetBytes("Hello world");
  1139. JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"""" + Convert.ToBase64String(data) + @"""")))
  1140. {
  1141. Schema = s
  1142. };
  1143. byte[] bytes = reader.ReadAsBytes();
  1144. CollectionAssert.AreEquivalent(data, bytes);
  1145. }
  1146. [Test]
  1147. public void ReadAsInt32()
  1148. {
  1149. JsonSchema s = new JsonSchemaGenerator().Generate(typeof (int));
  1150. JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"1")))
  1151. {
  1152. Schema = s
  1153. };
  1154. int? i = reader.ReadAsInt32();
  1155. Assert.AreEqual(1, i);
  1156. }
  1157. [Test]
  1158. public void ReadAsInt32Failure()
  1159. {
  1160. ExceptionAssert.Throws<JsonSchemaException>("Integer 5 exceeds maximum value of 2. Line 1, position 1.",
  1161. () =>
  1162. {
  1163. JsonSchema s = new JsonSchemaGenerator().Generate(typeof(int));
  1164. s.Maximum = 2;
  1165. JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"5")))
  1166. {
  1167. Schema = s
  1168. };
  1169. reader.ReadAsInt32();
  1170. });
  1171. }
  1172. [Test]
  1173. public void ReadAsDecimal()
  1174. {
  1175. JsonSchema s = new JsonSchemaGenerator().Generate(typeof (decimal));
  1176. JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"1.5")))
  1177. {
  1178. Schema = s
  1179. };
  1180. decimal? d = reader.ReadAsDecimal();
  1181. Assert.AreEqual(1.5m, d);
  1182. }
  1183. [Test]
  1184. public void ReadAsDecimalFailure()
  1185. {
  1186. ExceptionAssert.Throws<JsonSchemaException>("Float 5.5 is not evenly divisible by 1. Line 1, position 3.",
  1187. () =>
  1188. {
  1189. JsonSchema s = new JsonSchemaGenerator().Generate(typeof(decimal));
  1190. s.DivisibleBy = 1;
  1191. JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringR

Large files files are truncated, but you can click here to view the full file