Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/RicoSuter/NJsonSchema
Browse files Browse the repository at this point in the history
  • Loading branch information
RicoSuter committed Jan 21, 2021
2 parents 6c2da5f + 16cf749 commit b851592
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using NJsonSchema.CodeGeneration.CSharp;
using NJsonSchema.Generation;
using Xunit;

namespace NJsonSchema.CodeGeneration.Tests.CSharp
{
public class NullableReferenceTypesTests
{
private class ClassWithRequiredObject
{
public object Property { get; set; }

[Required]
[Newtonsoft.Json.JsonProperty("property2", Required = Newtonsoft.Json.Required.Always)]
public object Property2 { get; set; }
}

[Fact]
public async Task When_property_is_optional_and_GenerateNullableReferenceTypes_is_not_set_then_CSharp_property_is_not_nullable()
{
//// Arrange
var schema = JsonSchema.FromType<ClassWithRequiredObject>(new JsonSchemaGeneratorSettings
{
SchemaType = SchemaType.OpenApi3
});
var schemaData = schema.ToJson();

//// Act
var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings
{
ClassStyle = CSharpClassStyle.Poco,
SchemaType = SchemaType.OpenApi3,
GenerateNullableReferenceTypes = false
});
var code = generator.GenerateFile("MyClass");

//// Assert
Assert.Contains("public object Property { get; set; }", code);
Assert.Contains("public object Property2 { get; set; }", code);
}

[Fact]
public async Task When_property_is_optional_and_GenerateNullableOptionalProperties_is_set_then_CSharp_property_is_nullable()
{
//// Arrange
var schema = JsonSchema.FromType<ClassWithRequiredObject>(new JsonSchemaGeneratorSettings
{
SchemaType = SchemaType.OpenApi3
});
var schemaData = schema.ToJson();

//// Act
var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings
{
ClassStyle = CSharpClassStyle.Poco,
SchemaType = SchemaType.OpenApi3,
GenerateNullableReferenceTypes = true
});
var code = generator.GenerateFile("MyClass");

//// Assert
Assert.Contains("public object? Property { get; set; }= default!;", code);
Assert.Contains("public object Property2 { get; set; }= default!;", code);
}

[Fact]
public async Task When_generating_from_json_schema_property_is_optional_and_GenerateNullableOptionalProperties_is_not_set_then_CSharp_property()
{
//// Arrange

// CSharpGenerator `new object()` adds = new object() initializer to property only if it's explicitly marked
// as having `type: object` in json schema
var schemaJson = @"
{
""type"": ""object"",
""required"": [
""property2""
],
""properties"": {
""Property"": {
""x-nullable"": true,
""type"": ""object""
},
""property2"": {
""type"": ""object""
}
}
}
";

var schema = await JsonSchema.FromJsonAsync(schemaJson);
var schemaData = schema.ToJson();

//// Act
var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings
{
ClassStyle = CSharpClassStyle.Poco,
SchemaType = SchemaType.OpenApi3,
GenerateNullableReferenceTypes = false
});
var code = generator.GenerateFile("MyClass");

//// Assert
Assert.Contains("public object Property { get; set; }", code);
Assert.Contains("public object Property2 { get; set; } = new object();", code);
}

[Fact]
public async Task When_generating_from_json_schema_property_is_optional_and_GenerateNullableOptionalProperties_is_set_then_CSharp_property()
{
//// Arrange

// CSharpGenerator `new object()` adds = new object() initializer to property only if it's explicitly marked
// as having `type: object` in json schema
var schemaJson = @"
{
""type"": ""object"",
""required"": [
""property2""
],
""properties"": {
""Property"": {
""x-nullable"": true,
""type"": ""object""
},
""property2"": {
""type"": ""object""
}
}
}
";

var schema = await JsonSchema.FromJsonAsync(schemaJson);
var schemaData = schema.ToJson();

//// Act
var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings
{
ClassStyle = CSharpClassStyle.Poco,
SchemaType = SchemaType.OpenApi3,
GenerateNullableReferenceTypes = true
});
var code = generator.GenerateFile("MyClass");

