public async Task When_deserializing_schema_then_it_should_be_read_correctly() { //// Arrange var data = @"{ ""title"": ""Example Schema"", ""type"": ""object"", ""properties"": { ""firstName"": { ""type"": ""string"" }, ""lastName"": { ""type"": ""string"" }, ""age"": { ""description"": ""Age in years"", ""type"": ""integer"", ""minimum"": 0 } }, ""required"": [""firstName"", ""lastName""] }"; //// Act var schema = await JsonSchema.FromJsonAsync(data); var x = schema.ToJson(); //// Assert Assert.Equal(3, schema.Properties.Count); Assert.Equal(JsonObjectType.Object, schema.Type); }
public async Task Subtypes_are_serialized_with_correct_discriminator() { //// Arrange var json = await JsonSchema.FromJsonAsync(@"{""title"":""foo"",""type"":""object"",""discriminator"":""discriminator"",""properties"":{""discriminator"":{""type"":""string""}},""definitions"":{""bar"":{""type"":""object"",""allOf"":[{""$ref"":""#""}]}}}"); var data = json.ToJson(); var generator = new CSharpGenerator(json, new CSharpGeneratorSettings() { ClassStyle = CSharpClassStyle.Poco, Namespace = "foo" }); //// Act var code = generator.GenerateFile(); var assembly = Compile(code); var type = assembly.GetType("foo.Foo"); if (type == null) { throw new Exception("Foo not found in " + String.Join(", ", assembly.GetTypes().Select(t => t.Name))); } var bar = JsonConvert.DeserializeObject(@"{""discriminator"":""bar""}", type); //// Assert Assert.Contains(@"""bar""", JsonConvert.SerializeObject(bar)); }
public async Task When_property_is_string_dictionary_then_assignment_is_correct() { //// Arrange var json = @"{ ""properties"": { ""resource"": { ""type"": ""object"", ""additionalProperties"": { ""$ref"": ""#/definitions/myItem"" } } }, ""definitions"": { ""myItem"": { ""type"": ""string"" } } }"; var schema = await JsonSchema.FromJsonAsync(json); //// Act var codeGenerator = new TypeScriptGenerator(schema, new TypeScriptGeneratorSettings { TypeStyle = TypeScriptTypeStyle.Class, NullValue = TypeScriptNullValue.Undefined, TypeScriptVersion = 1.8m }); var code = codeGenerator.GenerateFile("Test"); //// Assert Assert.Contains("this.resource[key] = _data[\"resource\"][key];", code); }
public async Task When_ref_is_nested_then_it_should_be_resolved() { /// Arrange var json = @" { ""$schema"": ""http://json-schema.org/draft-04/schema#"", ""$ref"": ""#/definitions/refOne"", ""definitions"": { ""refOne"": { ""type"": ""object"", ""properties"": { ""Two"": { ""$ref"": ""#/definitions/refTwo"" } } }, ""refTwo"": { ""type"": ""object"", ""properties"": { ""Id"": { ""type"": ""string"" } } } } }"; /// Act var schema = await JsonSchema.FromJsonAsync(json); /// Assert var jsonOutput = schema.ToJson(); Assert.NotNull(jsonOutput); }
public async Task When_enum_property_is_not_required_in_Swagger2_then_it_is_nullable() { //// Arrange var json = @"{ ""type"": ""object"", ""required"": [ ""name"", ""photoUrls"" ], ""properties"": { ""status"": { ""type"": ""string"", ""description"": ""pet status in the store"", ""enum"": [ ""available"", ""pending"", ""sold"" ] } } }"; var schema = await JsonSchema.FromJsonAsync(json); var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings { SchemaType = SchemaType.Swagger2 }); //// Act var code = generator.GenerateFile("MyClass"); //// Assert Assert.Contains("public MyClassStatus? Status { get; set; }", code); }
public async Task When_allOf_schema_is_object_type_then_it_is_an_inherited_class_in_generated_code() { //// Arrange var json = @"{ '$schema': 'http://json-schema.org/draft-04/schema#', 'type': 'object', 'properties': { 'prop1' : { 'type' : 'string' } }, 'allOf': [ { '$ref': '#/definitions/Bar' } ], 'definitions': { 'Bar': { 'type': 'object', 'properties': { 'prop2' : { 'type' : 'string' } } } } }"; //// Act var schema = await JsonSchema.FromJsonAsync(json); var generator = new TypeScriptGenerator(schema, new TypeScriptGeneratorSettings { TypeStyle = TypeScriptTypeStyle.Class }); var code = generator.GenerateFile("Foo"); //// Assert Assert.Contains("class Foo extends Bar", code); }
// [Fact] public async Task When_integer_is_big_integer_then_validation_works() { // See https://github.com/RicoSuter/NJsonSchema/issues/568 /// Arrange const string json = @"{ ""type"": ""object"", ""properties"": { ""property1"": { ""type"": ""number"" } }, ""required"": [""property1""], ""additionalProperties"": false, ""additionalItems"": false }"; var data = @"{ ""property1"": 34545734242323232423434 }"; var validationSchema = JsonSchema.FromJsonAsync(json).Result; /// Act var errors = validationSchema.Validate(data); /// Assert Assert.Equal(0, errors.Count); }
private async Task LoadSchemas() { var assembly = typeof(EventSchemaValidator).Assembly; var resources = assembly.GetManifestResourceNames().Where(r => r.Contains("DW.ELA.Plugin.EDDN.Schemas")); if (!resources.Any()) { throw new ApplicationException("Unable to load any schemas"); } var schemas = new Dictionary <string, JsonSchema>(); foreach (string resource in resources) { using (var stream = assembly.GetManifestResourceStream(resource)) using (var reader = new StreamReader(stream)) { string json = await reader.ReadToEndAsync(); var schema = await JsonSchema.FromJsonAsync(json); schemas.Add(schema.Id.TrimEnd('#'), schema); Log.Trace("Loaded schema {0}", schema.Id); } } schemaCache = schemas; }
public async Task When_property_is_nullable_and_enum_allows_null_then_no_exception_is_thrown() { //// Arrange var json = @"{ ""type"":""object"", ""properties"":{ ""paataenktHandling"":{ ""title"":""paataenktHandling"", ""description"":""EAID_D38C4D27_B57C_4356_89E1_05E8DA0250B6"", ""type"":[ ""string"", ""null"" ], ""enum"":[ ""Ændring"", ""Nyoprettelse"", ""Udgår"", null ] } } }"; var schema = await JsonSchema.FromJsonAsync(json); //// Act var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings()); var code = generator.GenerateFile("Foo"); //// Assert Assert.NotNull(code); }
public async Task When_enumeration_has_null_and_value_is_null_then_no_validation_errors() { //// Arrange var json = @" { ""properties"": { ""SalutationType"": { ""type"": [ ""string"", ""null"" ], ""enum"": [ ""Mr"", ""Mrs"", ""Dr"", ""Ms"", null ] } } }"; //// Act var schema = await JsonSchema.FromJsonAsync(json); //// Act var errors = schema.Validate(@"{ ""SalutationType"": null }"); //// Assert Assert.Equal(0, errors.Count); }
public async Task When_JSON_contains_DateTime_is_available_then_string_validator_validates_correctly() { //// Arrange var schemaJson = @"{ ""$schema"": ""http://json-schema.org/draft-04/schema#"", ""type"": ""object"", ""properties"": { ""SimpleDate"": { ""type"": ""string"", ""format"": ""date-time"" }, ""PatternDate"": { ""type"": ""string"", ""pattern"" : ""(^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}Z$|^$)"" } } }"; var schema = await JsonSchema.FromJsonAsync(schemaJson); var dataJson = @"{ ""SimpleDate"":""2012-05-18T00:00:00Z"", ""PatternDate"":""2012-11-07T00:00:00Z"" }"; //// Act var errors = schema.Validate(dataJson); //// Assert Assert.Equal(0, errors.Count); }
public async Task <byte[]> SerializeAsync(T data, SerializationContext context) { var json = JsonSerializer.Serialize(data, new JsonSerializerOptions // TODO: Make this configurable { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, }); var subjectName = $"{context.Topic}-{context.Component.ToString().ToLower()}"; var subjectVersions = await _schemaRegistryClient.ListSchemaVersionsAsync(subjectName, CancellationToken.None); if (subjectVersions != null && subjectVersions.Any()) { var version = subjectVersions.Last(); var schemaDetails = await _schemaRegistryClient.GetSchemaAsync(subjectName, version, CancellationToken.None); if (!schemaDetails.SchemaType.Equals("JSON", StringComparison.InvariantCultureIgnoreCase)) { throw new KafkaSerializationException($"Unable to verify schema for subject {subjectName}, version {version}, " + $"as the schema is {schemaDetails.SchemaType} but expected JSON"); } var schema = await JsonSchema.FromJsonAsync(schemaDetails.Schema); var validationErrors = schema.Validate(json); if (validationErrors.Any()) { var validationErrorStrings = validationErrors.Select(err => err.ToString()).ToArray(); throw new KafkaJsonSchemaSerializationException(validationErrorStrings); } } return(Encoding.UTF8.GetBytes(json)); }
private void AddDeclaredClasses(ActivityDefinition activity, StringBuilder output) { var schemaProperty = activity.Properties.FirstOrDefault(x => x.Name == "Schema"); if (schemaProperty == null || schemaProperty.Expressions.Count == 0) { return; } var json = schemaProperty.Expressions.FirstOrDefault().Value; if (json == null) { return; } if (string.IsNullOrWhiteSpace(json)) { return; } var jsonSchema = JsonSchema.FromJsonAsync(json).Result; var generator = new TypeScriptGenerator(jsonSchema, new TypeScriptGeneratorSettings { TypeStyle = TypeScriptTypeStyle.Class, TypeScriptVersion = 4 }); var file = generator.GenerateFile("Json") .Replace("\r\n", "\n") .Replace("export class", "declare class") .Replace("export interface", "declare interface"); output.Append(file); }
public async Task When_Swagger2_enum_property_is_not_required_then_it_is_nullable() { var json = @"{ ""properties"": { ""sex"": { ""$ref"": ""#/definitions/Sex"" } }, ""definitions"": { ""Sex"": { ""type"": ""string"", ""enum"": [ ""male"", ""female"" ] } } }"; var schema = await JsonSchema.FromJsonAsync(json); var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings { SchemaType = SchemaType.Swagger2, ClassStyle = CSharpClassStyle.Poco }); //// Act var code = generator.GenerateFile("MyClass"); //// Assert Assert.Contains(@"public Sex? Sex", code); }
public async Task When_datetime_with_regex_validation_then_datetime_is_not_altered() { //// Arrange var schemaJson = @" { ""$schema"": ""http://json-schema.org/draft-07/schema#"", ""type"": ""object"", ""required"": [ ""my_datetime"" ], ""properties"": { ""my_datetime"": { ""type"": ""string"", ""pattern"": ""^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$"" } } }"; var json = @" { ""my_datetime"": ""2018-12-19T16:58:07.270Z"" }"; //// Act var schema = await JsonSchema.FromJsonAsync(schemaJson); var errors = schema.Validate(json); //// Assert Assert.Equal(0, errors.Count); }
public async Task When_more_properties_are_defined_in_allOf_and_type_none_then_all_of_contains_all_properties() { //// Arrange var json = @"{ '$schema': 'http://json-schema.org/draft-04/schema#', 'type': 'object', 'x-typeName': 'Foo', 'properties': { 'prop1' : { 'type' : 'string' } }, 'allOf': [ { 'type': 'object', 'properties': { 'baseProperty' : { 'type' : 'string' } } }, { 'properties': { 'prop2' : { 'type' : 'string' } } } ] }"; //// Act var schema = await JsonSchema.FromJsonAsync(json); //// Assert Assert.NotNull(schema.InheritedSchema); Assert.Equal(2, schema.ActualProperties.Count); Assert.True(schema.ActualProperties.ContainsKey("prop1")); Assert.True(schema.ActualProperties.ContainsKey("prop2")); }
public async Task When_patternProperties_is_set_with_string_value_type_then_correct_dictionary_is_generated() { //// Arrange var schemaJson = @"{ ""required"": [ ""dict"" ], ""properties"": { ""dict"": { ""type"": ""object"", ""additionalProperties"": false, ""patternProperties"": { ""^[a-zA-Z_$][a-zA-Z_$0-9]*$"": { ""type"": ""string"" } } } } }"; var schema = await JsonSchema.FromJsonAsync(schemaJson); //// Act var generator = new TypeScriptGenerator(schema, new TypeScriptGeneratorSettings { TypeStyle = TypeScriptTypeStyle.Class }); var code = generator.GenerateFile("MyClass"); //// Assert Assert.Contains("dict: { [key: string]: string; };", code); // property not nullable Assert.Contains("this.dict = {};", code); // must be initialized with {} }
public async Task When_allOf_schema_is_object_type_then_it_is_an_inherited_schema() { //// Arrange var json = @"{ '$schema': 'http://json-schema.org/draft-04/schema#', 'type': 'object', 'x-typeName': 'Foo', 'properties': { 'prop1' : { 'type' : 'string' } }, 'allOf': [ { 'type': 'object', 'x-typeName': 'Bar', 'properties': { 'prop2' : { 'type' : 'string' } } } ] }"; //// Act var schema = await JsonSchema.FromJsonAsync(json); //// Assert Assert.NotNull(schema.InheritedSchema); Assert.Equal(1, schema.ActualProperties.Count); Assert.True(schema.ActualProperties.ContainsKey("prop1")); }
public async Task When_additionalProperties_schema_is_set_for_object_then_special_property_is_rendered() { //// Arrange var json = @"{ ""properties"": { ""Pet"": { ""type"": ""object"", ""properties"": { ""id"": { ""type"": ""integer"", ""format"": ""int64"" }, ""category"": { ""type"": ""string"" } }, ""additionalProperties"": { ""type"": ""string"" } } } }"; var schema = await JsonSchema.FromJsonAsync(json); //// Act var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings()); var code = generator.GenerateFile("Person"); //// Assert Assert.Contains("[Newtonsoft.Json.JsonExtensionData]", code); Assert.Contains("public System.Collections.Generic.IDictionary<string, object> AdditionalProperties", code); }
public async Task When_array_of_string_dictionary_is_used_with_ConvertConstructorInterfaceData_then_it_should_be_ignored() { //// Arrange var json = @" { ""type"": ""object"", ""properties"": { ""custom4"": { ""type"": ""array"", ""items"": { ""type"": ""object"", ""additionalProperties"": { ""type"": ""string"" } } } } }"; var schema = await JsonSchema.FromJsonAsync(json); //// Act var generator = new TypeScriptGenerator(schema, new TypeScriptGeneratorSettings { GenerateConstructorInterface = true, ConvertConstructorInterfaceData = true }); var output = generator.GenerateFile("MyClass"); //// Assert Assert.Contains("custom4: { [key: string] : string; }[];", output); }
public async Task When_double_is_bigger_then_decimal_then_validation_works() { /// Arrange const string json = @"{ 'schema': 'http://json-schema.org/draft-04/schema', 'title': 'NumberWithCircleVisualisationData', 'type': 'object', 'additionalProperties': true, 'required': [ 'UpperLimit', ], 'properties': { 'UpperLimit': { 'type': 'number', 'format': 'double', }, } }"; var data = @"{ 'UpperLimit': 1.1111111111111111E+101 }"; var validationSchema = JsonSchema.FromJsonAsync(json).Result; /// Act var errors = validationSchema.Validate(data); /// Assert Assert.Equal(0, errors.Count); }
public async Task When_generating_CSharp_code_then_default_value_generates_expected_expression() { // Arrange var document = await JsonSchema.FromJsonAsync(@"{ ""type"": ""object"", ""properties"": { ""someOptionalProperty"": { ""type"": ""number"", ""default"": ""123"" } } }"); //// Act var settings = new CSharpGeneratorSettings(); settings.GenerateDefaultValues = true; var generator = new CSharpGenerator(document, settings); var code = generator.GenerateFile(); // Assert Assert.DoesNotContain("SomeOptionalProperty { get; set; } = D;", code); Assert.Contains("double SomeOptionalProperty { get; set; } = 123D;", code); }
public async Task When_enum_has_no_type_then_enum_is_generated() { //// Arrange var json = @"{ ""type"": ""object"", ""properties"": { ""category"" : { ""enum"" : [ ""commercial"", ""residential"" ] } } }"; var schema = await JsonSchema.FromJsonAsync(json); var generator = new CSharpGenerator(schema); //// Act var code = generator.GenerateFile("MyClass"); //// Assert Assert.Contains("public enum MyClassCategory", code); }
public async Task When_string_property_has_maxlength_then_stringlength_attribute_is_rendered_in_Swagger_mode() { //// Arrange const string json = @"{ 'type': 'object', 'required': [ 'value' ], 'properties': { 'value': { '$ref': '#/definitions/string50' } }, 'definitions': { 'string50': { 'type': 'string', 'maxLength': 50 } } }"; var schema = await JsonSchema.FromJsonAsync(json); //// Act var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings { ClassStyle = CSharpClassStyle.Poco, SchemaType = SchemaType.Swagger2 }); var code = generator.GenerateFile("Message"); //// Assert Assert.Null(schema.Properties["value"].MaxLength); Assert.Equal(50, schema.Properties["value"].ActualSchema.MaxLength); Assert.Contains("[System.ComponentModel.DataAnnotations.StringLength(50)]\n" + " public string Value { get; set; }\n", code); }
[InlineData("b#r")] // Non-escaped ill-formed JSON Pointer public async Task When_definitions_have_sharp_in_type_name(string referenceTypeName) { //// Arrange var json = $@"{{ ""type"": ""object"", ""properties"": {{ ""foo"": {{ ""$ref"": ""#/definitions/{referenceTypeName}"" }} }}, ""definitions"": {{ ""b#r"": {{ ""type"": ""integer"" }} }} }}"; //// Act var schema = await JsonSchema.FromJsonAsync(json); var j = schema.ToJson(); //// Assert Assert.Equal(JsonObjectType.Integer, schema.Properties["foo"].ActualTypeSchema.Type); }
public async Task When_property_is_integer_and_no_format_is_available_then_default_value_is_int32() { /// Arrange var json = @"{ ""type"": ""object"", ""properties"": { ""pageSize"": { ""type"": ""integer"", ""default"": 10, ""minimum"": 1 }, ""pagingSize"": { ""type"": ""integer"", ""default"": 5, ""minimum"": 1 } } }"; var schema = await JsonSchema.FromJsonAsync(json); /// Act var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings { ClassStyle = CSharpClassStyle.Poco, SchemaType = SchemaType.Swagger2 }); var code = generator.GenerateFile("MyClass"); /// Assert Assert.Contains("public int? PageSize { get; set; } = 10;", code); }
public async Task When_property_is_object_and_not_dictionary_it_should_be_assigned_in_init_method() { //// Arrange var json = @"{ ""properties"": { ""resource"": { ""type"": ""object"" } } }"; var schema = await JsonSchema.FromJsonAsync(json); //// Act var codeGenerator = new TypeScriptGenerator(schema, new TypeScriptGeneratorSettings { TypeStyle = TypeScriptTypeStyle.Class, NullValue = TypeScriptNullValue.Null }); var code = codeGenerator.GenerateFile("Test"); //// Assert Assert.Contains("resource: any;", code); Assert.DoesNotContain("this.resource[key] = _data[\"resource\"][key];", code); Assert.DoesNotContain(" : new any();", code); }
public async Task When_property_is_string_and_format_is_date_time_then_assign_default_value() { /// Arrange var json = @"{ ""type"": ""object"", ""properties"": { ""dateTime"": { ""type"": ""string"", ""format"": ""date-time"", ""default"": ""31.12.9999 23:59:59"" } } }"; var schema = await JsonSchema.FromJsonAsync(json); /// Act var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings { ClassStyle = CSharpClassStyle.Poco, SchemaType = SchemaType.Swagger2, DateTimeType = "System.DateTime" }); var code = generator.GenerateFile("MyClass"); /// Assert Assert.Contains("public System.DateTime? DateTime { get; set; } = System.DateTime.Parse(\"31.12.9999 23:59:59\");", code); }
public async Task When_definitions_is_nested_then_refs_work() { //// Arrange var json = @"{ ""type"": ""object"", ""properties"": { ""foo"": { ""$ref"": ""#/definitions/collection/bar"" } }, ""definitions"": { ""collection"": { ""bar"": { ""type"": ""integer"" } } } }"; //// Act var schema = await JsonSchema.FromJsonAsync(json); var j = schema.ToJson(); //// Assert Assert.Equal(JsonObjectType.Integer, schema.Properties["foo"].ActualTypeSchema.Type); }
public async Task When_schema_is_loaded_then_all_refs_are_resolved() { //// Arrange var json = @"{ ""$schema"": ""http://json-schema.org/draft-04/schema#"", ""type"": ""object"", ""allOf"": [ { ""$ref"": ""http://json-schema.org/draft-04/schema#"" }, { ""type"": ""object"", ""properties"": { ""simpleRef"": { ""type"": ""string"" } } } ], ""properties"": { ""simpleRef2"": { ""type"": ""string"" } } }"; //// Act var schema = await JsonSchema.FromJsonAsync(json); var data = schema.ToJson(); //// Assert Assert.NotNull(schema.AllOf.First().Reference); }