2
// Copyright (c) 2007 James Newton-King
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
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
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.
27
using System.Collections;
28
using System.Collections.Generic;
29
using System.Globalization;
30
using Newtonsoft.Json.Converters;
31
using Newtonsoft.Json.Serialization;
32
using Newtonsoft.Json.Tests.TestObjects;
33
using Newtonsoft.Json.Utilities;
35
using NUnit.Framework;
37
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
38
using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
39
using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
41
using Newtonsoft.Json.Schema;
43
using Newtonsoft.Json.Linq;
45
using Extensions=Newtonsoft.Json.Schema.Extensions;
47
using Newtonsoft.Json.Utilities.LinqBridge;
52
namespace Newtonsoft.Json.Tests.Schema
55
public class JsonSchemaGeneratorTests : TestFixtureBase
58
public void Generate_GenericDictionary()
60
JsonSchemaGenerator generator = new JsonSchemaGenerator();
61
JsonSchema schema = generator.Generate(typeof (Dictionary<string, List<string>>));
63
string json = schema.ToString();
67
""additionalProperties"": {
81
Dictionary<string, List<string>> value = new Dictionary<string, List<string>>
83
{"HasValue", new List<string>() { "first", "second", null }},
87
string valueJson = JsonConvert.SerializeObject(value, Formatting.Indented);
88
JObject o = JObject.Parse(valueJson);
90
Assert.IsTrue(o.IsValid(schema));
93
#if !(NETFX_CORE || PORTABLE)
95
public void Generate_DefaultValueAttributeTestClass()
97
JsonSchemaGenerator generator = new JsonSchemaGenerator();
98
JsonSchema schema = generator.Generate(typeof(DefaultValueAttributeTestClass));
100
string json = schema.ToString();
103
""description"": ""DefaultValueAttributeTestClass description!"",
104
""type"": ""object"",
105
""additionalProperties"": false,
109
""type"": ""integer"",
118
""default"": ""TestProperty1Value""
126
public void Generate_Person()
128
JsonSchemaGenerator generator = new JsonSchemaGenerator();
129
JsonSchema schema = generator.Generate(typeof(Person));
131
string json = schema.ToString();
135
""title"": ""Title!"",
136
""description"": ""JsonObjectAttribute description!"",
137
""type"": ""object"",
159
public void Generate_UserNullable()
161
JsonSchemaGenerator generator = new JsonSchemaGenerator();
162
JsonSchema schema = generator.Generate(typeof(UserNullable));
164
string json = schema.ToString();
167
""type"": ""object"",
189
""type"": ""integer""
191
""NullableRoleId"": {
217
public void Generate_RequiredMembersClass()
219
JsonSchemaGenerator generator = new JsonSchemaGenerator();
220
JsonSchema schema = generator.Generate(typeof(RequiredMembersClass));
222
Assert.AreEqual(JsonSchemaType.String, schema.Properties["FirstName"].Type);
223
Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["MiddleName"].Type);
224
Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["LastName"].Type);
225
Assert.AreEqual(JsonSchemaType.String, schema.Properties["BirthDate"].Type);
229
public void Generate_Store()
231
JsonSchemaGenerator generator = new JsonSchemaGenerator();
232
JsonSchema schema = generator.Generate(typeof(Store));
234
Assert.AreEqual(11, schema.Properties.Count);
236
JsonSchema productArraySchema = schema.Properties["product"];
237
JsonSchema productSchema = productArraySchema.Items[0];
239
Assert.AreEqual(4, productSchema.Properties.Count);
243
public void MissingSchemaIdHandlingTest()
245
JsonSchemaGenerator generator = new JsonSchemaGenerator();
247
JsonSchema schema = generator.Generate(typeof(Store));
248
Assert.AreEqual(null, schema.Id);
250
generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
251
schema = generator.Generate(typeof (Store));
252
Assert.AreEqual(typeof(Store).FullName, schema.Id);
254
generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseAssemblyQualifiedName;
255
schema = generator.Generate(typeof(Store));
256
Assert.AreEqual(typeof(Store).AssemblyQualifiedName, schema.Id);
260
public void CircularReferenceError()
262
ExceptionAssert.Throws<Exception>(@"Unresolved circular reference for type 'Newtonsoft.Json.Tests.TestObjects.CircularReferenceClass'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.",
265
JsonSchemaGenerator generator = new JsonSchemaGenerator();
266
generator.Generate(typeof(CircularReferenceClass));
271
public void CircularReferenceWithTypeNameId()
273
JsonSchemaGenerator generator = new JsonSchemaGenerator();
274
generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
276
JsonSchema schema = generator.Generate(typeof(CircularReferenceClass), true);
278
Assert.AreEqual(JsonSchemaType.String, schema.Properties["Name"].Type);
279
Assert.AreEqual(typeof(CircularReferenceClass).FullName, schema.Id);
280
Assert.AreEqual(JsonSchemaType.Object | JsonSchemaType.Null, schema.Properties["Child"].Type);
281
Assert.AreEqual(schema, schema.Properties["Child"]);
285
public void CircularReferenceWithExplicitId()
287
JsonSchemaGenerator generator = new JsonSchemaGenerator();
289
JsonSchema schema = generator.Generate(typeof(CircularReferenceWithIdClass));
291
Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["Name"].Type);
292
Assert.AreEqual("MyExplicitId", schema.Id);
293
Assert.AreEqual(JsonSchemaType.Object | JsonSchemaType.Null, schema.Properties["Child"].Type);
294
Assert.AreEqual(schema, schema.Properties["Child"]);
298
public void GenerateSchemaForType()
300
JsonSchemaGenerator generator = new JsonSchemaGenerator();
301
generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
303
JsonSchema schema = generator.Generate(typeof(Type));
305
Assert.AreEqual(JsonSchemaType.String, schema.Type);
307
string json = JsonConvert.SerializeObject(typeof(Version), Formatting.Indented);
309
JValue v = new JValue(json);
310
Assert.IsTrue(v.IsValid(schema));
313
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
315
public void GenerateSchemaForISerializable()
317
JsonSchemaGenerator generator = new JsonSchemaGenerator();
318
generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
320
JsonSchema schema = generator.Generate(typeof(Exception));
322
Assert.AreEqual(JsonSchemaType.Object, schema.Type);
323
Assert.AreEqual(true, schema.AllowAdditionalProperties);
324
Assert.AreEqual(null, schema.Properties);
328
#if !(NETFX_CORE || PORTABLE)
330
public void GenerateSchemaForDBNull()
332
JsonSchemaGenerator generator = new JsonSchemaGenerator();
333
generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
335
JsonSchema schema = generator.Generate(typeof(DBNull));
337
Assert.AreEqual(JsonSchemaType.Null, schema.Type);
340
public class CustomDirectoryInfoMapper : DefaultContractResolver
342
public CustomDirectoryInfoMapper()
347
protected override JsonContract CreateContract(Type objectType)
349
if (objectType == typeof(DirectoryInfo))
350
return base.CreateObjectContract(objectType);
352
return base.CreateContract(objectType);
355
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
357
IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
359
JsonPropertyCollection c = new JsonPropertyCollection(type);
360
CollectionUtils.AddRange(c, (IEnumerable)properties.Where(m => m.PropertyName != "Root"));
367
public void GenerateSchemaForDirectoryInfo()
369
JsonSchemaGenerator generator = new JsonSchemaGenerator();
370
generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
371
generator.ContractResolver = new CustomDirectoryInfoMapper
373
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
374
IgnoreSerializableAttribute = true
378
JsonSchema schema = generator.Generate(typeof(DirectoryInfo), true);
380
string json = schema.ToString();
383
""id"": ""System.IO.DirectoryInfo"",
389
""additionalProperties"": false,
399
""$ref"": ""System.IO.DirectoryInfo""
403
""type"": ""boolean""
423
""CreationTimeUtc"": {
427
""LastAccessTime"": {
431
""LastAccessTimeUtc"": {
439
""LastWriteTimeUtc"": {
445
""type"": ""integer""
450
DirectoryInfo temp = new DirectoryInfo(@"c:\temp");
452
JTokenWriter jsonWriter = new JTokenWriter();
453
JsonSerializer serializer = new JsonSerializer();
454
serializer.Converters.Add(new IsoDateTimeConverter());
455
serializer.ContractResolver = new CustomDirectoryInfoMapper
457
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
458
IgnoreSerializableInterface = true
461
serializer.Serialize(jsonWriter, temp);
463
List<string> errors = new List<string>();
464
jsonWriter.Token.Validate(schema, (sender, args) => errors.Add(args.Message));
466
Assert.AreEqual(0, errors.Count);
471
public void GenerateSchemaCamelCase()
473
JsonSchemaGenerator generator = new JsonSchemaGenerator();
474
generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
475
generator.ContractResolver = new CamelCasePropertyNamesContractResolver()
477
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
478
IgnoreSerializableAttribute = true
482
JsonSchema schema = generator.Generate(typeof(Version), true);
484
string json = schema.ToString();
487
""id"": ""System.Version"",
492
""additionalProperties"": false,
496
""type"": ""integer""
500
""type"": ""integer""
504
""type"": ""integer""
508
""type"": ""integer""
512
""type"": ""integer""
516
""type"": ""integer""
522
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
524
public void GenerateSchemaSerializable()
526
JsonSchemaGenerator generator = new JsonSchemaGenerator();
527
generator.ContractResolver = new DefaultContractResolver
529
IgnoreSerializableAttribute = false
531
generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
533
JsonSchema schema = generator.Generate(typeof (Version), true);
535
string json = schema.ToString();
538
""id"": ""System.Version"",
543
""additionalProperties"": false,
547
""type"": ""integer""
551
""type"": ""integer""
555
""type"": ""integer""
559
""type"": ""integer""
564
JTokenWriter jsonWriter = new JTokenWriter();
565
JsonSerializer serializer = new JsonSerializer();
566
serializer.ContractResolver = new DefaultContractResolver
568
IgnoreSerializableAttribute = false
570
serializer.Serialize(jsonWriter, new Version(1, 2, 3, 4));
572
List<string> errors = new List<string>();
573
jsonWriter.Token.Validate(schema, (sender, args) => errors.Add(args.Message));
575
Assert.AreEqual(0, errors.Count);
582
}", jsonWriter.Token.ToString());
584
Version version = jsonWriter.Token.ToObject<Version>(serializer);
585
Assert.AreEqual(1, version.Major);
586
Assert.AreEqual(2, version.Minor);
587
Assert.AreEqual(3, version.Build);
588
Assert.AreEqual(4, version.Revision);
592
public enum SortTypeFlag
601
public SortTypeFlag x;
605
public void GenerateSchemaWithNegativeEnum()
607
JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator();
608
JsonSchema schema = jsonSchemaGenerator.Generate(typeof(X));
610
string json = schema.ToString();
613
""type"": ""object"",
617
""type"": ""integer"",
643
public void CircularCollectionReferences()
645
Type type = typeof (Workspace);
646
JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator();
648
jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
649
JsonSchema jsonSchema = jsonSchemaGenerator.Generate(type);
652
Assert.IsNotNull(jsonSchema);
656
public void CircularReferenceWithMixedRequires()
658
JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator();
660
jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
661
JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(CircularReferenceClass));
662
string json = jsonSchema.ToString();
665
""id"": ""Newtonsoft.Json.Tests.TestObjects.CircularReferenceClass"",
676
""$ref"": ""Newtonsoft.Json.Tests.TestObjects.CircularReferenceClass""
683
public void JsonPropertyWithHandlingValues()
685
JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator();
687
jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
688
JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(JsonPropertyWithHandlingValues));
689
string json = jsonSchema.ToString();
692
""id"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues"",
699
""DefaultValueHandlingIgnoreProperty"": {
704
""default"": ""Default!""
706
""DefaultValueHandlingIncludeProperty"": {
712
""default"": ""Default!""
714
""DefaultValueHandlingPopulateProperty"": {
720
""default"": ""Default!""
722
""DefaultValueHandlingIgnoreAndPopulateProperty"": {
727
""default"": ""Default!""
729
""NullValueHandlingIgnoreProperty"": {
735
""NullValueHandlingIncludeProperty"": {
742
""ReferenceLoopHandlingErrorProperty"": {
743
""$ref"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues""
745
""ReferenceLoopHandlingIgnoreProperty"": {
746
""$ref"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues""
748
""ReferenceLoopHandlingSerializeProperty"": {
749
""$ref"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues""
756
public void GenerateForNullableInt32()
758
JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator();
760
JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(NullableInt32TestClass));
761
string json = jsonSchema.ToString();
764
""type"": ""object"",
778
public class NullableInt32TestClass
780
public int? Value { get; set; }
783
public class DMDSLBase
785
public String Comment;
788
public class Workspace : DMDSLBase
790
public ControlFlowItemCollection Jobs = new ControlFlowItemCollection();
793
public class ControlFlowItemBase : DMDSLBase
798
public class ControlFlowItem : ControlFlowItemBase//A Job
800
public TaskCollection Tasks = new TaskCollection();
801
public ContainerCollection Containers = new ContainerCollection();
804
public class ControlFlowItemCollection : List<ControlFlowItem>
808
public class Task : ControlFlowItemBase
810
public DataFlowTaskCollection DataFlowTasks = new DataFlowTaskCollection();
811
public BulkInsertTaskCollection BulkInsertTask = new BulkInsertTaskCollection();
814
public class TaskCollection : List<Task>
818
public class Container : ControlFlowItemBase
820
public ControlFlowItemCollection ContainerJobs = new ControlFlowItemCollection();
823
public class ContainerCollection : List<Container>
827
public class DataFlowTask_DSL : ControlFlowItemBase
831
public class DataFlowTaskCollection : List<DataFlowTask_DSL>
835
public class SequenceContainer_DSL : Container
839
public class BulkInsertTaskCollection : List<BulkInsertTask_DSL>
843
public class BulkInsertTask_DSL
b'\\ No newline at end of file'