2 using System.Collections.Generic;
8 using System.Xml.Schema;
9 using Newtonsoft.Json.Schema;
11 namespace Newtonsoft.Json.Tests
13 public class JsonValidatingReaderTests : TestFixtureBase
16 public void CheckInnerReader()
18 string json = "{'name':'James','hobbies':['pie','cake']}";
19 JsonReader reader = new JsonTextReader(new StringReader(json));
21 JsonValidatingReader validatingReader = new JsonValidatingReader(reader);
22 Assert.AreEqual(reader, validatingReader.Reader);
26 public void ValidateTypes()
28 string schemaJson = @"{
29 ""description"":""A person"",
33 ""name"":{""type"":""string""},
37 ""items"": {""type"":""string""}
42 string json = @"{'name':""James"",'hobbies':[""pie"",'cake']}";
44 Json.Schema.ValidationEventArgs validationEventArgs = null;
46 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
47 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
48 JsonSchema schema = JsonSchema.Parse(schemaJson);
49 reader.Schema = schema;
50 Assert.AreEqual(schema, reader.Schema);
52 Assert.AreEqual(0, reader.Depth);
54 Assert.IsTrue(reader.Read());
55 Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
57 Assert.IsTrue(reader.Read());
58 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
59 Assert.AreEqual("name", reader.Value.ToString());
61 Assert.AreEqual(1, reader.Depth);
63 Assert.IsTrue(reader.Read());
64 Assert.AreEqual(JsonToken.String, reader.TokenType);
65 Assert.AreEqual("James", reader.Value.ToString());
66 Assert.AreEqual(typeof(string), reader.ValueType);
67 Assert.AreEqual('"', reader.QuoteChar);
69 Assert.IsTrue(reader.Read());
70 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
71 Assert.AreEqual("hobbies", reader.Value.ToString());
72 Assert.AreEqual('\'', reader.QuoteChar);
74 Assert.IsTrue(reader.Read());
75 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
77 Assert.IsTrue(reader.Read());
78 Assert.AreEqual(JsonToken.String, reader.TokenType);
79 Assert.AreEqual("pie", reader.Value.ToString());
80 Assert.AreEqual('"', reader.QuoteChar);
82 Assert.IsTrue(reader.Read());
83 Assert.AreEqual(JsonToken.String, reader.TokenType);
84 Assert.AreEqual("cake", reader.Value.ToString());
86 Assert.IsTrue(reader.Read());
87 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
89 Assert.IsTrue(reader.Read());
90 Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
92 Assert.IsNull(validationEventArgs);
96 public void ValidateUnrestrictedArray()
98 string schemaJson = @"{
102 string json = "['pie','cake',['nested1','nested2'],{'nestedproperty1':1.1,'nestedproperty2':[null]}]";
104 Json.Schema.ValidationEventArgs validationEventArgs = null;
106 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
107 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
108 reader.Schema = JsonSchema.Parse(schemaJson);
110 Assert.IsTrue(reader.Read());
111 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
113 Assert.IsTrue(reader.Read());
114 Assert.AreEqual(JsonToken.String, reader.TokenType);
115 Assert.AreEqual("pie", reader.Value.ToString());
117 Assert.IsTrue(reader.Read());
118 Assert.AreEqual(JsonToken.String, reader.TokenType);
119 Assert.AreEqual("cake", reader.Value.ToString());
121 Assert.IsTrue(reader.Read());
122 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
124 Assert.IsTrue(reader.Read());
125 Assert.AreEqual(JsonToken.String, reader.TokenType);
126 Assert.AreEqual("nested1", reader.Value.ToString());
128 Assert.IsTrue(reader.Read());
129 Assert.AreEqual(JsonToken.String, reader.TokenType);
130 Assert.AreEqual("nested2", reader.Value.ToString());
132 Assert.IsTrue(reader.Read());
133 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
135 Assert.IsTrue(reader.Read());
136 Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
138 Assert.IsTrue(reader.Read());
139 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
140 Assert.AreEqual("nestedproperty1", reader.Value.ToString());
142 Assert.IsTrue(reader.Read());
143 Assert.AreEqual(JsonToken.Float, reader.TokenType);
144 Assert.AreEqual(1.1, reader.Value);
146 Assert.IsTrue(reader.Read());
147 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
148 Assert.AreEqual("nestedproperty2", reader.Value.ToString());
150 Assert.IsTrue(reader.Read());
151 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
153 Assert.IsTrue(reader.Read());
154 Assert.AreEqual(JsonToken.Null, reader.TokenType);
156 Assert.IsTrue(reader.Read());
157 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
159 Assert.IsTrue(reader.Read());
160 Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
162 Assert.IsTrue(reader.Read());
163 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
165 Assert.IsNull(validationEventArgs);
169 public void StringLessThanMinimumLength()
171 string schemaJson = @"{
177 string json = "'pie'";
179 Json.Schema.ValidationEventArgs validationEventArgs = null;
181 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
182 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
183 reader.Schema = JsonSchema.Parse(schemaJson);
185 Assert.IsTrue(reader.Read());
186 Assert.AreEqual(JsonToken.String, reader.TokenType);
187 Assert.AreEqual("String 'pie' is less than minimum length of 5. Line 1, position 5.", validationEventArgs.Message);
189 Assert.IsNotNull(validationEventArgs);
193 public void StringGreaterThanMaximumLength()
195 string schemaJson = @"{
201 string json = "'The quick brown fox jumps over the lazy dog.'";
203 Json.Schema.ValidationEventArgs validationEventArgs = null;
205 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
206 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
207 reader.Schema = JsonSchema.Parse(schemaJson);
209 Assert.IsTrue(reader.Read());
210 Assert.AreEqual(JsonToken.String, reader.TokenType);
211 Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' exceeds maximum length of 10. Line 1, position 46.", validationEventArgs.Message);
213 Assert.IsNotNull(validationEventArgs);
217 public void StringIsNotInEnum()
219 string schemaJson = @"{
223 ""enum"":[""one"",""two""]
228 string json = "['one','two','THREE']";
230 Json.Schema.ValidationEventArgs validationEventArgs = null;
232 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
233 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
234 reader.Schema = JsonSchema.Parse(schemaJson);
236 Assert.IsTrue(reader.Read());
237 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
239 Assert.IsTrue(reader.Read());
240 Assert.AreEqual(JsonToken.String, reader.TokenType);
242 Assert.IsTrue(reader.Read());
243 Assert.AreEqual(JsonToken.String, reader.TokenType);
244 Assert.AreEqual(null, validationEventArgs);
246 Assert.IsTrue(reader.Read());
247 Assert.AreEqual(JsonToken.String, reader.TokenType);
248 Assert.AreEqual(@"Value ""THREE"" is not defined in enum. Line 1, position 20.", validationEventArgs.Message);
250 Assert.IsTrue(reader.Read());
251 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
253 Assert.IsNotNull(validationEventArgs);
257 public void StringDoesNotMatchPattern()
259 string schemaJson = @"{
264 string json = "'The quick brown fox jumps over the lazy dog.'";
266 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);
272 Assert.IsTrue(reader.Read());
273 Assert.AreEqual(JsonToken.String, reader.TokenType);
274 Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' does not match regex pattern 'foo'. Line 1, position 46.", validationEventArgs.Message);
276 Assert.IsNotNull(validationEventArgs);
280 public void IntegerGreaterThanMaximumValue()
282 string schemaJson = @"{
283 ""type"":""integer"",
289 Json.Schema.ValidationEventArgs validationEventArgs = null;
291 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
292 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
293 reader.Schema = JsonSchema.Parse(schemaJson);
295 Assert.IsTrue(reader.Read());
296 Assert.AreEqual(JsonToken.Integer, reader.TokenType);
297 Assert.AreEqual("Integer 10 exceeds maximum value of 5. Line 1, position 2.", validationEventArgs.Message);
299 Assert.IsNotNull(validationEventArgs);
303 [ExpectedException(typeof(JsonSchemaException), ExpectedMessage = "Integer 10 exceeds maximum value of 5. Line 1, position 2.")]
304 public void ThrowExceptionWhenNoValidationEventHandler()
306 string schemaJson = @"{
307 ""type"":""integer"",
311 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader("10")));
312 reader.Schema = JsonSchema.Parse(schemaJson);
314 Assert.IsTrue(reader.Read());
318 public void IntegerLessThanMinimumValue()
320 string schemaJson = @"{
321 ""type"":""integer"",
327 Json.Schema.ValidationEventArgs validationEventArgs = null;
329 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
330 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
331 reader.Schema = JsonSchema.Parse(schemaJson);
333 Assert.IsTrue(reader.Read());
334 Assert.AreEqual(JsonToken.Integer, reader.TokenType);
335 Assert.AreEqual("Integer 1 is less than minimum value of 5. Line 1, position 1.", validationEventArgs.Message);
337 Assert.IsNotNull(validationEventArgs);
341 public void IntegerIsNotInEnum()
343 string schemaJson = @"{
346 ""type"":""integer"",
352 string json = "[1,2,3]";
354 Json.Schema.ValidationEventArgs validationEventArgs = null;
356 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
357 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
358 reader.Schema = JsonSchema.Parse(schemaJson);
360 Assert.IsTrue(reader.Read());
361 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
363 Assert.IsTrue(reader.Read());
364 Assert.AreEqual(JsonToken.Integer, reader.TokenType);
366 Assert.IsTrue(reader.Read());
367 Assert.AreEqual(JsonToken.Integer, reader.TokenType);
368 Assert.AreEqual(null, validationEventArgs);
370 Assert.IsTrue(reader.Read());
371 Assert.AreEqual(JsonToken.Integer, reader.TokenType);
372 Assert.AreEqual(@"Value 3 is not defined in enum. Line 1, position 7.", validationEventArgs.Message);
374 Assert.IsTrue(reader.Read());
375 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
377 Assert.IsNotNull(validationEventArgs);
381 public void FloatGreaterThanMaximumValue()
383 string schemaJson = @"{
388 string json = "10.0";
390 Json.Schema.ValidationEventArgs validationEventArgs = null;
392 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
393 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
394 reader.Schema = JsonSchema.Parse(schemaJson);
396 Assert.IsTrue(reader.Read());
397 Assert.AreEqual(JsonToken.Float, reader.TokenType);
398 Assert.AreEqual("Float 10.0 exceeds maximum value of 5. Line 1, position 4.", validationEventArgs.Message);
400 Assert.IsNotNull(validationEventArgs);
404 public void FloatLessThanMinimumValue()
406 string schemaJson = @"{
413 Json.Schema.ValidationEventArgs validationEventArgs = null;
415 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
416 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
417 reader.Schema = JsonSchema.Parse(schemaJson);
419 Assert.IsTrue(reader.Read());
420 Assert.AreEqual(JsonToken.Float, reader.TokenType);
421 Assert.AreEqual("Float 1.1 is less than minimum value of 5. Line 1, position 3.", validationEventArgs.Message);
423 Assert.IsNotNull(validationEventArgs);
427 public void FloatIsNotInEnum()
429 string schemaJson = @"{
438 string json = "[1.1,2.2,3.0]";
440 Json.Schema.ValidationEventArgs validationEventArgs = null;
442 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
443 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
444 reader.Schema = JsonSchema.Parse(schemaJson);
446 Assert.IsTrue(reader.Read());
447 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
449 Assert.IsTrue(reader.Read());
450 Assert.AreEqual(JsonToken.Float, reader.TokenType);
452 Assert.IsTrue(reader.Read());
453 Assert.AreEqual(JsonToken.Float, reader.TokenType);
454 Assert.AreEqual(null, validationEventArgs);
456 Assert.IsTrue(reader.Read());
457 Assert.AreEqual(JsonToken.Float, reader.TokenType);
458 Assert.AreEqual(@"Value 3.0 is not defined in enum. Line 1, position 13.", validationEventArgs.Message);
460 Assert.IsTrue(reader.Read());
461 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
463 Assert.IsNotNull(validationEventArgs);
467 public void FloatExceedsMaxDecimalPlaces()
469 string schemaJson = @"{
477 string json = "[1.1,2.2,4.001]";
479 Json.Schema.ValidationEventArgs validationEventArgs = null;
481 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
482 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
483 reader.Schema = JsonSchema.Parse(schemaJson);
485 Assert.IsTrue(reader.Read());
486 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
488 Assert.IsTrue(reader.Read());
489 Assert.AreEqual(JsonToken.Float, reader.TokenType);
491 Assert.IsTrue(reader.Read());
492 Assert.AreEqual(JsonToken.Float, reader.TokenType);
493 Assert.AreEqual(null, validationEventArgs);
495 Assert.IsTrue(reader.Read());
496 Assert.AreEqual(JsonToken.Float, reader.TokenType);
497 Assert.AreEqual(@"Float 4.001 is not evenly divisible by 0.1. Line 1, position 15.", validationEventArgs.Message);
499 Assert.IsTrue(reader.Read());
500 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
502 Assert.IsNotNull(validationEventArgs);
506 public void NullNotInEnum()
508 string schemaJson = @"{
517 string json = "[null]";
519 Json.Schema.ValidationEventArgs validationEventArgs = null;
521 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
522 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
523 reader.Schema = JsonSchema.Parse(schemaJson);
525 Assert.IsTrue(reader.Read());
526 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
528 Assert.IsTrue(reader.Read());
529 Assert.AreEqual(JsonToken.Null, reader.TokenType);
530 Assert.AreEqual(@"Value null is not defined in enum. Line 1, position 5.", validationEventArgs.Message);
532 Assert.IsTrue(reader.Read());
533 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
535 Assert.IsNotNull(validationEventArgs);
539 public void BooleanNotInEnum()
541 string schemaJson = @"{
544 ""type"":""boolean"",
550 string json = "[true,false]";
552 Json.Schema.ValidationEventArgs validationEventArgs = null;
554 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
555 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
556 reader.Schema = JsonSchema.Parse(schemaJson);
558 Assert.IsTrue(reader.Read());
559 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
561 Assert.IsTrue(reader.Read());
562 Assert.AreEqual(JsonToken.Boolean, reader.TokenType);
563 Assert.AreEqual(null, validationEventArgs);
565 Assert.IsTrue(reader.Read());
566 Assert.AreEqual(JsonToken.Boolean, reader.TokenType);
567 Assert.AreEqual(@"Value false is not defined in enum. Line 1, position 11.", validationEventArgs.Message);
569 Assert.IsTrue(reader.Read());
570 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
572 Assert.IsNotNull(validationEventArgs);
576 public void ArrayCountGreaterThanMaximumItems()
578 string schemaJson = @"{
584 string json = "[null,null,null,null]";
586 Json.Schema.ValidationEventArgs validationEventArgs = null;
588 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
589 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
590 reader.Schema = JsonSchema.Parse(schemaJson);
592 Assert.IsTrue(reader.Read());
593 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
595 Assert.IsTrue(reader.Read());
596 Assert.AreEqual(JsonToken.Null, reader.TokenType);
597 Assert.IsTrue(reader.Read());
598 Assert.AreEqual(JsonToken.Null, reader.TokenType);
599 Assert.IsTrue(reader.Read());
600 Assert.AreEqual(JsonToken.Null, reader.TokenType);
601 Assert.IsTrue(reader.Read());
602 Assert.AreEqual(JsonToken.Null, reader.TokenType);
604 Assert.IsTrue(reader.Read());
605 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
606 Assert.AreEqual("Array item count 4 exceeds maximum count of 3. Line 1, position 21.", validationEventArgs.Message);
608 Assert.IsNotNull(validationEventArgs);
612 public void ArrayCountLessThanMinimumItems()
614 string schemaJson = @"{
620 string json = "[null]";
622 Json.Schema.ValidationEventArgs validationEventArgs = null;
624 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
625 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
626 reader.Schema = JsonSchema.Parse(schemaJson);
628 Assert.IsTrue(reader.Read());
629 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
631 Assert.IsTrue(reader.Read());
632 Assert.AreEqual(JsonToken.Null, reader.TokenType);
634 Assert.IsTrue(reader.Read());
635 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
636 Assert.AreEqual("Array item count 1 is less than minimum count of 2. Line 1, position 6.", validationEventArgs.Message);
638 Assert.IsNotNull(validationEventArgs);
642 public void InvalidDataType()
644 string schemaJson = @"{
651 string json = "[null,null,null,null]";
653 Json.Schema.ValidationEventArgs validationEventArgs = null;
655 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
656 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
657 reader.Schema = JsonSchema.Parse(schemaJson);
659 Assert.IsTrue(reader.Read());
660 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
661 Assert.AreEqual(@"Invalid type. Expected String but got Array. Line 1, position 1.", validationEventArgs.Message);
663 Assert.IsNotNull(validationEventArgs);
667 public void StringDisallowed()
669 string schemaJson = @"{
672 ""disallow"":[""number""]
677 string json = "['pie',1.1]";
679 Json.Schema.ValidationEventArgs validationEventArgs = null;
681 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
682 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
683 reader.Schema = JsonSchema.Parse(schemaJson);
685 Assert.IsTrue(reader.Read());
686 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
688 Assert.IsTrue(reader.Read());
689 Assert.AreEqual(JsonToken.String, reader.TokenType);
690 Assert.AreEqual(null, validationEventArgs);
692 Assert.IsTrue(reader.Read());
693 Assert.AreEqual(JsonToken.Float, reader.TokenType);
694 Assert.AreEqual(@"Type Float is disallowed. Line 1, position 11.", validationEventArgs.Message);
696 Assert.IsTrue(reader.Read());
697 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
699 Assert.IsNotNull(validationEventArgs);
703 public void MissingRequiredProperties()
705 string schemaJson = @"{
706 ""description"":""A person"",
710 ""name"":{""type"":""string""},
711 ""hobbies"":{""type"":""string"",""required"":true},
712 ""age"":{""type"":""integer"",""required"":true}
716 string json = "{'name':'James'}";
718 Json.Schema.ValidationEventArgs validationEventArgs = null;
720 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
721 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
722 reader.Schema = JsonSchema.Parse(schemaJson);
724 Assert.IsTrue(reader.Read());
725 Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
727 Assert.IsTrue(reader.Read());
728 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
729 Assert.AreEqual("name", reader.Value.ToString());
731 Assert.IsTrue(reader.Read());
732 Assert.AreEqual(JsonToken.String, reader.TokenType);
733 Assert.AreEqual("James", reader.Value.ToString());
734 Assert.AreEqual(null, validationEventArgs);
736 Assert.IsTrue(reader.Read());
737 Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
738 Assert.AreEqual("Required properties are missing from object: hobbies, age. Line 1, position 16.", validationEventArgs.Message);
740 Assert.IsNotNull(validationEventArgs);
744 public void MissingNonRequiredProperties()
746 string schemaJson = @"{
747 ""description"":""A person"",
751 ""name"":{""type"":""string"",""required"":true},
752 ""hobbies"":{""type"":""string"",""required"":false},
753 ""age"":{""type"":""integer""}
757 string json = "{'name':'James'}";
759 Json.Schema.ValidationEventArgs validationEventArgs = null;
761 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
762 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
763 reader.Schema = JsonSchema.Parse(schemaJson);
765 Assert.IsTrue(reader.Read());
766 Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
768 Assert.IsTrue(reader.Read());
769 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
770 Assert.AreEqual("name", reader.Value.ToString());
772 Assert.IsTrue(reader.Read());
773 Assert.AreEqual(JsonToken.String, reader.TokenType);
774 Assert.AreEqual("James", reader.Value.ToString());
775 Assert.IsNull(validationEventArgs);
777 Assert.IsTrue(reader.Read());
778 Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
780 Assert.IsNull(validationEventArgs);
784 public void DisableAdditionalProperties()
786 string schemaJson = @"{
787 ""description"":""A person"",
791 ""name"":{""type"":""string""}
793 ""additionalProperties"":false
796 string json = "{'name':'James','additionalProperty1':null,'additionalProperty2':null}";
798 Json.Schema.ValidationEventArgs validationEventArgs = null;
800 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
801 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
802 reader.Schema = JsonSchema.Parse(schemaJson);
804 Assert.IsTrue(reader.Read());
805 Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
807 Assert.IsTrue(reader.Read());
808 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
809 Assert.AreEqual("name", reader.Value.ToString());
811 Assert.IsTrue(reader.Read());
812 Assert.AreEqual(JsonToken.String, reader.TokenType);
813 Assert.AreEqual("James", reader.Value.ToString());
814 Assert.AreEqual(null, validationEventArgs);
816 Assert.IsTrue(reader.Read());
817 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
818 Assert.AreEqual("additionalProperty1", reader.Value.ToString());
820 Assert.IsTrue(reader.Read());
821 Assert.AreEqual(JsonToken.Null, reader.TokenType);
822 Assert.AreEqual(null, reader.Value);
823 Assert.AreEqual("Property 'additionalProperty1' has not been defined and the schema does not allow additional properties. Line 1, position 38.", validationEventArgs.Message);
825 Assert.IsTrue(reader.Read());
826 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
827 Assert.AreEqual("additionalProperty2", reader.Value.ToString());
829 Assert.IsTrue(reader.Read());
830 Assert.AreEqual(JsonToken.Null, reader.TokenType);
831 Assert.AreEqual(null, reader.Value);
832 Assert.AreEqual("Property 'additionalProperty2' has not been defined and the schema does not allow additional properties. Line 1, position 65.", validationEventArgs.Message);
834 Assert.IsTrue(reader.Read());
835 Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
837 Assert.IsNotNull(validationEventArgs);
841 public void ExtendsStringGreaterThanMaximumLength()
843 string schemaJson = @"{
852 List<string> errors = new List<string>();
853 string json = "'The quick brown fox jumps over the lazy dog.'";
855 Json.Schema.ValidationEventArgs validationEventArgs = null;
857 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
858 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; errors.Add(validationEventArgs.Message); };
859 reader.Schema = JsonSchema.Parse(schemaJson);
861 Assert.IsTrue(reader.Read());
862 Assert.AreEqual(JsonToken.String, reader.TokenType);
863 Assert.AreEqual(1, errors.Count);
864 Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' exceeds maximum length of 9. Line 1, position 46.", errors[0]);
866 Assert.IsNotNull(validationEventArgs);
869 private JsonSchema GetExtendedSchema()
876 ""firstproperty"":{""type"":""string"",""required"":true}
878 ""additionalProperties"":{}
884 ""extends"":{""$ref"":""first""},
887 ""secondproperty"":{""type"":""string"",""required"":true}
889 ""additionalProperties"":false
892 JsonSchemaResolver resolver = new JsonSchemaResolver();
893 JsonSchema firstSchema = JsonSchema.Parse(first, resolver);
894 JsonSchema secondSchema = JsonSchema.Parse(second, resolver);
900 public void ExtendsDisallowAdditionProperties()
902 string json = "{'firstproperty':'blah','secondproperty':'blah2','additional':'blah3','additional2':'blah4'}";
904 Json.Schema.ValidationEventArgs validationEventArgs = null;
906 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
907 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
908 reader.Schema = GetExtendedSchema();
910 Assert.IsTrue(reader.Read());
911 Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
913 Assert.IsTrue(reader.Read());
914 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
915 Assert.AreEqual("firstproperty", reader.Value.ToString());
916 Assert.AreEqual(null, validationEventArgs);
918 Assert.IsTrue(reader.Read());
919 Assert.AreEqual(JsonToken.String, reader.TokenType);
920 Assert.AreEqual("blah", reader.Value.ToString());
921 Assert.AreEqual(null, validationEventArgs);
923 Assert.IsTrue(reader.Read());
924 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
925 Assert.AreEqual("secondproperty", reader.Value.ToString());
926 Assert.AreEqual(null, validationEventArgs);
928 Assert.IsTrue(reader.Read());
929 Assert.AreEqual(JsonToken.String, reader.TokenType);
930 Assert.AreEqual("blah2", reader.Value.ToString());
931 Assert.AreEqual(null, validationEventArgs);
933 Assert.IsTrue(reader.Read());
934 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
935 Assert.AreEqual("additional", reader.Value.ToString());
936 Assert.AreEqual("Property 'additional' has not been defined and the schema does not allow additional properties. Line 1, position 62.", validationEventArgs.Message);
938 Assert.IsTrue(reader.Read());
939 Assert.AreEqual(JsonToken.String, reader.TokenType);
940 Assert.AreEqual("blah3", reader.Value.ToString());
942 Assert.IsTrue(reader.Read());
943 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
944 Assert.AreEqual("additional2", reader.Value.ToString());
945 Assert.AreEqual("Property 'additional2' has not been defined and the schema does not allow additional properties. Line 1, position 84.", validationEventArgs.Message);
947 Assert.IsTrue(reader.Read());
948 Assert.AreEqual(JsonToken.String, reader.TokenType);
949 Assert.AreEqual("blah4", reader.Value.ToString());
951 Assert.IsTrue(reader.Read());
952 Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
954 Assert.IsFalse(reader.Read());
958 public void ExtendsMissingRequiredProperties()
962 List<string> errors = new List<string>();
964 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
965 reader.ValidationEventHandler += (sender, args) => { errors.Add(args.Message); };
966 reader.Schema = GetExtendedSchema();
968 Assert.IsTrue(reader.Read());
969 Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
971 Assert.IsTrue(reader.Read());
972 Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
974 Assert.AreEqual(1, errors.Count);
975 Assert.AreEqual("Required properties are missing from object: secondproperty, firstproperty. Line 1, position 2.", errors[0]);
979 public void NoAdditionalProperties()
981 string schemaJson = @"{
983 ""items"": [{""type"":""string""},{""type"":""integer""}],
984 ""additionalProperties"": false
987 string json = @"[1, 'a', null]";
989 Json.Schema.ValidationEventArgs validationEventArgs = null;
991 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
992 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
993 reader.Schema = JsonSchema.Parse(schemaJson);
995 Assert.IsTrue(reader.Read());
996 Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
998 Assert.IsTrue(reader.Read());
999 Assert.AreEqual(JsonToken.Integer, reader.TokenType);
1000 Assert.AreEqual("Invalid type. Expected String but got Integer. Line 1, position 3.", validationEventArgs.Message);
1002 Assert.IsTrue(reader.Read());
1003 Assert.AreEqual(JsonToken.String, reader.TokenType);
1004 Assert.AreEqual("Invalid type. Expected Integer but got String. Line 1, position 7.", validationEventArgs.Message);
1006 Assert.IsTrue(reader.Read());
1007 Assert.AreEqual(JsonToken.Null, reader.TokenType);
1008 Assert.AreEqual("Index 3 has not been defined and the schema does not allow additional items. Line 1, position 13.", validationEventArgs.Message);
1010 Assert.IsTrue(reader.Read());
1011 Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
1013 Assert.IsFalse(reader.Read());
1017 public void PatternPropertiesNoAdditionalProperties()
1019 string schemaJson = @"{
1020 ""type"":""object"",
1021 ""patternProperties"": {
1022 ""hi"": {""type"":""string""},
1023 ""ho"": {""type"":""string""}
1025 ""additionalProperties"": false
1029 ""hi"": ""A string!"",
1030 ""hide"": ""A string!"",
1032 ""hey"": ""A string!""
1035 Json.Schema.ValidationEventArgs validationEventArgs = null;
1037 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
1038 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
1039 reader.Schema = JsonSchema.Parse(schemaJson);
1041 Assert.IsTrue(reader.Read());
1042 Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
1044 Assert.IsTrue(reader.Read());
1045 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
1046 Assert.AreEqual(null, validationEventArgs);
1048 Assert.IsTrue(reader.Read());
1049 Assert.AreEqual(JsonToken.String, reader.TokenType);
1051 Assert.IsTrue(reader.Read());
1052 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
1053 Assert.AreEqual(null, validationEventArgs);
1055 Assert.IsTrue(reader.Read());
1056 Assert.AreEqual(JsonToken.String, reader.TokenType);
1058 Assert.IsTrue(reader.Read());
1059 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
1060 Assert.AreEqual(null, validationEventArgs);
1062 Assert.IsTrue(reader.Read());
1063 Assert.AreEqual(JsonToken.Integer, reader.TokenType);
1064 Assert.AreEqual("Invalid type. Expected String but got Integer. Line 4, position 10.", validationEventArgs.Message);
1066 Assert.IsTrue(reader.Read());
1067 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
1068 Assert.AreEqual("Property 'hey' has not been defined and the schema does not allow additional properties. Line 5, position 8.", validationEventArgs.Message);
1070 Assert.IsTrue(reader.Read());
1071 Assert.AreEqual(JsonToken.String, reader.TokenType);
1073 Assert.IsTrue(reader.Read());
1074 Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
1076 Assert.IsFalse(reader.Read());
1080 public void ExtendedComplex()
1084 ""type"":""object"",
1087 ""firstproperty"":{""type"":""string""},
1088 ""secondproperty"":{""type"":""string"",""maxLength"":10},
1090 ""type"":""object"",
1093 ""thirdproperty_firstproperty"":{""type"":""string"",""maxLength"":10,""minLength"":7}
1097 ""additionalProperties"":{}
1102 ""type"":""object"",
1103 ""extends"":{""$ref"":""first""},
1106 ""secondproperty"":{""type"":""any""},
1111 ""thirdproperty_firstproperty"":{""maxLength"":9,""minLength"":6,""pattern"":""hi2u""}
1113 ""additionalProperties"":{""maxLength"":9,""minLength"":6,""enum"":[""one"",""two""]}
1115 ""type"":""object"",
1118 ""thirdproperty_firstproperty"":{""pattern"":""hi""}
1120 ""additionalProperties"":{""type"":""string"",""enum"":[""two"",""three""]}
1122 ""fourthproperty"":{""type"":""string""}
1124 ""additionalProperties"":false
1127 JsonSchemaResolver resolver = new JsonSchemaResolver();
1128 JsonSchema firstSchema = JsonSchema.Parse(first, resolver);
1129 JsonSchema secondSchema = JsonSchema.Parse(second, resolver);
1131 JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder();
1134 'firstproperty':'blahblahblahblahblahblah',
1135 'secondproperty':'secasecasecasecaseca',
1137 'thirdproperty_firstproperty':'aaa',
1138 'additional':'three'
1142 Json.Schema.ValidationEventArgs validationEventArgs = null;
1143 List<string> errors = new List<string>();
1145 JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
1146 reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; errors.Add(validationEventArgs.Message); };
1147 reader.Schema = secondSchema;
1149 Assert.IsTrue(reader.Read());
1150 Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
1152 Assert.IsTrue(reader.Read());
1153 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
1154 Assert.AreEqual("firstproperty", reader.Value.ToString());
1155 Assert.AreEqual(null, validationEventArgs);
1157 Assert.IsTrue(reader.Read());
1158 Assert.AreEqual(JsonToken.String, reader.TokenType);
1159 Assert.AreEqual("blahblahblahblahblahblah", reader.Value.ToString());
1161 Assert.IsTrue(reader.Read());
1162 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
1163 Assert.AreEqual("secondproperty", reader.Value.ToString());
1165 Assert.IsTrue(reader.Read());
1166 Assert.AreEqual(JsonToken.String, reader.TokenType);
1167 Assert.AreEqual("secasecasecasecaseca", reader.Value.ToString());
1168 Assert.AreEqual(1, errors.Count);
1169 Assert.AreEqual("String 'secasecasecasecaseca' exceeds maximum length of 10. Line 3, position 41.", errors[0]);
1171 Assert.IsTrue(reader.Read());
1172 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
1173 Assert.AreEqual("thirdproperty", reader.Value.ToString());
1174 Assert.AreEqual(1, errors.Count);
1176 Assert.IsTrue(reader.Read());
1177 Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
1178 Assert.AreEqual(1, errors.Count);
1180 Assert.IsTrue(reader.Read());
1181 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
1182 Assert.AreEqual("thirdproperty_firstproperty", reader.Value.ToString());
1183 Assert.AreEqual(1, errors.Count);
1185 Assert.IsTrue(reader.Read());
1186 Assert.AreEqual(JsonToken.String, reader.TokenType);
1187 Assert.AreEqual("aaa", reader.Value.ToString());
1188 Assert.AreEqual(4, errors.Count);
1189 Assert.AreEqual("String 'aaa' is less than minimum length of 7. Line 5, position 39.", errors[1]);
1190 Assert.AreEqual("String 'aaa' does not match regex pattern 'hi'. Line 5, position 39.", errors[2]);
1191 Assert.AreEqual("String 'aaa' does not match regex pattern 'hi2u'. Line 5, position 39.", errors[3]);
1193 Assert.IsTrue(reader.Read());
1194 Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
1195 Assert.AreEqual("additional", reader.Value.ToString());
1196 Assert.AreEqual(4, errors.Count);
1198 Assert.IsTrue(reader.Read());
1199 Assert.AreEqual(JsonToken.String, reader.TokenType);
1200 Assert.AreEqual("three", reader.Value.ToString());
1201 Assert.AreEqual(5, errors.Count);
1202 Assert.AreEqual("String 'three' is less than minimum length of 6. Line 6, position 24.", errors[4]);
1204 Assert.IsTrue(reader.Read());
1205 Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
1207 Assert.IsTrue(reader.Read());
1208 Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
1210 Assert.IsFalse(reader.Read());