From 5d1e4baed8291229cc1d771798df048934df344a Mon Sep 17 00:00:00 2001 From: Luis Fernando Planella Gonzalez Date: Wed, 19 Feb 2020 15:56:52 -0300 Subject: [PATCH] Handle multiple similar suffixes as a single one Fixes #64 --- lib/operation.ts | 49 ++++++++++++++++++++----------------- test/all-operations.json | 13 ++++++++++ test/all-operations.spec.ts | 2 +- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/lib/operation.ts b/lib/operation.ts index ae3f11f..c89ed88 100644 --- a/lib/operation.ts +++ b/lib/operation.ts @@ -158,31 +158,36 @@ export class Operation { }); } - private calculateVariants() { - const hasRequestBodyVariants = this.requestBody && this.requestBody.content.length > 1; - const hasResponseVariants = this.successResponse && this.successResponse.content.length > 1; - const contentOrNull = (hasContent?: { content?: Content[] }): (Content | null)[] => { - if (hasContent) { - const content = hasContent.content; - if (content && content.length > 0) { - return content; - } - } - return [null]; - }; - const requestBodyVariants = contentOrNull(this.requestBody); - const successResponseVariants = contentOrNull(this.successResponse); - for (const requestBodyVariant of requestBodyVariants) { - const methodPart = this.methodName + (hasRequestBodyVariants ? this.variantMethodPart(requestBodyVariant) : ''); - for (const successResponseVariant of successResponseVariants) { - const methodName = methodPart + (hasResponseVariants ? this.variantMethodPart(successResponseVariant) : ''); - if (!this.variants.find(v => v.methodName === methodName)) { - // It is possible to have multiple content types which end up in the same method. - // For example: application/json, application/foo-bar+json, text/json ... - this.variants.push(new OperationVariant(this, methodName, requestBodyVariant, successResponseVariant, this.options)); + private contentsByMethodPart(hasContent?: { content?: Content[] }): Map { + const map = new Map(); + if (hasContent) { + const content = hasContent.content; + if (content && content.length > 0) { + for (const type of content) { + if (type && type.mediaType) { + map.set(this.variantMethodPart(type), type); + } } } } + if (map.size < 2) { + map.clear(); + map.set('', null); + } + return map; + } + + private calculateVariants() { + // It is possible to have multiple content types which end up in the same method. + // For example: application/json, application/foo-bar+json, text/json ... + const requestVariants = this.contentsByMethodPart(this.requestBody); + const responseVariants = this.contentsByMethodPart(this.successResponse); + requestVariants.forEach((requestContent, requestPart) => { + responseVariants.forEach((responseContent, responsePart) => { + const methodName = this.methodName + requestPart + responsePart; + this.variants.push(new OperationVariant(this, methodName, requestContent, responseContent, this.options)); + }); + }); } /** diff --git a/test/all-operations.json b/test/all-operations.json index 493a4f6..cae0aaf 100644 --- a/test/all-operations.json +++ b/test/all-operations.json @@ -94,6 +94,11 @@ "$ref": "#/components/schemas/RefObject" } }, + "application/dummy+json": { + "schema": { + "$ref": "#/components/schemas/RefObject" + } + }, "image/*": { "schema": { "type": "string", @@ -197,6 +202,14 @@ "type": "string" } } + }, + "application/*+json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } } } } diff --git a/test/all-operations.spec.ts b/test/all-operations.spec.ts index 3282d02..4806d01 100644 --- a/test/all-operations.spec.ts +++ b/test/all-operations.spec.ts @@ -182,7 +182,7 @@ describe('Generation tests using all-operations.json', () => { expect(success).toBeDefined(); if (success) { expect(success.statusCode).toBe('200'); - expect(success.content.length).toBe(2); + expect(success.content.length).toBe(3); const json = success.content.find(c => c.mediaType === 'application/json'); expect(json).toBeDefined(); if (json) {