//// Assert
Assert.Contains("public object? Property { get; set; }= default!;", code);
Assert.Contains("public object Property2 { get; set; } = new object();", code);
}
}
}
7 changes: 5 additions & 2 deletions src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,15 @@ schema is JsonSchemaProperty property &&
isNullable = true;
}

var markAsNullableType = Settings.GenerateNullableReferenceTypes && isNullable;

if (schema.ActualTypeSchema.IsAnyType &&
schema.InheritedSchema == null && // not in inheritance hierarchy
schema.AllOf.Count == 0 &&
!Types.Keys.Contains(schema) &&
!schema.HasReference)
{
return Settings.AnyType;
return markAsNullableType ? Settings.AnyType + "?" : Settings.AnyType;
}

var type = schema.ActualTypeSchema.Type;
Expand All @@ -107,7 +109,8 @@ schema is JsonSchemaProperty property &&
return ResolveBoolean(isNullable);
}

var nullableReferenceType = Settings.GenerateNullableReferenceTypes && isNullable ? "?" : string.Empty;

var nullableReferenceType = markAsNullableType ? "?" : string.Empty;

if (schema.IsBinary)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard1.3;netstandard2.0;net451</TargetFrameworks>
<Description>JSON Schema reader, generator and validator for .NET</Description>
<Version>10.3.1</Version>
<Version>10.3.3</Version>
<PackageTags>json schema validation generator .net</PackageTags>
<Copyright>Copyright © Rico Suter, 2020</Copyright>
<PackageLicenseUrl>https://github.com/rsuter/NJsonSchema/blob/master/LICENSE.md</PackageLicenseUrl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard1.3;netstandard2.0;net451</TargetFrameworks>
<Description>JSON Schema reader, generator and validator for .NET</Description>
<Version>10.3.1</Version>
<Version>10.3.3</Version>
<PackageTags>json schema validation generator .net</PackageTags>
<Copyright>Copyright © Rico Suter, 2020</Copyright>
<PackageLicenseUrl>https://github.com/RicoSuter/NJsonSchema/blob/master/LICENSE.md</PackageLicenseUrl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
{% endif -%}
}

