Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add missing properties to json schema #124

Merged
merged 4 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions src/LEGO.AsyncAPI.Readers/V2/AsyncApiSchemaDeserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public class JsonSchemaDeserializer
{
if (n is ValueNode && n.GetBooleanValueOrDefault(null) == false)
{
a.AdditionalProperties = new NoAdditionalProperties();
a.AdditionalProperties = new FalseApiSchema();
}
else
{
Expand All @@ -139,7 +139,36 @@ public class JsonSchemaDeserializer
}
},
{
"items", (a, n) => { a.Items = LoadSchema(n); }
"items", (a, n) =>
{
if (n is ValueNode && n.GetBooleanValueOrDefault(null) == false)
{
a.Items = new FalseApiSchema();
}
else
{
a.Items = LoadSchema(n);
}
}
},
{
"additionalItems", (a, n) =>
{
if (n is ValueNode && n.GetBooleanValueOrDefault(null) == false)
{
a.AdditionalItems = new FalseApiSchema();
}
else
{
a.AdditionalItems = LoadSchema(n);
}
}
},
{
"patternProperties", (a, n) => { a.PatternProperties = n.CreateMap(LoadSchema); }
},
{
"propertyNames", (a, n) => { a.PropertyNames = LoadSchema(n); }
},
{
"contains", (a, n) => { a.Contains = LoadSchema(n); }
Expand Down
3 changes: 3 additions & 0 deletions src/LEGO.AsyncAPI/Models/AsyncApiConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,8 @@ public static class AsyncApiConstants
public const string MaxMessageBytes = "max.message.bytes";
public const string TopicConfiguration = "topicConfiguration";
public const string GeoReplication = "geo-replication";
public const string AdditionalItems = "additionalItems";
public const string PropertyNames = "propertyNames";
public const string PatternProperties = "patternProperties";
}
}
34 changes: 32 additions & 2 deletions src/LEGO.AsyncAPI/Models/AsyncApiSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,13 @@ public class AsyncApiSchema : IAsyncApiReferenceable, IAsyncApiExtensible, IAsyn
/// </summary>
public AsyncApiSchema Items { get; set; }

/// <summary>
/// follow JSON Schema definition: https://json-schema.org/draft-07/json-schema-release-notes.html
/// Value MUST be an object and not an array. Inline or referenced schema MUST be of a Schema Object
/// and not a standard JSON Schema. items MUST be present if the type is array.
/// </summary>
public AsyncApiSchema AdditionalItems { get; set; }

/// <summary>
/// follow JSON Schema definition: https://json-schema.org/draft-07/json-schema-release-notes.html.
/// </summary>
Expand Down Expand Up @@ -197,6 +204,8 @@ public class AsyncApiSchema : IAsyncApiReferenceable, IAsyncApiExtensible, IAsyn
/// </summary>
public AsyncApiSchema AdditionalProperties { get; set; }

public IDictionary<string, AsyncApiSchema> PatternProperties { get; set; } = new Dictionary<string, AsyncApiSchema>();

/// <summary>
/// follow JSON Schema definition: https://json-schema.org/draft-07/json-schema-release-notes.html.
/// </summary>
Expand Down Expand Up @@ -335,7 +344,24 @@ public void SerializeV2WithoutReference(IAsyncApiWriter writer)
writer.WriteOptionalCollection(AsyncApiConstants.Required, this.Required, (w, s) => w.WriteValue(s));

// items
writer.WriteOptionalObject(AsyncApiConstants.Items, this.Items, (w, s) => s.SerializeV2(w));
if (this.Items is FalseApiSchema)
{
writer.WriteOptionalProperty<bool>(AsyncApiConstants.Items, false);
}
else
{
writer.WriteOptionalObject(AsyncApiConstants.Items, this.Items, (w, s) => s.SerializeV2(w));
}

// additionalItems
if (this.AdditionalItems is FalseApiSchema)
{
writer.WriteOptionalProperty<bool>(AsyncApiConstants.AdditionalItems, false);
}
else
{
writer.WriteOptionalObject(AsyncApiConstants.AdditionalItems, this.AdditionalItems, (w, s) => s.SerializeV2(w));
}

// maxItems
writer.WriteOptionalProperty(AsyncApiConstants.MaxItems, this.MaxItems);
Expand All @@ -356,7 +382,7 @@ public void SerializeV2WithoutReference(IAsyncApiWriter writer)
writer.WriteOptionalProperty(AsyncApiConstants.MinProperties, this.MinProperties);

// additionalProperties
if (this.AdditionalProperties is NoAdditionalProperties)
if (this.AdditionalProperties is FalseApiSchema)
{
writer.WriteOptionalProperty<bool>(AsyncApiConstants.AdditionalProperties, false);
}
Expand All @@ -365,6 +391,10 @@ public void SerializeV2WithoutReference(IAsyncApiWriter writer)
writer.WriteOptionalObject(AsyncApiConstants.AdditionalProperties, this.AdditionalProperties, (w, s) => s.SerializeV2(w));
}

writer.WriteOptionalMap(AsyncApiConstants.PatternProperties, this.PatternProperties, (w, s) => s.SerializeV2(w));

writer.WriteOptionalObject(AsyncApiConstants.PropertyNames, this.PropertyNames, (w, s) => s.SerializeV2(w));

