diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml new file mode 100644 index 000000000..d7efd6213 --- /dev/null +++ b/.github/workflows/sonarcloud.yml @@ -0,0 +1,78 @@ +name: Sonarcloud +on: + workflow_dispatch: + push: + branches: + - main + paths-ignore: ['.vscode/**'] + pull_request: + types: [opened, synchronize, reopened] + paths-ignore: ['.vscode/**'] + +env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + +jobs: + checksecret: + name: check if SONAR_TOKEN is set in github secrets + runs-on: ubuntu-latest + outputs: + is_SONAR_TOKEN_set: ${{ steps.checksecret_job.outputs.is_SONAR_TOKEN_set }} + steps: + - name: Check whether unity activation requests should be done + id: checksecret_job + run: | + echo "is_SONAR_TOKEN_set=${{ env.SONAR_TOKEN != '' }}" >> $GITHUB_OUTPUT + build: + needs: [checksecret] + if: needs.checksecret.outputs.is_SONAR_TOKEN_set == 'true' + name: Build + runs-on: windows-latest + steps: + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + distribution: 'adopt' + java-version: 11 + - name: Setup .NET 5 # At the moment the scanner requires dotnet 5 https://www.nuget.org/packages/dotnet-sonarscanner + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 5.0.x + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 7.0.x + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: Cache SonarCloud packages + uses: actions/cache@v3 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Cache SonarCloud scanner + id: cache-sonar-scanner + uses: actions/cache@v3 + with: + path: ./.sonar/scanner + key: ${{ runner.os }}-sonar-scanner + restore-keys: ${{ runner.os }}-sonar-scanner + - name: Install SonarCloud scanner + if: steps.cache-sonar-scanner.outputs.cache-hit != 'true' + shell: pwsh + run: | + New-Item -Path ./.sonar/scanner -ItemType Directory + dotnet tool update dotnet-sonarscanner --tool-path ./.sonar/scanner + - name: Build and analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + CollectCoverage: true + CoverletOutputFormat: 'opencover' # https://github.com/microsoft/vstest/issues/4014#issuecomment-1307913682 + shell: pwsh + run: | + ./.sonar/scanner/dotnet-sonarscanner begin /k:"microsoft_OpenAPI.NET" /o:"microsoft" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="test/**/coverage.opencover.xml" + dotnet workload restore + dotnet build + dotnet test Microsoft.OpenApi.sln --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover + ./.sonar/scanner/dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}" \ No newline at end of file diff --git a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj index defdfdd54..bcac9a7af 100644 --- a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj +++ b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj @@ -10,7 +10,7 @@ Microsoft Microsoft.OpenApi.Readers Microsoft.OpenApi.Readers - 1.4.4 + 1.4.5 OpenAPI.NET Readers for JSON and YAML documents © Microsoft Corporation. All rights reserved. OpenAPI .NET diff --git a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj index 50d026f91..a938a968f 100644 --- a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj +++ b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj @@ -11,7 +11,7 @@ Microsoft Microsoft.OpenApi Microsoft.OpenApi - 1.4.4 + 1.4.5 .NET models with JSON and YAML writers for OpenAPI specification © Microsoft Corporation. All rights reserved. OpenAPI .NET diff --git a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs index e0e472721..fa62f0b79 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System; using System.Collections.Generic; using System.Runtime; using Microsoft.OpenApi.Any; @@ -238,9 +239,12 @@ public void SerializeAsV3WithoutReference(IOpenApiWriter writer) // allowEmptyValue writer.WriteProperty(OpenApiConstants.AllowEmptyValue, AllowEmptyValue, false); - + // style - writer.WriteProperty(OpenApiConstants.Style, Style?.GetDisplayName()); + if (_style.HasValue) + { + writer.WriteProperty(OpenApiConstants.Style, Style.Value.GetDisplayName()); + } // explode writer.WriteProperty(OpenApiConstants.Explode, Explode, Style.HasValue && Style.Value == ParameterStyle.Form); @@ -377,7 +381,7 @@ public void SerializeAsV2WithoutReference(IOpenApiWriter writer) // allowEmptyValue writer.WriteProperty(OpenApiConstants.AllowEmptyValue, AllowEmptyValue, false); - if (this.In == ParameterLocation.Query) + if (this.In == ParameterLocation.Query && "array".Equals(Schema?.Type, StringComparison.OrdinalIgnoreCase)) { if (this.Style == ParameterStyle.Form && this.Explode == true) { diff --git a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs index 6019d7362..513b865df 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs @@ -280,7 +280,7 @@ public OpenApiSchema(OpenApiSchema schema) MaxProperties = schema?.MaxProperties ?? MaxProperties; MinProperties = schema?.MinProperties ?? MinProperties; AdditionalPropertiesAllowed = schema?.AdditionalPropertiesAllowed ?? AdditionalPropertiesAllowed; - AdditionalProperties = new(schema?.AdditionalProperties); + AdditionalProperties = schema?.AdditionalProperties != null ? new(schema?.AdditionalProperties) : null; Discriminator = schema?.Discriminator != null ? new(schema?.Discriminator) : null; Example = OpenApiAnyCloneHelper.CloneFromCopyConstructor(schema?.Example); Enum = schema?.Enum != null ? new List(schema.Enum) : null; diff --git a/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs b/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs index ba2ed4129..a0aee12e7 100644 --- a/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs +++ b/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs @@ -20,7 +20,7 @@ public class OpenApiValidator : OpenApiVisitorBase, IValidationContext private readonly IList _warnings = new List(); /// - /// Create a vistor that will validate an OpenAPIDocument + /// Create a visitor that will validate an OpenAPIDocument /// /// public OpenApiValidator(ValidationRuleSet ruleSet) @@ -198,6 +198,100 @@ public void AddWarning(OpenApiValidatorWarning warning) /// The object to be validated public override void Visit(IList items) => Validate(items, items.GetType()); + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(OpenApiPathItem item) => Validate(item); + + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(OpenApiServerVariable item) => Validate(item); + + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(OpenApiSecurityScheme item) => Validate(item); + + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(OpenApiSecurityRequirement item) => Validate(item); + + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(OpenApiRequestBody item) => Validate(item); + + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(OpenApiPaths item) => Validate(item); + + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(OpenApiLink item) => Validate(item); + + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(OpenApiExample item) => Validate(item); + + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(OpenApiOperation item) => Validate(item); + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(IDictionary item) => Validate(item, item.GetType()); + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(IDictionary item) => Validate(item, item.GetType()); + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(IDictionary item) => Validate(item, item.GetType()); + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(IDictionary item) => Validate(item, item.GetType()); + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(IDictionary item) => Validate(item, item.GetType()); + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(IDictionary item) => Validate(item, item.GetType()); + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(IDictionary item) => Validate(item, item.GetType()); + /// + /// Execute validation rules against a + /// + /// The object to be validated + public override void Visit(IDictionary item) => Validate(item, item.GetType()); + private void Validate(T item) { var type = typeof(T); diff --git a/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj b/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj index f450e2ff7..0902ff177 100644 --- a/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj +++ b/test/Microsoft.OpenApi.Hidi.Tests/Microsoft.OpenApi.Hidi.Tests.csproj @@ -9,8 +9,12 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + - + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj index a12969f52..8fb35ee88 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj +++ b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj @@ -253,10 +253,18 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + - + diff --git a/test/Microsoft.OpenApi.SmokeTests/Microsoft.OpenApi.SmokeTests.csproj b/test/Microsoft.OpenApi.SmokeTests/Microsoft.OpenApi.SmokeTests.csproj index 9c88e8394..0fab323f7 100644 --- a/test/Microsoft.OpenApi.SmokeTests/Microsoft.OpenApi.SmokeTests.csproj +++ b/test/Microsoft.OpenApi.SmokeTests/Microsoft.OpenApi.SmokeTests.csproj @@ -8,8 +8,16 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + - + all diff --git a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj index e2a21cc74..5f6d0c748 100644 --- a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj +++ b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj @@ -15,12 +15,20 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + - - + + - + all diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV2JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV2JsonWorks_produceTerseOutput=False.verified.txt index a991e0761..a2e4fbd4c 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV2JsonWorks_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV2JsonWorks_produceTerseOutput=False.verified.txt @@ -46,8 +46,7 @@ "name": "limit", "description": "maximum number of results to return", "type": "integer", - "format": "int32", - "collectionFormat": "multi" + "format": "int32" } ], "responses": { diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV2JsonWorks_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV2JsonWorks_produceTerseOutput=True.verified.txt index 5ce01bf79..081bcda08 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV2JsonWorks_produceTerseOutput=True.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV2JsonWorks_produceTerseOutput=True.verified.txt @@ -1 +1 @@ -{"swagger":"2.0","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","termsOfService":"http://helloreverb.com/terms/","contact":{"name":"Swagger API team","url":"http://swagger.io","email":"foo@example.com"},"license":{"name":"MIT","url":"http://opensource.org/licenses/MIT"},"version":"1.0.0"},"host":"petstore.swagger.io","basePath":"/api","schemes":["http"],"paths":{"/pets":{"get":{"description":"Returns all pets from the system that the user has access to","operationId":"findPets","produces":["application/json","application/xml","text/html"],"parameters":[{"in":"query","name":"tags","description":"tags to filter by","type":"array","items":{"type":"string"},"collectionFormat":"multi"},{"in":"query","name":"limit","description":"maximum number of results to return","type":"integer","format":"int32","collectionFormat":"multi"}],"responses":{"200":{"description":"pet response","schema":{"type":"array","items":{"required":["id","name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}}}},"4XX":{"description":"unexpected client error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}},"5XX":{"description":"unexpected server error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}}}},"post":{"description":"Creates a new pet in the store. Duplicates are allowed","operationId":"addPet","consumes":["application/json"],"produces":["application/json","text/html"],"parameters":[{"in":"body","name":"body","description":"Pet to add to the store","required":true,"schema":{"required":["name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}}}],"responses":{"200":{"description":"pet response","schema":{"required":["id","name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}}},"4XX":{"description":"unexpected client error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}},"5XX":{"description":"unexpected server error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}}}}},"/pets/{id}":{"get":{"description":"Returns a user based on a single ID, if the user does not have access to the pet","operationId":"findPetById","produces":["application/json","application/xml","text/html"],"parameters":[{"in":"path","name":"id","description":"ID of pet to fetch","required":true,"type":"integer","format":"int64"}],"responses":{"200":{"description":"pet response","schema":{"required":["id","name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}}},"4XX":{"description":"unexpected client error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}},"5XX":{"description":"unexpected server error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}}}},"delete":{"description":"deletes a single pet based on the ID supplied","operationId":"deletePet","produces":["text/html"],"parameters":[{"in":"path","name":"id","description":"ID of pet to delete","required":true,"type":"integer","format":"int64"}],"responses":{"204":{"description":"pet deleted"},"4XX":{"description":"unexpected client error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}},"5XX":{"description":"unexpected server error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}}}}}},"definitions":{"pet":{"required":["id","name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}},"newPet":{"required":["name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}},"errorModel":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}}} \ No newline at end of file +{"swagger":"2.0","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","termsOfService":"http://helloreverb.com/terms/","contact":{"name":"Swagger API team","url":"http://swagger.io","email":"foo@example.com"},"license":{"name":"MIT","url":"http://opensource.org/licenses/MIT"},"version":"1.0.0"},"host":"petstore.swagger.io","basePath":"/api","schemes":["http"],"paths":{"/pets":{"get":{"description":"Returns all pets from the system that the user has access to","operationId":"findPets","produces":["application/json","application/xml","text/html"],"parameters":[{"in":"query","name":"tags","description":"tags to filter by","type":"array","items":{"type":"string"},"collectionFormat":"multi"},{"in":"query","name":"limit","description":"maximum number of results to return","type":"integer","format":"int32"}],"responses":{"200":{"description":"pet response","schema":{"type":"array","items":{"required":["id","name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}}}},"4XX":{"description":"unexpected client error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}},"5XX":{"description":"unexpected server error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}}}},"post":{"description":"Creates a new pet in the store. Duplicates are allowed","operationId":"addPet","consumes":["application/json"],"produces":["application/json","text/html"],"parameters":[{"in":"body","name":"body","description":"Pet to add to the store","required":true,"schema":{"required":["name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}}}],"responses":{"200":{"description":"pet response","schema":{"required":["id","name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}}},"4XX":{"description":"unexpected client error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}},"5XX":{"description":"unexpected server error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}}}}},"/pets/{id}":{"get":{"description":"Returns a user based on a single ID, if the user does not have access to the pet","operationId":"findPetById","produces":["application/json","application/xml","text/html"],"parameters":[{"in":"path","name":"id","description":"ID of pet to fetch","required":true,"type":"integer","format":"int64"}],"responses":{"200":{"description":"pet response","schema":{"required":["id","name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}}},"4XX":{"description":"unexpected client error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}},"5XX":{"description":"unexpected server error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}}}},"delete":{"description":"deletes a single pet based on the ID supplied","operationId":"deletePet","produces":["text/html"],"parameters":[{"in":"path","name":"id","description":"ID of pet to delete","required":true,"type":"integer","format":"int64"}],"responses":{"204":{"description":"pet deleted"},"4XX":{"description":"unexpected client error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}},"5XX":{"description":"unexpected server error","schema":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}}}}}},"definitions":{"pet":{"required":["id","name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}},"newPet":{"required":["name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}},"errorModel":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}}} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks2_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks2_produceTerseOutput=False.verified.txt new file mode 100644 index 000000000..a94db37b7 --- /dev/null +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks2_produceTerseOutput=False.verified.txt @@ -0,0 +1,495 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Swagger Petstore (Simple)", + "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification", + "termsOfService": "http://helloreverb.com/terms/", + "contact": { + "name": "Swagger API team", + "url": "http://swagger.io", + "email": "foo@example.com" + }, + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/MIT" + }, + "version": "1.0.0" + }, + "servers": [ + { + "url": "http://petstore.swagger.io/api" + } + ], + "paths": { + "/pets": { + "get": { + "description": "Returns all pets from the system that the user has access to", + "operationId": "findPets", + "parameters": [ + { + "name": "tags", + "in": "query", + "description": "tags to filter by", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "limit", + "in": "query", + "description": "maximum number of results to return", + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "description": "pet response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "required": [ + "id", + "name" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + } + } + }, + "application/xml": { + "schema": { + "type": "array", + "items": { + "required": [ + "id", + "name" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + } + } + } + } + }, + "4XX": { + "description": "unexpected client error", + "content": { + "text/html": { + "schema": { + "required": [ + "code", + "message" + ], + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } + }, + "5XX": { + "description": "unexpected server error", + "content": { + "text/html": { + "schema": { + "required": [ + "code", + "message" + ], + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "post": { + "description": "Creates a new pet in the store. Duplicates are allowed", + "operationId": "addPet", + "requestBody": { + "description": "Pet to add to the store", + "content": { + "application/json": { + "schema": { + "required": [ + "name" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "pet response", + "content": { + "application/json": { + "schema": { + "required": [ + "id", + "name" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + } + } + } + }, + "4XX": { + "description": "unexpected client error", + "content": { + "text/html": { + "schema": { + "required": [ + "code", + "message" + ], + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } + }, + "5XX": { + "description": "unexpected server error", + "content": { + "text/html": { + "schema": { + "required": [ + "code", + "message" + ], + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/pets/{id}": { + "get": { + "description": "Returns a user based on a single ID, if the user does not have access to the pet", + "operationId": "findPetById", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of pet to fetch", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "200": { + "description": "pet response", + "content": { + "application/json": { + "schema": { + "required": [ + "id", + "name" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + } + }, + "application/xml": { + "schema": { + "required": [ + "id", + "name" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + } + } + } + }, + "4XX": { + "description": "unexpected client error", + "content": { + "text/html": { + "schema": { + "required": [ + "code", + "message" + ], + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } + }, + "5XX": { + "description": "unexpected server error", + "content": { + "text/html": { + "schema": { + "required": [ + "code", + "message" + ], + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "delete": { + "description": "deletes a single pet based on the ID supplied", + "operationId": "deletePet", + "parameters": [ + { + "name": "id", + "in": "path", + "description": "ID of pet to delete", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], + "responses": { + "204": { + "description": "pet deleted" + }, + "4XX": { + "description": "unexpected client error", + "content": { + "text/html": { + "schema": { + "required": [ + "code", + "message" + ], + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } + }, + "5XX": { + "description": "unexpected server error", + "content": { + "text/html": { + "schema": { + "required": [ + "code", + "message" + ], + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "pet": { + "required": [ + "id", + "name" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "newPet": { + "required": [ + "name" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "errorModel": { + "required": [ + "code", + "message" + ], + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } +} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks2_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks2_produceTerseOutput=True.verified.txt new file mode 100644 index 000000000..72106e400 --- /dev/null +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks2_produceTerseOutput=True.verified.txt @@ -0,0 +1 @@ +{"openapi":"3.0.1","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","termsOfService":"http://helloreverb.com/terms/","contact":{"name":"Swagger API team","url":"http://swagger.io","email":"foo@example.com"},"license":{"name":"MIT","url":"http://opensource.org/licenses/MIT"},"version":"1.0.0"},"servers":[{"url":"http://petstore.swagger.io/api"}],"paths":{"/pets":{"get":{"description":"Returns all pets from the system that the user has access to","operationId":"findPets","parameters":[{"name":"tags","in":"query","description":"tags to filter by","schema":{"type":"array","items":{"type":"string"}}},{"name":"limit","in":"query","description":"maximum number of results to return","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"type":"array","items":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}},"application/xml":{"schema":{"type":"array","items":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}}},"post":{"description":"Creates a new pet in the store. Duplicates are allowed","operationId":"addPet","requestBody":{"description":"Pet to add to the store","content":{"application/json":{"schema":{"required":["name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}},"required":true},"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}}}},"/pets/{id}":{"get":{"description":"Returns a user based on a single ID, if the user does not have access to the pet","operationId":"findPetById","parameters":[{"name":"id","in":"path","description":"ID of pet to fetch","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}},"application/xml":{"schema":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}}},"delete":{"description":"deletes a single pet based on the ID supplied","operationId":"deletePet","parameters":[{"name":"id","in":"path","description":"ID of pet to delete","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"pet deleted"},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}}}}},"components":{"schemas":{"pet":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"newPet":{"required":["name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"errorModel":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks_produceTerseOutput=False.verified.txt index 5b27add35..a94db37b7 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks_produceTerseOutput=False.verified.txt @@ -1,4 +1,4 @@ -{ +{ "openapi": "3.0.1", "info": { "title": "Swagger Petstore (Simple)", @@ -30,7 +30,6 @@ "name": "tags", "in": "query", "description": "tags to filter by", - "style": "form", "schema": { "type": "array", "items": { @@ -42,7 +41,6 @@ "name": "limit", "in": "query", "description": "maximum number of results to return", - "style": "form", "schema": { "type": "integer", "format": "int32" @@ -266,7 +264,6 @@ "in": "path", "description": "ID of pet to fetch", "required": true, - "style": "simple", "schema": { "type": "integer", "format": "int64" @@ -378,7 +375,6 @@ "in": "path", "description": "ID of pet to delete", "required": true, - "style": "simple", "schema": { "type": "integer", "format": "int64" diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks_produceTerseOutput=True.verified.txt index e3abf0e50..72106e400 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks_produceTerseOutput=True.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentAsV3JsonWorks_produceTerseOutput=True.verified.txt @@ -1 +1 @@ -{"openapi":"3.0.1","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","termsOfService":"http://helloreverb.com/terms/","contact":{"name":"Swagger API team","url":"http://swagger.io","email":"foo@example.com"},"license":{"name":"MIT","url":"http://opensource.org/licenses/MIT"},"version":"1.0.0"},"servers":[{"url":"http://petstore.swagger.io/api"}],"paths":{"/pets":{"get":{"description":"Returns all pets from the system that the user has access to","operationId":"findPets","parameters":[{"name":"tags","in":"query","description":"tags to filter by","style":"form","schema":{"type":"array","items":{"type":"string"}}},{"name":"limit","in":"query","description":"maximum number of results to return","style":"form","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"type":"array","items":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}},"application/xml":{"schema":{"type":"array","items":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}}},"post":{"description":"Creates a new pet in the store. Duplicates are allowed","operationId":"addPet","requestBody":{"description":"Pet to add to the store","content":{"application/json":{"schema":{"required":["name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}},"required":true},"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}}}},"/pets/{id}":{"get":{"description":"Returns a user based on a single ID, if the user does not have access to the pet","operationId":"findPetById","parameters":[{"name":"id","in":"path","description":"ID of pet to fetch","required":true,"style":"simple","schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}},"application/xml":{"schema":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}}},"delete":{"description":"deletes a single pet based on the ID supplied","operationId":"deletePet","parameters":[{"name":"id","in":"path","description":"ID of pet to delete","required":true,"style":"simple","schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"pet deleted"},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}}}}},"components":{"schemas":{"pet":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"newPet":{"required":["name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"errorModel":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}} \ No newline at end of file +{"openapi":"3.0.1","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","termsOfService":"http://helloreverb.com/terms/","contact":{"name":"Swagger API team","url":"http://swagger.io","email":"foo@example.com"},"license":{"name":"MIT","url":"http://opensource.org/licenses/MIT"},"version":"1.0.0"},"servers":[{"url":"http://petstore.swagger.io/api"}],"paths":{"/pets":{"get":{"description":"Returns all pets from the system that the user has access to","operationId":"findPets","parameters":[{"name":"tags","in":"query","description":"tags to filter by","schema":{"type":"array","items":{"type":"string"}}},{"name":"limit","in":"query","description":"maximum number of results to return","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"type":"array","items":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}},"application/xml":{"schema":{"type":"array","items":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}}},"post":{"description":"Creates a new pet in the store. Duplicates are allowed","operationId":"addPet","requestBody":{"description":"Pet to add to the store","content":{"application/json":{"schema":{"required":["name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}},"required":true},"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}}}},"/pets/{id}":{"get":{"description":"Returns a user based on a single ID, if the user does not have access to the pet","operationId":"findPetById","parameters":[{"name":"id","in":"path","description":"ID of pet to fetch","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"pet response","content":{"application/json":{"schema":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}},"application/xml":{"schema":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}}}}},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}}},"delete":{"description":"deletes a single pet based on the ID supplied","operationId":"deletePet","parameters":[{"name":"id","in":"path","description":"ID of pet to delete","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"204":{"description":"pet deleted"},"4XX":{"description":"unexpected client error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}},"5XX":{"description":"unexpected server error","content":{"text/html":{"schema":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}}}}}},"components":{"schemas":{"pet":{"required":["id","name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"newPet":{"required":["name"],"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"tag":{"type":"string"}}},"errorModel":{"required":["code","message"],"type":"object","properties":{"code":{"type":"integer","format":"int32"},"message":{"type":"string"}}}}}} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=False.verified.txt index 1ee60de40..443881617 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=False.verified.txt @@ -46,8 +46,7 @@ "name": "limit", "description": "maximum number of results to return", "type": "integer", - "format": "int32", - "collectionFormat": "multi" + "format": "int32" } ], "responses": { diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=True.verified.txt index 682b253b7..3818a4799 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=True.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV2JsonWorks_produceTerseOutput=True.verified.txt @@ -1 +1 @@ -{"swagger":"2.0","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","termsOfService":"http://helloreverb.com/terms/","contact":{"name":"Swagger API team","url":"http://swagger.io","email":"foo@example.com"},"license":{"name":"MIT","url":"http://opensource.org/licenses/MIT"},"version":"1.0.0"},"host":"petstore.swagger.io","basePath":"/api","schemes":["http"],"paths":{"/pets":{"get":{"description":"Returns all pets from the system that the user has access to","operationId":"findPets","produces":["application/json","application/xml","text/html"],"parameters":[{"in":"query","name":"tags","description":"tags to filter by","type":"array","items":{"type":"string"},"collectionFormat":"multi"},{"in":"query","name":"limit","description":"maximum number of results to return","type":"integer","format":"int32","collectionFormat":"multi"}],"responses":{"200":{"description":"pet response","schema":{"type":"array","items":{"$ref":"#/definitions/pet"}}},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/definitions/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/definitions/errorModel"}}}},"post":{"description":"Creates a new pet in the store. Duplicates are allowed","operationId":"addPet","consumes":["application/json"],"produces":["application/json","text/html"],"parameters":[{"in":"body","name":"body","description":"Pet to add to the store","required":true,"schema":{"$ref":"#/definitions/newPet"}}],"responses":{"200":{"description":"pet response","schema":{"$ref":"#/definitions/pet"}},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/definitions/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/definitions/errorModel"}}}}},"/pets/{id}":{"get":{"description":"Returns a user based on a single ID, if the user does not have access to the pet","operationId":"findPetById","produces":["application/json","application/xml","text/html"],"parameters":[{"in":"path","name":"id","description":"ID of pet to fetch","required":true,"type":"integer","format":"int64"}],"responses":{"200":{"description":"pet response","schema":{"$ref":"#/definitions/pet"}},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/definitions/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/definitions/errorModel"}}}},"delete":{"description":"deletes a single pet based on the ID supplied","operationId":"deletePet","produces":["text/html"],"parameters":[{"in":"path","name":"id","description":"ID of pet to delete","required":true,"type":"integer","format":"int64"}],"responses":{"204":{"description":"pet deleted"},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/definitions/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/definitions/errorModel"}}}}}},"definitions":{"pet":{"required":["id","name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}},"newPet":{"required":["name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}},"errorModel":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}}} \ No newline at end of file +{"swagger":"2.0","info":{"title":"Swagger Petstore (Simple)","description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification","termsOfService":"http://helloreverb.com/terms/","contact":{"name":"Swagger API team","url":"http://swagger.io","email":"foo@example.com"},"license":{"name":"MIT","url":"http://opensource.org/licenses/MIT"},"version":"1.0.0"},"host":"petstore.swagger.io","basePath":"/api","schemes":["http"],"paths":{"/pets":{"get":{"description":"Returns all pets from the system that the user has access to","operationId":"findPets","produces":["application/json","application/xml","text/html"],"parameters":[{"in":"query","name":"tags","description":"tags to filter by","type":"array","items":{"type":"string"},"collectionFormat":"multi"},{"in":"query","name":"limit","description":"maximum number of results to return","type":"integer","format":"int32"}],"responses":{"200":{"description":"pet response","schema":{"type":"array","items":{"$ref":"#/definitions/pet"}}},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/definitions/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/definitions/errorModel"}}}},"post":{"description":"Creates a new pet in the store. Duplicates are allowed","operationId":"addPet","consumes":["application/json"],"produces":["application/json","text/html"],"parameters":[{"in":"body","name":"body","description":"Pet to add to the store","required":true,"schema":{"$ref":"#/definitions/newPet"}}],"responses":{"200":{"description":"pet response","schema":{"$ref":"#/definitions/pet"}},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/definitions/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/definitions/errorModel"}}}}},"/pets/{id}":{"get":{"description":"Returns a user based on a single ID, if the user does not have access to the pet","operationId":"findPetById","produces":["application/json","application/xml","text/html"],"parameters":[{"in":"path","name":"id","description":"ID of pet to fetch","required":true,"type":"integer","format":"int64"}],"responses":{"200":{"description":"pet response","schema":{"$ref":"#/definitions/pet"}},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/definitions/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/definitions/errorModel"}}}},"delete":{"description":"deletes a single pet based on the ID supplied","operationId":"deletePet","produces":["text/html"],"parameters":[{"in":"path","name":"id","description":"ID of pet to delete","required":true,"type":"integer","format":"int64"}],"responses":{"204":{"description":"pet deleted"},"4XX":{"description":"unexpected client error","schema":{"$ref":"#/definitions/errorModel"}},"5XX":{"description":"unexpected server error","schema":{"$ref":"#/definitions/errorModel"}}}}}},"definitions":{"pet":{"required":["id","name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}},"newPet":{"required":["name"],"type":"object","properties":{"id":{"format":"int64","type":"integer"},"name":{"type":"string"},"tag":{"type":"string"}}},"errorModel":{"required":["code","message"],"type":"object","properties":{"code":{"format":"int32","type":"integer"},"message":{"type":"string"}}}}} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt index f272b26eb..f1da0b354 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeAdvancedDocumentWithReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt @@ -30,7 +30,6 @@ "name": "tags", "in": "query", "description": "tags to filter by", - "style": "form", "schema": { "type": "array", "items": { @@ -42,7 +41,6 @@ "name": "limit", "in": "query", "description": "maximum number of results to return", - "style": "form", "schema": { "type": "integer", "format": "int32" @@ -151,7 +149,6 @@ "in": "path", "description": "ID of pet to fetch", "required": true, - "style": "simple", "schema": { "type": "integer", "format": "int64" @@ -205,7 +202,6 @@ "in": "path", "description": "ID of pet to delete", "required": true, - "style": "simple", "schema": { "type": "integer", "format": "int64" diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeDuplicateExtensionsAsV3JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeDuplicateExtensionsAsV3JsonWorks_produceTerseOutput=False.verified.txt index 8b90dd0ee..c2e9f5312 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeDuplicateExtensionsAsV3JsonWorks_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.SerializeDuplicateExtensionsAsV3JsonWorks_produceTerseOutput=False.verified.txt @@ -20,7 +20,6 @@ "in": "path", "description": "The first operand", "required": true, - "style": "simple", "schema": { "type": "integer", "my-extension": 4 @@ -32,7 +31,6 @@ "in": "path", "description": "The second operand", "required": true, - "style": "simple", "schema": { "type": "integer", "my-extension": 4 diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.cs index 89289397f..8633bdbaf 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.cs @@ -1,10 +1,11 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Threading; using System.Threading.Tasks; using FluentAssertions; using Microsoft.OpenApi.Extensions; @@ -598,7 +599,7 @@ public class OpenApiDocumentTests public static OpenApiSchema ErrorModelSchema = AdvancedComponents.Schemas["errorModel"]; - public static OpenApiDocument AdvancedDocument = new OpenApiDocument + public OpenApiDocument AdvancedDocument = new OpenApiDocument { Info = new OpenApiInfo { @@ -987,8 +988,8 @@ public OpenApiDocumentTests(ITestOutputHelper output) } [Theory] - [InlineData(true)] [InlineData(false)] + [InlineData(true)] public async Task SerializeAdvancedDocumentAsV3JsonWorks(bool produceTerseOutput) { // Arrange @@ -1356,5 +1357,146 @@ public void CopyConstructorForAdvancedDocumentWorks() Assert.Equal(2, doc.Paths.Count); Assert.NotNull(doc.Components); } + + [Fact] + public void SerializeV2DocumentWithNonArraySchemaTypeDoesNotWriteOutCollectionFormat() + { + // Arrange + var expected = @"swagger: '2.0' +info: { } +paths: + /foo: + get: + parameters: + - in: query + type: string + responses: { }"; + + var doc = new OpenApiDocument + { + Info = new OpenApiInfo(), + Paths = new OpenApiPaths + { + ["/foo"] = new OpenApiPathItem + { + Operations = new Dictionary + { + [OperationType.Get] = new OpenApiOperation + { + Parameters = new List + { + new OpenApiParameter + { + In = ParameterLocation.Query, + Schema = new OpenApiSchema + { + Type = "string" + } + } + }, + Responses = new OpenApiResponses() + } + } + } + } + }; + + // Act + var actual = doc.SerializeAsYaml(OpenApiSpecVersion.OpenApi2_0); + + // Assert + actual = actual.MakeLineBreaksEnvironmentNeutral(); + expected = expected.MakeLineBreaksEnvironmentNeutral(); + actual.Should().Be(expected); + } + + [Fact] + public void SerializeV2DocumentWithStyleAsNullDoesNotWriteOutStyleValue() + { + // Arrange + var expected = @"openapi: 3.0.1 +info: + title: magic style + version: 1.0.0 +paths: + /foo: + get: + parameters: + - name: id + in: query + schema: + type: object + additionalProperties: + type: integer + responses: + '200': + description: foo + content: + text/plain: + schema: + type: string"; + + var doc = new OpenApiDocument + { + Info = new OpenApiInfo + { + Title = "magic style", + Version = "1.0.0" + }, + Paths = new OpenApiPaths + { + ["/foo"] = new OpenApiPathItem + { + Operations = new Dictionary + { + [OperationType.Get] = new OpenApiOperation + { + Parameters = new List + { + new OpenApiParameter + { + Name = "id", + In = ParameterLocation.Query, + Schema = new OpenApiSchema + { + Type = "object", + AdditionalProperties = new OpenApiSchema + { + Type = "integer" + } + } + } + }, + Responses = new OpenApiResponses + { + ["200"] = new OpenApiResponse + { + Description = "foo", + Content = new Dictionary + { + ["text/plain"] = new OpenApiMediaType + { + Schema = new OpenApiSchema + { + Type = "string" + } + } + } + } + } + } + } + } + } + }; + + // Act + var actual = doc.SerializeAsYaml(OpenApiSpecVersion.OpenApi3_0); + + // Assert + actual = actual.MakeLineBreaksEnvironmentNeutral(); + expected = expected.MakeLineBreaksEnvironmentNeutral(); + actual.Should().Be(expected); + } } } diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs index 368aeb227..2079a3122 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs @@ -334,13 +334,11 @@ public void SerializeOperationWithBodyAsV3JsonWorks() ""parameters"": [ { ""name"": ""parameter1"", - ""in"": ""path"", - ""style"": ""simple"" + ""in"": ""path"" }, { ""name"": ""parameter2"", - ""in"": ""header"", - ""style"": ""simple"" + ""in"": ""header"" } ], ""requestBody"": { @@ -409,13 +407,11 @@ public void SerializeAdvancedOperationWithTagAndSecurityAsV3JsonWorks() ""parameters"": [ { ""name"": ""parameter1"", - ""in"": ""path"", - ""style"": ""simple"" + ""in"": ""path"" }, { ""name"": ""parameter2"", - ""in"": ""header"", - ""style"": ""simple"" + ""in"": ""header"" } ], ""requestBody"": { @@ -505,7 +501,6 @@ public void SerializeOperationWithFormDataAsV3JsonWorks() ""in"": ""path"", ""description"": ""ID of pet that needs to be updated"", ""required"": true, - ""style"": ""simple"", ""schema"": { ""type"": ""string"" } diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.SerializeReferencedParameterAsV3JsonWithoutReferenceWorksAsync_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.SerializeReferencedParameterAsV3JsonWithoutReferenceWorksAsync_produceTerseOutput=False.verified.txt index f4424fa30..5275532e8 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.SerializeReferencedParameterAsV3JsonWithoutReferenceWorksAsync_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.SerializeReferencedParameterAsV3JsonWithoutReferenceWorksAsync_produceTerseOutput=False.verified.txt @@ -1,5 +1,4 @@ { "name": "name1", - "in": "path", - "style": "simple" + "in": "path" } \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs index cfcc56d15..2f57673af 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs @@ -213,8 +213,7 @@ public void SerializeBasicParameterAsV3JsonWorks() // Arrange var expected = @"{ ""name"": ""name1"", - ""in"": ""path"", - ""style"": ""simple"" + ""in"": ""path"" }"; // Act diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs index 429129c1e..447d01337 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs @@ -463,5 +463,24 @@ public void SerializeAsV2ShouldSetFormatPropertyInParentSchemaIfPresentInChildre // Assert Assert.Equal(expectedV2Schema, v2Schema); } + + [Fact] + public void OpenApiSchemaCopyConstructorSucceeds() + { + var baseSchema = new OpenApiSchema() + { + Type = "string", + Format = "date" + }; + + var actualSchema = new OpenApiSchema(baseSchema) + { + Nullable = true + }; + + Assert.Equal("string", actualSchema.Type); + Assert.Equal("date", actualSchema.Format); + Assert.True(actualSchema.Nullable); + } } } diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index b8646cae5..9b4747312 100755 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -1212,18 +1212,35 @@ namespace Microsoft.OpenApi.Validations public override void Visit(Microsoft.OpenApi.Models.OpenApiContact item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiDocument item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiEncoding item) { } + public override void Visit(Microsoft.OpenApi.Models.OpenApiExample item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiExternalDocs item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiHeader item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiInfo item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiLicense item) { } + public override void Visit(Microsoft.OpenApi.Models.OpenApiLink item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiMediaType item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiOAuthFlow item) { } + public override void Visit(Microsoft.OpenApi.Models.OpenApiOperation item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiParameter item) { } + public override void Visit(Microsoft.OpenApi.Models.OpenApiPathItem item) { } + public override void Visit(Microsoft.OpenApi.Models.OpenApiPaths item) { } + public override void Visit(Microsoft.OpenApi.Models.OpenApiRequestBody item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiResponse item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiResponses item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiSchema item) { } + public override void Visit(Microsoft.OpenApi.Models.OpenApiSecurityRequirement item) { } + public override void Visit(Microsoft.OpenApi.Models.OpenApiSecurityScheme item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiServer item) { } + public override void Visit(Microsoft.OpenApi.Models.OpenApiServerVariable item) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiTag item) { } + public override void Visit(System.Collections.Generic.IDictionary item) { } + public override void Visit(System.Collections.Generic.IDictionary item) { } + public override void Visit(System.Collections.Generic.IDictionary item) { } + public override void Visit(System.Collections.Generic.IDictionary item) { } + public override void Visit(System.Collections.Generic.IDictionary item) { } + public override void Visit(System.Collections.Generic.IDictionary item) { } + public override void Visit(System.Collections.Generic.IDictionary item) { } + public override void Visit(System.Collections.Generic.IDictionary item) { } public override void Visit(System.Collections.Generic.IList items) { } } public class OpenApiValidatorError : Microsoft.OpenApi.Models.OpenApiError