static fromJS(data: any{% if HandleReferences %}, _mappings?: any{% endif %}): {{ ClassName }} {
static fromJS(data: any{% if HandleReferences %}, _mappings?: any{% endif %}): {{ ClassName }}{% if HandleReferences %} | null{% endif %} {
data = typeof data === 'object' ? data : {};
{% if HandleReferences -%}
{% if HasBaseDiscriminator -%}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
return json;
}

function createInstance<T>(data: any, mappings: any, type: any): T {
function createInstance<T>(data: any, mappings: any, type: any): T | null {
if (!mappings)
mappings = [];
if (!data)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
}
}

static fromJS(data: any{% if HandleReferences %}, _mappings?: any{% endif %}): {{ ClassName }} {
static fromJS(data: any{% if HandleReferences %}, _mappings?: any{% endif %}): {{ ClassName }}{% if HandleReferences %} | null{% endif %} {
{% if HandleReferences -%}
{% if HasBaseDiscriminator -%}
{% for derivedClass in DerivedClasses -%}
Expand Down
3 changes: 3 additions & 0 deletions src/NJsonSchema.CodeGeneration/Models/PropertyModelBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ protected PropertyModelBase(
/// <summary>Gets the property extension data.</summary>
public IDictionary<string, object> ExtensionData => _property.ExtensionData;

/// <summary>Gets the JSON Schema format property.</summary>
public string Format => _property.ActualSchema.Format;

/// <summary>Gets the type name hint for the property.</summary>
protected string GetTypeNameHint()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard1.3;netstandard2.0;net451</TargetFrameworks>
<Description>JSON Schema reader, generator and validator for .NET</Description>
<Version>10.3.1</Version>
<Version>10.3.3</Version>
<PackageTags>json schema validation generator .net</PackageTags>
<Copyright>Copyright © Rico Suter, 2020</Copyright>
<PackageLicenseUrl>https://github.com/rsuter/NJsonSchema/blob/master/LICENSE.md</PackageLicenseUrl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public async Task PropertyWithIntegerMinimumDefiniton()


[Fact]
public async Task PropertyWithFloatMinimumDefiniton()
public async Task PropertyWithFloatMinimumDefinition()
{
//// Arrange
var data = @"{
Expand Down Expand Up @@ -172,8 +172,8 @@ public async Task PropertyWithFloatMinimumDefiniton()
""properties"": {
""value"": {
""type"": ""number"",
""maximum"": 5.0,
""minimum"": 1.0
""maximum"": 5.00001,
""minimum"": 1.000012
}
}
}
Expand All @@ -188,7 +188,7 @@ public async Task PropertyWithFloatMinimumDefiniton()
var validationResult = schema.Validate(testJson);
Assert.NotNull(validationResult);
Assert.Equal(0, validationResult.Count);
Assert.Equal(1.0, testJson.SelectToken("body.numberContent.value").Value<float>());
Assert.Equal(1.000012, testJson.SelectToken("body.numberContent.value").Value<double>());
}

[Fact]
Expand Down
2 changes: 1 addition & 1 deletion src/NJsonSchema.Yaml/NJsonSchema.Yaml.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard1.3;netstandard2.0;net45</TargetFrameworks>
<Description>JSON Schema reader, generator and validator for .NET</Description>
<Version>10.3.1</Version>
<Version>10.3.3</Version>
<PackageTags>json schema validation generator .net</PackageTags>
<Copyright>Copyright © Rico Suter, 2020</Copyright>
<PackageLicenseUrl>https://github.com/rsuter/NJsonSchema/blob/master/LICENSE.md</PackageLicenseUrl>
Expand Down
6 changes: 3 additions & 3 deletions src/NJsonSchema/Generation/SampleJsonDataGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,15 @@ private static JToken HandleNumberType(JsonSchema schema)
{
if (schema.ExclusiveMinimumRaw != null)
{
return JToken.FromObject(float.Parse(schema.Minimum.ToString()) + 0.1);
return JToken.FromObject((decimal)(float.Parse(schema.Minimum.ToString()) + 0.1));
}
else if (schema.ExclusiveMinimum != null)
{
return JToken.FromObject(float.Parse(schema.ExclusiveMinimum.ToString()));
return JToken.FromObject(decimal.Parse(schema.ExclusiveMinimum.ToString()));
}
else if (schema.Minimum.HasValue)
{
return float.Parse(schema.Minimum.ToString());
return decimal.Parse(schema.Minimum.ToString());
}
return JToken.FromObject(0.0);
}
Expand Down
4 changes: 2 additions & 2 deletions src/NJsonSchema/NJsonSchema.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard1.0;netstandard2.0;net40;net45</TargetFrameworks>
<Description>JSON Schema reader, generator and validator for .NET</Description>
<Version>10.3.1</Version>
<Version>10.3.3</Version>
<PackageTags>json schema validation generator .net</PackageTags>
<Copyright>Copyright © Rico Suter, 2020</Copyright>
<PackageLicenseUrl>https://github.com/RicoSuter/NJsonSchema/blob/master/LICENSE.md</PackageLicenseUrl>
Expand All @@ -28,7 +28,7 @@
<WarningsAsErrors />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Namotion.Reflection" Version="1.0.14" />
<PackageReference Include="Namotion.Reflection" Version="1.0.15" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net40'">
Expand Down

0 comments on commit b851592

Please sign in to comment.