// discriminator
writer.WriteOptionalProperty(AsyncApiConstants.Discriminator, this.Discriminator);

Expand Down
10 changes: 10 additions & 0 deletions src/LEGO.AsyncAPI/Models/JsonSchema/FalseApiSchema.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace LEGO.AsyncAPI.Models

Check warning on line 1 in src/LEGO.AsyncAPI/Models/JsonSchema/FalseApiSchema.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

The file header is missing or not located at the top of the file.
{
/// <summary>
/// An object representing 'false' for properties of AsyncApiSchema that can be false OR a schema.
/// </summary>
/// <seealso cref="AsyncApiSchema" />
public class FalseApiSchema : AsyncApiSchema
{
}
}
12 changes: 0 additions & 12 deletions src/LEGO.AsyncAPI/Models/JsonSchema/NoAdditionalProperties.cs

This file was deleted.

118 changes: 113 additions & 5 deletions test/LEGO.AsyncAPI.Tests/Models/AsyncApiSchema_Should.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ public class AsyncApiSchema_Should
MaxLength = 15,
},
},
AdditionalProperties = new NoAdditionalProperties(),
AdditionalProperties = new FalseApiSchema(),
Items = new FalseApiSchema(),
AdditionalItems = new FalseApiSchema(),
},
["property4"] = new AsyncApiSchema
{
Expand All @@ -93,6 +95,26 @@ public class AsyncApiSchema_Should
MinLength = 2,
},
},
PatternProperties = new Dictionary<string, AsyncApiSchema>()
{
{
"^S_",
new AsyncApiSchema()
{
Type = SchemaType.String,
}
},
{
"^I_", new AsyncApiSchema()
{
Type = SchemaType.Integer,
}
},
},
PropertyNames = new AsyncApiSchema()
{
Pattern = "^[A-Za-z_][A-Za-z0-9_]*$",
},
AdditionalProperties = new AsyncApiSchema
{
Properties = new Dictionary<string, AsyncApiSchema>
Expand All @@ -103,8 +125,28 @@ public class AsyncApiSchema_Should
},
},
},
Items = new AsyncApiSchema
{
Properties = new Dictionary<string, AsyncApiSchema>
{
["Property9"] = new AsyncApiSchema
{
Type = SchemaType.String | SchemaType.Null,
},
},
},
AdditionalItems = new AsyncApiSchema
{
Properties = new Dictionary<string, AsyncApiSchema>
{
["Property10"] = new AsyncApiSchema
{
Type = SchemaType.String | SchemaType.Null,
},
},
},
},
["property9"] = new AsyncApiSchema
["property11"] = new AsyncApiSchema
{
Const = new AsyncApiString("aSpecialConstant"),
},
Expand Down Expand Up @@ -387,6 +429,8 @@ public void SerializeAsJson_WithAdvancedSchemaObject_V2Works()
""title"": ""title1"",
""properties"": {
""property1"": {
""items"": false,
""additionalItems"": false,
""properties"": {
""property2"": {
""type"": ""integer""
Expand All @@ -399,6 +443,26 @@ public void SerializeAsJson_WithAdvancedSchemaObject_V2Works()
""additionalProperties"": false
},
""property4"": {
""items"": {
""properties"": {
""Property9"": {
""type"": [
""null"",
""string""
]
}
}
},
""additionalItems"": {
""properties"": {
""Property10"": {
""type"": [
""null"",
""string""
]
}
}
},
""properties"": {
""property5"": {
""properties"": {
Expand All @@ -421,9 +485,20 @@ public void SerializeAsJson_WithAdvancedSchemaObject_V2Works()
]
}
}
},
""patternProperties"": {
""^S_"": {
""type"": ""string""
},
""^I_"": {
""type"": ""integer""
}
},
""propertyNames"": {
""pattern"": ""^[A-Za-z_][A-Za-z0-9_]*$""
}
},
""property9"": {
""property11"": {
""const"": ""aSpecialConstant""
}
},
Expand All @@ -443,13 +518,15 @@ public void SerializeAsJson_WithAdvancedSchemaObject_V2Works()
}

[Test]
public void Deserialize_WithAdditionalProperties_Works()
public void Deserialize_WithAdvancedSchema_Works()
{
// Arrange
var json = @"{
""title"": ""title1"",
""properties"": {
""property1"": {
""items"": false,
""additionalItems"": false,
""properties"": {
""property2"": {
""type"": ""integer""
Expand All @@ -462,6 +539,26 @@ public void Deserialize_WithAdditionalProperties_Works()
""additionalProperties"": false
},
""property4"": {
""items"": {
""properties"": {
""Property9"": {
""type"": [
""null"",
""string""
]
}
}
},
""additionalItems"": {
""properties"": {
""Property10"": {
""type"": [
""null"",
""string""
]
}
}
},
""properties"": {
""property5"": {
""properties"": {
Expand All @@ -484,9 +581,20 @@ public void Deserialize_WithAdditionalProperties_Works()
]
}
}
},
""patternProperties"": {
""^S_"": {
""type"": ""string""
},
""^I_"": {
""type"": ""integer""
}
},
""propertyNames"": {
""pattern"": ""^[A-Za-z_][A-Za-z0-9_]*$""
}
},
""property9"": {
""property11"": {
""const"": ""aSpecialConstant""
}
},
Expand Down
Loading