From 1646fefd561d8476361758f6aaaeb570885f23a1 Mon Sep 17 00:00:00 2001 From: ctytgat Date: Fri, 1 Dec 2017 12:31:12 +0100 Subject: [PATCH] Fix crash on empty tables (#293) * https://github.com/Swagger2Markup/swagger2markup-cli/issues/17 * https://github.com/Swagger2Markup/swagger2markup-cli/issues/17 add test case --- .../component/DefinitionComponent.java | 14 +- .../SecuritySchemeDefinitionComponent.java | 28 ++-- .../swagger2markup/AsciidocConverterTest.java | 24 ++++ .../asciidoc/empty_tables/definitions.adoc | 44 +++++++ .../asciidoc/empty_tables/overview.adoc | 42 ++++++ .../expected/asciidoc/empty_tables/paths.adoc | 48 +++++++ .../asciidoc/empty_tables/security.adoc | 21 +++ .../resources/json/swagger_empty_tables.json | 122 ++++++++++++++++++ 8 files changed, 327 insertions(+), 16 deletions(-) create mode 100644 src/test/resources/expected/asciidoc/empty_tables/definitions.adoc create mode 100644 src/test/resources/expected/asciidoc/empty_tables/overview.adoc create mode 100644 src/test/resources/expected/asciidoc/empty_tables/paths.adoc create mode 100644 src/test/resources/expected/asciidoc/empty_tables/security.adoc create mode 100644 src/test/resources/json/swagger_empty_tables.json diff --git a/src/main/java/io/github/swagger2markup/internal/component/DefinitionComponent.java b/src/main/java/io/github/swagger2markup/internal/component/DefinitionComponent.java index ea2f6394..ca907639 100644 --- a/src/main/java/io/github/swagger2markup/internal/component/DefinitionComponent.java +++ b/src/main/java/io/github/swagger2markup/internal/component/DefinitionComponent.java @@ -26,6 +26,7 @@ import io.github.swagger2markup.spi.DefinitionsDocumentExtension; import io.github.swagger2markup.spi.MarkupComponent; import io.swagger.models.Model; +import io.swagger.models.properties.Property; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.Validate; @@ -157,11 +158,14 @@ private List typeSection(MarkupDocBuilder markupDocBuilder, String d if (isNotBlank(typeInfosString)) markupDocBuilder.paragraph(typeInfosString, true); - propertiesTableComponent.apply(markupDocBuilder, - PropertiesTableComponent.parameters( - ((ObjectType) modelType).getProperties(), - definitionName, - inlineDefinitions)); + Map properties = ((ObjectType) modelType).getProperties(); + if (!properties.isEmpty()) { + propertiesTableComponent.apply(markupDocBuilder, + PropertiesTableComponent.parameters( + properties, + definitionName, + inlineDefinitions)); + } } else if (modelType != null) { MarkupDocBuilder typeInfos = copyMarkupDocBuilder(markupDocBuilder); typeInfos.italicText(labels.getLabel(TYPE_COLUMN)).textLine(COLON + modelType.displaySchema(markupDocBuilder)); diff --git a/src/main/java/io/github/swagger2markup/internal/component/SecuritySchemeDefinitionComponent.java b/src/main/java/io/github/swagger2markup/internal/component/SecuritySchemeDefinitionComponent.java index c29ad318..9b98c30e 100644 --- a/src/main/java/io/github/swagger2markup/internal/component/SecuritySchemeDefinitionComponent.java +++ b/src/main/java/io/github/swagger2markup/internal/component/SecuritySchemeDefinitionComponent.java @@ -88,23 +88,29 @@ private MarkupDocBuilder buildSecurityScheme(MarkupDocBuilder markupDocBuilder, if (isNotBlank(oauth2Scheme.getTokenUrl())) { paragraphBuilder.italicText(labels.getLabel(TOKEN_URL)).textLine(COLON + oauth2Scheme.getTokenUrl()); } - StringColumn.Builder nameColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(NAME_COLUMN))) - .putMetaData(TableComponent.WIDTH_RATIO, "3") - .putMetaData(TableComponent.HEADER_COLUMN, "true"); - StringColumn.Builder descriptionColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(DESCRIPTION_COLUMN))) - .putMetaData(TableComponent.WIDTH_RATIO, "17") - .putMetaData(TableComponent.HEADER_COLUMN, "true"); - - if (oauth2Scheme.getScopes() != null) { + + markupDocBuilder.paragraph(paragraphBuilder.toString(), true); + + if (oauth2Scheme.getScopes() != null && !oauth2Scheme.getScopes().isEmpty()) { + StringColumn.Builder nameColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(NAME_COLUMN))) + .putMetaData(TableComponent.WIDTH_RATIO, "3") + .putMetaData(TableComponent.HEADER_COLUMN, "true"); + StringColumn.Builder descriptionColumnBuilder = StringColumn.builder(StringColumnId.of(labels.getLabel(DESCRIPTION_COLUMN))) + .putMetaData(TableComponent.WIDTH_RATIO, "17") + .putMetaData(TableComponent.HEADER_COLUMN, "true"); + for (Map.Entry scope : oauth2Scheme.getScopes().entrySet()) { nameColumnBuilder.add(scope.getKey()); descriptionColumnBuilder.add(scope.getValue()); } + + return tableComponent.apply(markupDocBuilder, TableComponent.parameters(nameColumnBuilder.build(), + descriptionColumnBuilder.build())); + } else { + + return markupDocBuilder; } - markupDocBuilder.paragraph(paragraphBuilder.toString(), true); - return tableComponent.apply(markupDocBuilder, TableComponent.parameters(nameColumnBuilder.build(), - descriptionColumnBuilder.build())); } else { return markupDocBuilder.paragraph(paragraphBuilder.toString(), true); } diff --git a/src/test/java/io/github/swagger2markup/AsciidocConverterTest.java b/src/test/java/io/github/swagger2markup/AsciidocConverterTest.java index 9df0e656..4abd97d5 100644 --- a/src/test/java/io/github/swagger2markup/AsciidocConverterTest.java +++ b/src/test/java/io/github/swagger2markup/AsciidocConverterTest.java @@ -805,4 +805,28 @@ public void testWithPageBreaks() throws IOException, URISyntaxException { Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/page_breaks").toURI()); DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithPageBreaks.html"); } + + @Test + public void testWithEmptyTables() throws IOException, URISyntaxException { + //Given + String swaggerJsonString = IOUtils.toString(getClass().getResourceAsStream("/json/swagger_empty_tables.json")); + Path outputDirectory = Paths.get("build/test/asciidoc/empty_tables"); + FileUtils.deleteQuietly(outputDirectory.toFile()); + + //When + Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() + .withPageBreaks(new ArrayList<>(asList(PageBreakLocations.BEFORE_OPERATION, PageBreakLocations.BEFORE_OPERATION_EXAMPLE_REQUEST))) + .build(); + + Swagger2MarkupConverter.from(swaggerJsonString) + .withConfig(config) + .build() + .toFolder(outputDirectory); + + //Then + String[] files = outputDirectory.toFile().list(); + assertThat(files).hasSize(4).containsAll(expectedFiles); + Path expectedFilesDirectory = Paths.get(AsciidocConverterTest.class.getResource("/expected/asciidoc/empty_tables").toURI()); + DiffUtils.assertThatAllFilesAreEqual(expectedFilesDirectory, outputDirectory, "testWithEmptyTables.html"); + } } diff --git a/src/test/resources/expected/asciidoc/empty_tables/definitions.adoc b/src/test/resources/expected/asciidoc/empty_tables/definitions.adoc new file mode 100644 index 00000000..1cac81a0 --- /dev/null +++ b/src/test/resources/expected/asciidoc/empty_tables/definitions.adoc @@ -0,0 +1,44 @@ + +[[_definitions]] +== Definitions + +[[_category]] +=== Category +[%hardbreaks] +__Polymorphism__ : Composition + + +[options="header", cols=".^3a,.^4a"] +|=== +|Name|Schema +|**id** + +__optional__|integer (int64) +|=== + + +[[_identified]] +=== Identified + +[options="header", cols=".^3a,.^4a"] +|=== +|Name|Schema +|**id** + +__optional__|integer (int64) +|=== + + +[[_user]] +=== User +[%hardbreaks] +__Polymorphism__ : Composition + + +[options="header", cols=".^3a,.^4a"] +|=== +|Name|Schema +|**id** + +__optional__|integer (int64) +|=== + + + diff --git a/src/test/resources/expected/asciidoc/empty_tables/overview.adoc b/src/test/resources/expected/asciidoc/empty_tables/overview.adoc new file mode 100644 index 00000000..2038d84c --- /dev/null +++ b/src/test/resources/expected/asciidoc/empty_tables/overview.adoc @@ -0,0 +1,42 @@ += Swagger Petstore API + + +[[_overview]] +== Overview +This is a sample server Petstore server. + +http://swagger.wordnik.com[Learn about Swagger] or join the IRC channel `#swagger` on irc.freenode.net. + +For this sample, you can use the api key `special-key` to test the authorization filters + + +=== Version information +[%hardbreaks] +__Version__ : 1.0.0 + + +=== Contact information +[%hardbreaks] +__Contact__ : apiteam@wordnik.com + + +=== License information +[%hardbreaks] +__License__ : Apache 2.0 +__License URL__ : http://www.apache.org/licenses/LICENSE-2.0.html +__Terms of service__ : http://helloreverb.com/terms/ + + +=== URI scheme +[%hardbreaks] +__Host__ : petstore.swagger.wordnik.com +__BasePath__ : /v2 +__Schemes__ : HTTP + + +=== Tags + +* user : User resource + + + diff --git a/src/test/resources/expected/asciidoc/empty_tables/paths.adoc b/src/test/resources/expected/asciidoc/empty_tables/paths.adoc new file mode 100644 index 00000000..d2e3027a --- /dev/null +++ b/src/test/resources/expected/asciidoc/empty_tables/paths.adoc @@ -0,0 +1,48 @@ + +[[_paths]] +== Paths + +<<< + +[[_createuser]] +=== Create user +.... +POST /users +.... + + +==== Description +This can only be done by the logged in user. + + +==== Parameters + +[options="header", cols=".^2a,.^3a,.^9a,.^4a"] +|=== +|Type|Name|Description|Schema +|**Body**|**body** + +__optional__|Created user object|<<_user,User>> +|=== + + +==== Responses + +[options="header", cols=".^2a,.^14a,.^4a"] +|=== +|HTTP Code|Description|Schema +|**default**|successful operation|No Content +|=== + + +==== Produces + +* `application/json` +* `application/xml` + + +==== Tags + +* user + + + diff --git a/src/test/resources/expected/asciidoc/empty_tables/security.adoc b/src/test/resources/expected/asciidoc/empty_tables/security.adoc new file mode 100644 index 00000000..f2aa5838 --- /dev/null +++ b/src/test/resources/expected/asciidoc/empty_tables/security.adoc @@ -0,0 +1,21 @@ + +[[_securityscheme]] +== Security + +[[_api_key]] +=== api_key +[%hardbreaks] +__Type__ : apiKey +__Name__ : api_key +__In__ : HEADER + + +[[_petstore_auth]] +=== petstore_auth +[%hardbreaks] +__Type__ : oauth2 +__Flow__ : implicit +__Token URL__ : http://petstore.swagger.wordnik.com/api/oauth/dialog + + + diff --git a/src/test/resources/json/swagger_empty_tables.json b/src/test/resources/json/swagger_empty_tables.json new file mode 100644 index 00000000..5d2a978d --- /dev/null +++ b/src/test/resources/json/swagger_empty_tables.json @@ -0,0 +1,122 @@ +{ + "swagger": "2.0", + "info": { + "description": "This is a sample server Petstore server.\n\n[Learn about Swagger](http://swagger.wordnik.com) or join the IRC channel `#swagger` on irc.freenode.net.\n\nFor this sample, you can use the api key `special-key` to test the authorization filters\n", + "version": "1.0.0", + "title": "Swagger Petstore API", + "termsOfService": "http://helloreverb.com/terms/", + "contact": { + "name": "apiteam@wordnik.com" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "host": "petstore.swagger.wordnik.com", + "basePath": "/v2", + "schemes": [ + "http" + ], + "tags": [ + { + "name": "user", + "description": "User resource" + } + ], + "paths": { + "/users": { + "post": { + "tags": [ + "user" + ], + "summary": "Create user", + "description": "This can only be done by the logged in user.", + "operationId": "createUser", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "Created user object", + "required": false, + "schema": { + "$ref": "#/definitions/User" + } + } + ], + "responses": { + "default": { + "description": "successful operation" + } + } + } + } + }, + "securityDefinitions": { + "api_key": { + "type": "apiKey", + "name": "api_key", + "in": "header" + }, + "petstore_auth": { + "type": "oauth2", + "authorizationUrl": "http://petstore.swagger.wordnik.com/api/oauth/dialog", + "flow": "implicit", + "scopes": { + } + } + }, + "responses": { + "FoundPets": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Pet" + } + } + } + }, + "parameters": { + "petId": { + "in": "path", + "name": "petId", + "description": "ID of the pet", + "required": true, + "type": "integer", + "format": "int64" + } + }, + "definitions": { + "Identified": { + "properties": { + "id": { + "type": "integer", + "format": "int64" + } + } + }, + "User": { + "allOf": [ + { + "$ref": "#/definitions/Identified" + }, + { + "properties": { + } + } + ] + }, + "Category": { + "allOf": [ + { + "$ref": "#/definitions/Identified" + } + ] + } + } +} \ No newline at end of file