зеркало из https://github.com/Azure/autorest.git
base classes can now have x-ms-discriminator-value extension on them (#2115)
* base classes can now have x-ms-discriminator-value extension on them * updated example schema to support description of the scneario * resolving the csproj file
This commit is contained in:
Родитель
4d884a1a10
Коммит
1ae5af28cf
|
@ -15,6 +15,10 @@
|
|||
"description": "The title in the swagger spec that uniquely identifies the swagger spec.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "A brief explanation about the current scenario.",
|
||||
"type": "string"
|
||||
},
|
||||
"parameters": {
|
||||
"$ref": "#/xmsParametersExample"
|
||||
},
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Resource\Swagger\swagger-x-ms-discriminator-value.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Resource\Swagger\Validation\swagger-list-by-immediate-parent.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@ -62,4 +65,6 @@
|
|||
<ProjectReference Include="$(SolutionDir)src/core/AutoRest.Core/AutoRest.Core.csproj" />
|
||||
<ProjectReference Include="$(SolutionDir)src/modeler/AutoRest.Swagger/AutoRest.Swagger.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ProjectExtensions><VisualStudio><UserProperties Resource_4Swagger_4swagger-x-ms-discriminator-value_1json__JSONSchema="..\..\..\..\..\schema\swagger-extensions.json" /></VisualStudio></ProjectExtensions>
|
||||
</Project>
|
|
@ -0,0 +1,287 @@
|
|||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"version": "1.0.0",
|
||||
"title": "Swagger Petstore",
|
||||
"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": "Wordnik API Team",
|
||||
"email": "foo@example.com",
|
||||
"url": "http://madskristensen.net"
|
||||
},
|
||||
"license": {
|
||||
"name": "MIT",
|
||||
"url": "http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT"
|
||||
}
|
||||
},
|
||||
"host": "petstore.swagger.wordnik.com",
|
||||
"basePath": "/api",
|
||||
"schemes": [
|
||||
"http", "https"
|
||||
],
|
||||
"consumes": [
|
||||
"application/json",
|
||||
"application/xml",
|
||||
"application/json; charset=utf-8",
|
||||
"application/xml; charset=utf-8",
|
||||
"application/atom+xml",
|
||||
"application/octet-stream",
|
||||
"application/zip",
|
||||
"application/gzip"
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml",
|
||||
"application/json; charset=utf-8",
|
||||
"application/xml; charset=utf-8",
|
||||
"application/atom+xml",
|
||||
"application/atom+xml; charset=utf-8",
|
||||
"application/octet-stream",
|
||||
"application/zip",
|
||||
"application/gzip"
|
||||
],
|
||||
"paths": {
|
||||
"/pet": {
|
||||
"get": {
|
||||
"description": "Returns all pets from the system that the user has access to",
|
||||
"operationId": "findPets",
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml",
|
||||
"text/xml",
|
||||
"text/html"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "tags",
|
||||
"in": "query",
|
||||
"description": "tags to filter by",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"collectionFormat": "csv"
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"in": "query",
|
||||
"description": "maximum number of results to return",
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "pet response",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/pet"
|
||||
}
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "unexpected error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"description": "Creates a new pet in the store. Duplicates are allowed",
|
||||
"operationId": "addPet",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "pet",
|
||||
"in": "body",
|
||||
"description": "Pet to add to the store",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/newPet"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "pet response",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/pet"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "unexpected error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorModel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"tags": [],
|
||||
"summary": "",
|
||||
"description": "",
|
||||
"operationId": "CreateOrUpdatePet",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "PetCreateOrUpdateParameter",
|
||||
"in": "body",
|
||||
"description": "A Pet",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/pet"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": { "$ref": "#/responses/petResponse" },
|
||||
"default": {
|
||||
"description": "unexpected error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorModel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schemes": [ "http", "https" ],
|
||||
"deprecated": true,
|
||||
"security": [],
|
||||
"x-test-header-info": {
|
||||
"name": "x-static-header",
|
||||
"value": "headerValue"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"pet": {
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"discriminator": "type",
|
||||
"x-ms-discriminator-value": "Microsoft.Models.MSPet",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"tag": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"cat": {
|
||||
"x-ms-discriminator-value": "Microsoft.Models.MSCat",
|
||||
"allOf": [ { "$ref": "#/definitions/pet" } ],
|
||||
"required": [ "breed" ],
|
||||
"properties": {
|
||||
"breed": {
|
||||
"type": "string"
|
||||
},
|
||||
"color": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"siamese": {
|
||||
"x-ms-discriminator-value": "Microsoft.Models.MSSiameseCat",
|
||||
"allOf": [ { "$ref": "#/definitions/cat" } ],
|
||||
"properties": {
|
||||
"mood": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dog": {
|
||||
"x-ms-discriminator-value": "Microsoft.Models.MSDog",
|
||||
"allOf": [ { "$ref": "#/definitions/pet" } ],
|
||||
"required": [ "pedigree" ],
|
||||
"properties": {
|
||||
"pedigree": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"newPet": {
|
||||
"x-ms-discriminator-value": "Microsoft.Models.MSNewPet",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/pet"
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"errorModel": {
|
||||
"required": [
|
||||
"code",
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"petParameter": {
|
||||
"name": "PetCreateOrUpdateParameter",
|
||||
"in": "body",
|
||||
"description": "A Pet",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/pet"
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"petResponse": {
|
||||
"description": " A created or updated pet",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/pet"
|
||||
},
|
||||
"headers": {
|
||||
"x-ms-request-id": {
|
||||
"description": " The request ID",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": { },
|
||||
"security": [ ],
|
||||
"tags": [ ]
|
||||
}
|
|
@ -21,7 +21,7 @@ namespace AutoRest.Swagger.Tests
|
|||
{
|
||||
public SwaggerModelerTests()
|
||||
{
|
||||
Directory.SetCurrentDirectory( Core.Utilities.Extensions.CodeBaseDirectory );
|
||||
Directory.SetCurrentDirectory(Core.Utilities.Extensions.CodeBaseDirectory);
|
||||
}
|
||||
|
||||
private string CreateCSharpDeclarationString(Parameter parameter)
|
||||
|
@ -249,6 +249,32 @@ namespace AutoRest.Swagger.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestcodeModelWithXmsDiscriminatorValue()
|
||||
{
|
||||
using (NewContext)
|
||||
{
|
||||
new Settings
|
||||
{
|
||||
Namespace = "Test",
|
||||
Input = Path.Combine(Core.Utilities.Extensions.CodeBaseDirectory, "Resource", "Swagger", "swagger-x-ms-discriminator-value.json")
|
||||
};
|
||||
var modeler = new SwaggerModeler();
|
||||
var codeModel = modeler.Build();
|
||||
|
||||
Assert.NotNull(codeModel);
|
||||
Assert.Equal("Pet", codeModel.ModelTypes.First(m => m.Name == "Pet").Name);
|
||||
Assert.Equal("Microsoft.Models.MSPet", codeModel.ModelTypes.First(m => m.Name == "Pet").Extensions["x-ms-discriminator-value"]);
|
||||
Assert.Equal("type", codeModel.ModelTypes.First(m => m.Name == "Pet").PolymorphicDiscriminator);
|
||||
Assert.Equal(true, codeModel.ModelTypes.First(m => m.Name == "Pet").IsPolymorphic);
|
||||
Assert.Equal(true, codeModel.ModelTypes.First(m => m.Name == "Pet").BaseIsPolymorphic);
|
||||
Assert.Equal("Cat", codeModel.ModelTypes.First(m => m.Name == "Cat").Name);
|
||||
Assert.Equal("Microsoft.Models.MSCat", codeModel.ModelTypes.First(m => m.Name == "Cat").Extensions["x-ms-discriminator-value"]);
|
||||
Assert.Equal(true, codeModel.ModelTypes.First(m => m.Name == "Cat").BaseIsPolymorphic);
|
||||
Assert.Equal("Pet", codeModel.ModelTypes.First(m => m.Name == "Cat").BaseModelType.Name);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestcodeModelPolymorhism()
|
||||
{
|
||||
|
@ -530,12 +556,12 @@ namespace AutoRest.Swagger.Tests
|
|||
Assert.Equal("IList<String> array", CreateCSharpDeclarationString(codeModel.Methods[0].Parameters[14]));
|
||||
|
||||
var variableEnumInPath =
|
||||
codeModel.Methods.First(m => m.Name == "List" && m.Group .IsNullOrEmpty())
|
||||
codeModel.Methods.First(m => m.Name == "List" && m.Group.IsNullOrEmpty())
|
||||
.Parameters.First(p => p.Name == "color" && p.Location == ParameterLocation.Path)
|
||||
.ModelType as EnumType;
|
||||
Assert.NotNull(variableEnumInPath);
|
||||
Assert.Equal(variableEnumInPath.Values,
|
||||
new[] {new EnumValue {Name = "red"}, new EnumValue {Name = "blue"}, new EnumValue {Name = "green"}}
|
||||
new[] { new EnumValue { Name = "red" }, new EnumValue { Name = "blue" }, new EnumValue { Name = "green" } }
|
||||
.ToList());
|
||||
Assert.True(variableEnumInPath.ModelAsString);
|
||||
Assert.Empty(variableEnumInPath.Name.RawValue);
|
||||
|
@ -560,7 +586,7 @@ namespace AutoRest.Swagger.Tests
|
|||
.ModelType as EnumType;
|
||||
Assert.NotNull(differentEnum);
|
||||
Assert.Equal(differentEnum.Values,
|
||||
new[] {new EnumValue {Name = "cyan"}, new EnumValue {Name = "yellow"}}.ToList());
|
||||
new[] { new EnumValue { Name = "cyan" }, new EnumValue { Name = "yellow" } }.ToList());
|
||||
Assert.True(differentEnum.ModelAsString);
|
||||
Assert.Empty(differentEnum.Name.RawValue);
|
||||
|
||||
|
@ -570,7 +596,7 @@ namespace AutoRest.Swagger.Tests
|
|||
.ModelType as EnumType;
|
||||
Assert.NotNull(sameEnum);
|
||||
Assert.Equal(sameEnum.Values,
|
||||
new[] {new EnumValue {Name = "blue"}, new EnumValue {Name = "green"}, new EnumValue {Name = "red"}}
|
||||
new[] { new EnumValue { Name = "blue" }, new EnumValue { Name = "green" }, new EnumValue { Name = "red" } }
|
||||
.ToList());
|
||||
Assert.True(sameEnum.ModelAsString);
|
||||
Assert.Empty(sameEnum.Name.RawValue);
|
||||
|
@ -581,7 +607,7 @@ namespace AutoRest.Swagger.Tests
|
|||
.ModelType as EnumType;
|
||||
Assert.NotNull(modelEnum);
|
||||
Assert.Equal(modelEnum.Values,
|
||||
new[] {new EnumValue {Name = "red"}, new EnumValue {Name = "blue"}, new EnumValue {Name = "green"}}
|
||||
new[] { new EnumValue { Name = "red" }, new EnumValue { Name = "blue" }, new EnumValue { Name = "green" } }
|
||||
.ToList());
|
||||
Assert.True(modelEnum.ModelAsString);
|
||||
Assert.Empty(modelEnum.Name.RawValue);
|
||||
|
@ -592,7 +618,7 @@ namespace AutoRest.Swagger.Tests
|
|||
.ModelType as EnumType;
|
||||
Assert.NotNull(fixedEnum);
|
||||
Assert.Equal(fixedEnum.Values,
|
||||
new[] {new EnumValue {Name = "red"}, new EnumValue {Name = "blue"}, new EnumValue {Name = "green"}}
|
||||
new[] { new EnumValue { Name = "red" }, new EnumValue { Name = "blue" }, new EnumValue { Name = "green" } }
|
||||
.ToList());
|
||||
Assert.False(fixedEnum.ModelAsString);
|
||||
Assert.Equal("Colors", fixedEnum.Name);
|
||||
|
@ -609,7 +635,7 @@ namespace AutoRest.Swagger.Tests
|
|||
.ModelType as EnumType;
|
||||
Assert.NotNull(refEnum);
|
||||
Assert.Equal(refEnum.Values,
|
||||
new[] {new EnumValue {Name = "red"}, new EnumValue {Name = "green"}, new EnumValue {Name = "blue"}}
|
||||
new[] { new EnumValue { Name = "red" }, new EnumValue { Name = "green" }, new EnumValue { Name = "blue" } }
|
||||
.ToList());
|
||||
Assert.True(refEnum.ModelAsString);
|
||||
Assert.Equal("RefColors", refEnum.Name);
|
||||
|
@ -688,7 +714,7 @@ namespace AutoRest.Swagger.Tests
|
|||
Assert.Equal("100", codeModel.ModelTypes.First(m => m.Name == "Product").Properties[3].Constraints[Constraint.ExclusiveMaximum]);
|
||||
Assert.Equal("0", codeModel.ModelTypes.First(m => m.Name == "Product").Properties[3].Constraints[Constraint.ExclusiveMinimum]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestConstants()
|
||||
|
@ -766,7 +792,7 @@ namespace AutoRest.Swagger.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Fact]
|
||||
public void TestcodeModelWithResponseHeaders()
|
||||
{
|
||||
using (NewContext)
|
||||
|
@ -783,22 +809,22 @@ namespace AutoRest.Swagger.Tests
|
|||
Assert.Equal(2, codeModel.Methods.Count);
|
||||
Assert.Equal(2, codeModel.Methods[0].Responses.Count);
|
||||
Assert.Equal("ListHeaders", codeModel.Methods[0].Responses[HttpStatusCode.OK].Headers.Name);
|
||||
Assert.Equal(3,((CompositeType) codeModel.Methods[0].Responses[HttpStatusCode.OK].Headers).Properties.Count);
|
||||
Assert.Equal(3, ((CompositeType)codeModel.Methods[0].Responses[HttpStatusCode.OK].Headers).Properties.Count);
|
||||
Assert.Equal("ListHeaders", codeModel.Methods[0].Responses[HttpStatusCode.Created].Headers.Name);
|
||||
Assert.Equal(3,((CompositeType) codeModel.Methods[0].Responses[HttpStatusCode.Created].Headers).Properties.Count);
|
||||
Assert.Equal(3, ((CompositeType)codeModel.Methods[0].Responses[HttpStatusCode.Created].Headers).Properties.Count);
|
||||
Assert.Equal("ListHeaders", codeModel.Methods[0].ReturnType.Headers.Name);
|
||||
Assert.Equal(3, ((CompositeType) codeModel.Methods[0].ReturnType.Headers).Properties.Count);
|
||||
Assert.Equal(3, ((CompositeType)codeModel.Methods[0].ReturnType.Headers).Properties.Count);
|
||||
|
||||
Assert.Equal(1, codeModel.Methods[1].Responses.Count);
|
||||
Assert.Equal("CreateHeaders", codeModel.Methods[1].Responses[HttpStatusCode.OK].Headers.Name);
|
||||
Assert.Equal(3,((CompositeType) codeModel.Methods[1].Responses[HttpStatusCode.OK].Headers).Properties.Count);
|
||||
Assert.Equal(3, ((CompositeType)codeModel.Methods[1].Responses[HttpStatusCode.OK].Headers).Properties.Count);
|
||||
Assert.Equal("CreateHeaders", codeModel.Methods[1].ReturnType.Headers.Name);
|
||||
Assert.Equal(3, ((CompositeType) codeModel.Methods[1].ReturnType.Headers).Properties.Count);
|
||||
Assert.Equal(3, ((CompositeType)codeModel.Methods[1].ReturnType.Headers).Properties.Count);
|
||||
Assert.True(codeModel.HeaderTypes.Any(c => c.Name == "ListHeaders"));
|
||||
Assert.True(codeModel.HeaderTypes.Any(c => c.Name == "CreateHeaders"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void TestCustomPaths()
|
||||
{
|
||||
|
|
|
@ -166,20 +166,20 @@ namespace AutoRest.Swagger
|
|||
// Copy over extensions
|
||||
_schema.Extensions.ForEach(e => objectType.Extensions[e.Key] = e.Value);
|
||||
|
||||
// Optionally override the discriminator value for polymorphic types. We expect this concept to be
|
||||
// added to Swagger at some point, but until it is, we use an extension.
|
||||
object discriminatorValueExtension;
|
||||
if (objectType.Extensions.TryGetValue(DiscriminatorValueExtension, out discriminatorValueExtension))
|
||||
{
|
||||
string discriminatorValue = discriminatorValueExtension as string;
|
||||
if (discriminatorValue != null)
|
||||
{
|
||||
objectType.SerializedName = discriminatorValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (_schema.Extends != null)
|
||||
{
|
||||
// Optionally override the discriminator value for polymorphic types. We expect this concept to be
|
||||
// added to Swagger at some point, but until it is, we use an extension.
|
||||
object discriminatorValueExtension;
|
||||
if (objectType.Extensions.TryGetValue(DiscriminatorValueExtension, out discriminatorValueExtension))
|
||||
{
|
||||
string discriminatorValue = discriminatorValueExtension as string;
|
||||
if (discriminatorValue != null)
|
||||
{
|
||||
objectType.SerializedName = discriminatorValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Put this in the extended type serializationProperty for building method return type in the end
|
||||
Modeler.ExtendedTypes[serviceTypeName] = _schema.Extends.StripDefinitionPath();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче