Skip to content

Commit de33d93

Browse files
Merge pull request #1563 from microsoft/mk/add-pattern-properties
Adds PatternProperties to the OpenAPI Schema
2 parents 180eb5c + d426c06 commit de33d93

14 files changed

+97
-551
lines changed

src/Microsoft.OpenApi.Readers/V31/JsonSchemaDeserializer.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ internal static partial class OpenApiV31Deserializer
167167
o.Properties(n.CreateMap(LoadSchema));
168168
}
169169
},
170+
{
171+
"patternProperties", (o, n) =>
172+
{
173+
o.PatternProperties(n.CreateMap(LoadSchema));
174+
}
175+
},
170176
{
171177
"additionalProperties", (o, n) =>
172178
{

src/Microsoft.OpenApi/Models/OpenApiConstants.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,11 @@ public static class OpenApiConstants
400400
/// </summary>
401401
public const string Properties = "properties";
402402

403+
/// <summary>
404+
/// Field: Pattern Properties
405+
/// </summary>
406+
public const string PatternProperties = "patternProperties";
407+
403408
/// <summary>
404409
/// Field: AdditionalProperties
405410
/// </summary>

src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

44
using System;
55
using System.Collections.Generic;
66
using System.IO;
7+
using System.Linq;
78
using System.Text.Json;
9+
using System.Text.RegularExpressions;
810
using Json.Schema;
911
using Json.Schema.OpenApi;
1012
using Microsoft.OpenApi.Any;
@@ -536,6 +538,16 @@ public void WriteJsonSchemaWithoutReference(IOpenApiWriter writer, JsonSchema sc
536538
writer.WriteOptionalMap(OpenApiConstants.Properties, (IDictionary<string, JsonSchema>)schema.GetProperties(),
537539
(w, key, s) => w.WriteJsonSchema(s, version));
538540

541+
// pattern properties
542+
var patternProperties = schema?.GetPatternProperties();
543+
var stringPatternProperties = patternProperties?.ToDictionary(
544+
kvp => kvp.Key.ToString(), // Convert Regex key to string
545+
kvp => kvp.Value
546+
);
547+
548+
writer.WriteOptionalMap(OpenApiConstants.PatternProperties, stringPatternProperties,
549+
(w, key, s) => w.WriteJsonSchema(s, version));
550+
539551
// additionalProperties
540552
if (schema.GetAdditionalPropertiesAllowed() ?? false)
541553
{

test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<ItemGroup>
3131
<ProjectReference Include="..\..\src\Microsoft.OpenApi\Microsoft.OpenApi.csproj" />
3232
<ProjectReference Include="..\..\src\Microsoft.OpenApi.Readers\Microsoft.OpenApi.Readers.csproj" />
33+
<ProjectReference Include="..\Microsoft.OpenApi.Tests\Microsoft.OpenApi.Tests.csproj" />
3334
</ItemGroup>
3435

3536
</Project>

test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
using System.IO;
44
using FluentAssertions;
55
using Json.Schema;
6+
using Microsoft.OpenApi.Extensions;
67
using Microsoft.OpenApi.Interfaces;
78
using Microsoft.OpenApi.Models;
9+
using Microsoft.OpenApi.Tests;
810
using Microsoft.OpenApi.Writers;
911
using Xunit;
1012

@@ -352,5 +354,49 @@ public void ParseDocumentWithExampleInSchemaShouldSucceed()
352354
// Assert
353355
Assert.NotNull(actual);
354356
}
357+
358+
[Fact]
359+
public void ParseDocumentWithPatternPropertiesInSchemaWorks()
360+
{
361+
// Arrange
362+
using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "docWithPatternPropertiesInSchema.yaml"));
363+
364+
// Act
365+
var doc = new OpenApiStreamReader().Read(stream, out var diagnostic);
366+
367+
var actualSchema = doc.Paths["/example"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema;
368+
369+
var expectedSchema = new JsonSchemaBuilder()
370+
.Type(SchemaValueType.Object)
371+
.Properties(
372+
("prop1", new JsonSchemaBuilder().Type(SchemaValueType.String)),
373+
("prop2", new JsonSchemaBuilder().Type(SchemaValueType.String)),
374+
("prop3", new JsonSchemaBuilder().Type(SchemaValueType.String)))
375+
.PatternProperties(
376+
("^x-.*$", new JsonSchemaBuilder().Type(SchemaValueType.String)))
377+
.Build();
378+
379+
// Serialization
380+
var mediaType = doc.Paths["/example"].Operations[OperationType.Get].Responses["200"].Content["application/json"];
381+
382+
var expectedMediaType = @"schema:
383+
type: object
384+
properties:
385+
prop1:
386+
type: string
387+
prop2:
388+
type: string
389+
prop3:
390+
type: string
391+
patternProperties:
392+
^x-.*$:
393+
type: string";
394+
395+
var actualMediaType = mediaType.SerializeAsYaml(OpenApiSpecVersion.OpenApi3_1);
396+
397+
// Assert
398+
actualSchema.Should().BeEquivalentTo(expectedSchema);
399+
actualMediaType.MakeLineBreaksEnvironmentNeutral().Should().BeEquivalentTo(expectedMediaType.MakeLineBreaksEnvironmentNeutral());
400+
}
355401
}
356402
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
openapi: 3.1.0
2+
info:
3+
title: Example API
4+
version: 1.0.0
5+
paths:
6+
/example:
7+
get:
8+
summary: Get example object
9+
responses:
10+
'200':
11+
description: Successful operation
12+
content:
13+
application/json:
14+
schema:
15+
type: object
16+
properties:
17+
prop1:
18+
type: string
19+
prop2:
20+
type: string
21+
prop3:
22+
type: string
23+
patternProperties:
24+
"^x-.*$":
25+
type: string

test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.SerializeReferencedSchemaAsV3JsonWorksAsync_produceTerseOutput=False.verified.txt

Lines changed: 0 additions & 3 deletions
This file was deleted.

test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.SerializeReferencedSchemaAsV3JsonWorksAsync_produceTerseOutput=True.verified.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.SerializeReferencedSchemaAsV3WithoutReferenceJsonWorksAsync_produceTerseOutput=False.verified.txt

Lines changed: 0 additions & 13 deletions
This file was deleted.

test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.SerializeReferencedSchemaAsV3WithoutReferenceJsonWorksAsync_produceTerseOutput=True.verified.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)