From ca6b1f9ae39a96ebaa5d427bcc6329fbeef818d7 Mon Sep 17 00:00:00 2001 From: kumagoro_alice Date: Tue, 21 Feb 2017 20:48:36 +0900 Subject: [PATCH 1/3] fix: Fix condition --- src/expand-uri-template-with-parameters.coffee | 6 +++--- src/validate-parameters.coffee | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/expand-uri-template-with-parameters.coffee b/src/expand-uri-template-with-parameters.coffee index be4233a..4f7c495 100644 --- a/src/expand-uri-template-with-parameters.coffee +++ b/src/expand-uri-template-with-parameters.coffee @@ -41,9 +41,9 @@ expandUriTemplateWithParameters = (uriTemplate, parameters) -> for uriParameter in uriParameters param = parameters[uriParameter] - if param.example + if param.example? and param.example isnt '' toExpand[uriParameter] = param.example - else if param.default + else if param.default? and param.default isnt '' toExpand[uriParameter] = param.default else if param.required @@ -54,7 +54,7 @@ expandUriTemplateWithParameters = (uriTemplate, parameters) -> document: #{uriParameter}\ """) - if param.required and param.default + if param.required and param.default? and param.default isnt '' result.warnings.push("""\ Required URI parameter '#{uriParameter}' has a default value. Default value for a required parameter doesn't make sense from \ diff --git a/src/validate-parameters.coffee b/src/validate-parameters.coffee index 222f54e..e8e90f0 100644 --- a/src/validate-parameters.coffee +++ b/src/validate-parameters.coffee @@ -3,7 +3,7 @@ validateParameters = (params) -> result = {warnings: [], errors: []} for paramName, param of params - if param.required and not param.example and not param.default + if param.required and (not param.example? or param.example is '') and (not param.default? or param.default is '') text = "Required URI parameter '#{paramName}' has no example or default value." result.errors.push(text) From c06faaa918833bd4833dab6d6cc2b8cf6055a2c8 Mon Sep 17 00:00:00 2001 From: kumagoro_alice Date: Tue, 21 Feb 2017 21:31:31 +0900 Subject: [PATCH 2/3] test: Add test case --- .../default-required-boolean.apib | 12 +++++ test/fixtures/index.coffee | 4 ++ .../swagger/default-required-boolean.yml | 40 +++++++++++++++++ test/integration/compile-test.coffee | 19 ++++++++ ...d-uri-template-with-parameters-test.coffee | 45 +++++++++++++++++++ test/unit/validate-parameters-test.coffee | 28 ++++++++++++ 6 files changed, 148 insertions(+) create mode 100644 test/fixtures/api-blueprint/default-required-boolean.apib create mode 100644 test/fixtures/swagger/default-required-boolean.yml diff --git a/test/fixtures/api-blueprint/default-required-boolean.apib b/test/fixtures/api-blueprint/default-required-boolean.apib new file mode 100644 index 0000000..3931b03 --- /dev/null +++ b/test/fixtures/api-blueprint/default-required-boolean.apib @@ -0,0 +1,12 @@ +FORMAT: 1A + +# Beehive API + +## Honey [/honey{?exampleBool}] + +### Get [GET] + ++ Parameters + + exampleBool: `false` (required, boolean) + ++ Response 200 diff --git a/test/fixtures/index.coffee b/test/fixtures/index.coffee index 16bca29..b2ef8e2 100644 --- a/test/fixtures/index.coffee +++ b/test/fixtures/index.coffee @@ -119,6 +119,10 @@ fixtures = apiBlueprint: fromFile('./api-blueprint/example-parameter.apib') swagger: fromFile('./swagger/example-parameter.yml') ) + defaultRequiredBoolean: fixture( + apiBlueprint: fromFile('./api-blueprint/default-required-boolean.apib') + swagger: fromFile('./swagger/default-required-boolean.yml') + ) # Specific to API Blueprint unrecognizable: fixture( diff --git a/test/fixtures/swagger/default-required-boolean.yml b/test/fixtures/swagger/default-required-boolean.yml new file mode 100644 index 0000000..354b193 --- /dev/null +++ b/test/fixtures/swagger/default-required-boolean.yml @@ -0,0 +1,40 @@ +swagger: "2.0" +info: + version: "1.0" + title: Beehive API + description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification +host: petstore.swagger.io +basePath: / +schemes: + - http +consumes: + - application/json +produces: + - application/json +paths: + /honey: + get: + parameters: + - name: exampleBool + in: query + type: boolean + required: true + default: 'false' + responses: + 200: + description: Sample description + schema: + $ref: '#/definitions/Pet' +definitions: + Pet: + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string diff --git a/test/integration/compile-test.coffee b/test/integration/compile-test.coffee index 6b07f9b..8522eab 100644 --- a/test/integration/compile-test.coffee +++ b/test/integration/compile-test.coffee @@ -505,4 +505,23 @@ describe('compile() ยท all API description formats', -> ) ) ) + + describe('with example boolean value of URI parameter', -> + transaction = undefined + errors = undefined + + fixtures.defaultRequiredBoolean.forEachDescribe(({source}) -> + beforeEach((done) -> + compileFixture(source, (args...) -> + [err, compilationResult] = args + transaction = compilationResult.transactions[0] + done(err) + ) + ) + it('expands the request URI with the example value', -> + assert.equal(transaction.request.uri, '/honey?exampleBool=false') + ) + ) + ) + ) diff --git a/test/unit/expand-uri-template-with-parameters-test.coffee b/test/unit/expand-uri-template-with-parameters-test.coffee index e501c14..02a8797 100644 --- a/test/unit/expand-uri-template-with-parameters-test.coffee +++ b/test/unit/expand-uri-template-with-parameters-test.coffee @@ -355,3 +355,48 @@ describe 'expandUriTemplateWithParameters', -> it 'should return some URI', -> assert.isNotNull data['uri'] + + + describe 'when example value are not given', -> + before -> + uriTemplate = '/machines/{name}' + parameters = + name: + description: 'Machine name' + type: 'boolean' + required: true + default: false + example: '' + + data = expandUriTemplateWithParameters uriTemplate, parameters + + it 'should return no error', -> + assert.equal data['errors'].length, 0 + + it 'should return 1 warning', -> + assert.equal data['warnings'].length, 1 + + it 'should return some URI', -> + assert.isNotNull data['uri'] + + describe 'when default values are not given', -> + before -> + uriTemplate = '/machines/{name}' + parameters = + name: + description: 'Machine name' + type: 'boolean' + required: true + default: '' + example: false + + data = expandUriTemplateWithParameters uriTemplate, parameters + + it 'should return no error', -> + assert.equal data['errors'].length, 0 + + it 'should return no warning', -> + assert.equal data['warnings'].length, 0 + + it 'should return some URI', -> + assert.isNotNull data['uri'] diff --git a/test/unit/validate-parameters-test.coffee b/test/unit/validate-parameters-test.coffee index d3d6572..3b2a576 100644 --- a/test/unit/validate-parameters-test.coffee +++ b/test/unit/validate-parameters-test.coffee @@ -248,3 +248,31 @@ describe 'validateParameters', -> result = validateParameters params assert.equal result['errors'].length, 0 + + describe 'when type is boolean and example value is false', () -> + it 'should not set the error', () -> + params = + name: + description: 'Machine name' + type: 'boolean' + required: true + example: 'false' + default: '' + values: [] + + result = validateParameters params + assert.equal result['errors'].length, 0 + + describe 'when type is boolean and default value is parseable bool and example value is empty', () -> + it 'should not set the error', () -> + params = + name: + description: 'Machine name' + type: 'boolean' + required: true + example: '' + default: 'false' + values: [] + + result = validateParameters params + assert.equal result['errors'].length, 1 From 7033557635538b7570cf1518cbf48e632bf60bd3 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Thu, 18 May 2017 15:43:02 +0200 Subject: [PATCH 3/3] fix: Treat empty strings as valid values for URI params BREAKING CHANGE: Empty strings are now treated as valid values for URI parameters. --- ...expand-uri-template-with-parameters.coffee | 6 +- src/validate-parameters.coffee | 16 +- ...d-uri-template-with-parameters-test.coffee | 139 +++++++++++++++--- test/unit/validate-parameters-test.coffee | 132 ++++++++++++++--- 4 files changed, 246 insertions(+), 47 deletions(-) diff --git a/src/expand-uri-template-with-parameters.coffee b/src/expand-uri-template-with-parameters.coffee index 4f7c495..25deb48 100644 --- a/src/expand-uri-template-with-parameters.coffee +++ b/src/expand-uri-template-with-parameters.coffee @@ -41,9 +41,9 @@ expandUriTemplateWithParameters = (uriTemplate, parameters) -> for uriParameter in uriParameters param = parameters[uriParameter] - if param.example? and param.example isnt '' + if param.example? toExpand[uriParameter] = param.example - else if param.default? and param.default isnt '' + else if param.default? toExpand[uriParameter] = param.default else if param.required @@ -54,7 +54,7 @@ expandUriTemplateWithParameters = (uriTemplate, parameters) -> document: #{uriParameter}\ """) - if param.required and param.default? and param.default isnt '' + if param.required and param.default? result.warnings.push("""\ Required URI parameter '#{uriParameter}' has a default value. Default value for a required parameter doesn't make sense from \ diff --git a/src/validate-parameters.coffee b/src/validate-parameters.coffee index e8e90f0..1553b3a 100644 --- a/src/validate-parameters.coffee +++ b/src/validate-parameters.coffee @@ -3,18 +3,24 @@ validateParameters = (params) -> result = {warnings: [], errors: []} for paramName, param of params - if param.required and (not param.example? or param.example is '') and (not param.default? or param.default is '') + if param.required and not (param.example? or param.default?) text = "Required URI parameter '#{paramName}' has no example or default value." result.errors.push(text) switch param.type when 'number' - if isNaN(parseFloat(param.example)) - text = "URI parameter '#{paramName}' is declared as 'number' but it is a string." + if param.example? and isNaN(parseFloat(param.example)) + text = "URI parameter '#{paramName}' is declared as 'number' but its example value '#{param.example}' is not." + result.errors.push(text) + if param.default? and isNaN(parseFloat(param.default)) + text = "URI parameter '#{paramName}' is declared as 'number' but its default value '#{param.example}' is not." result.errors.push(text) when 'boolean' - if param.example isnt 'true' and param.example isnt 'false' - text = "URI parameter '#{paramName}' is declared as 'boolean' but it is not." + if param.example? and param.example isnt 'true' and param.example isnt 'false' + text = "URI parameter '#{paramName}' is declared as 'boolean' but its example value '#{param.example}' is not." + result.errors.push(text) + if param.default? and param.default isnt 'true' and param.default isnt 'false' + text = "URI parameter '#{paramName}' is declared as 'boolean' but its default value '#{param.example}' is not." result.errors.push(text) if param.values.length > 0 diff --git a/test/unit/expand-uri-template-with-parameters-test.coffee b/test/unit/expand-uri-template-with-parameters-test.coffee index 02a8797..c234800 100644 --- a/test/unit/expand-uri-template-with-parameters-test.coffee +++ b/test/unit/expand-uri-template-with-parameters-test.coffee @@ -15,14 +15,14 @@ describe 'expandUriTemplateWithParameters', -> type: 'string' required: true example: 'waldo' - default: '' + default: null data = expandUriTemplateWithParameters uriTemplate, parameters it 'should return an object', -> assert.isObject data - describe 'returned obejct', -> + describe 'returned object', -> [ 'errors' 'warnings' @@ -40,7 +40,7 @@ describe 'expandUriTemplateWithParameters', -> type: 'string' required: true example: 'waldo' - default: '' + default: null data = expandUriTemplateWithParameters uriTemplate, parameters @@ -74,7 +74,7 @@ describe 'expandUriTemplateWithParameters', -> type: 'string' required: true example: 'waldo' - default: '' + default: null data = expandUriTemplateWithParameters uriTemplate, parameters @@ -124,14 +124,14 @@ describe 'expandUriTemplateWithParameters', -> type: 'string' required: true example: 'waldo' - default: '' + default: null fanny: required: false description: 'Machine fanny' type: 'string' required: true example: 'wild' - default: '' + default: null data = expandUriTemplateWithParameters uriTemplate, parameters @@ -155,8 +155,8 @@ describe 'expandUriTemplateWithParameters', -> description: 'Machine name' type: 'string' required: true - example: '' - default: '' + example: null + default: null data = expandUriTemplateWithParameters uriTemplate, parameters @@ -187,7 +187,7 @@ describe 'expandUriTemplateWithParameters', -> type: 'string' required: true example: 'example-one' - default: '' + default: null data = expandUriTemplateWithParameters uriTemplate, parameters @@ -203,7 +203,7 @@ describe 'expandUriTemplateWithParameters', -> it 'should return URI', -> assert.isNotNull data['uri'] - describe 'when default value is given', -> + describe 'when example value is given as empty string', -> before -> uriTemplate = '/machines/{name}' parameters = @@ -212,6 +212,31 @@ describe 'expandUriTemplateWithParameters', -> type: 'string' required: true example: '' + default: null + + data = expandUriTemplateWithParameters uriTemplate, parameters + + it 'should return no error', -> + assert.equal data['errors'].length, 0 + + it 'should return no warning', -> + assert.equal data['warnings'].length, 0 + + it 'should use example value to URI parameter expansion', -> + assert.include data['uri'], parameters['name']['example'] + + it 'should return URI', -> + assert.isNotNull data['uri'] + + describe 'when default value is given', -> + before -> + uriTemplate = '/machines/{name}' + parameters = + name: + description: 'Machine name' + type: 'string' + required: true + example: null default: 'example-one' data = expandUriTemplateWithParameters uriTemplate, parameters @@ -231,6 +256,31 @@ describe 'expandUriTemplateWithParameters', -> it 'should return URI', -> assert.isNotNull data['uri'] + describe 'when default value is given as empty string', -> + before -> + uriTemplate = '/machines/{name}' + parameters = + name: + description: 'Machine name' + type: 'string' + required: true + example: null + default: '' + + data = expandUriTemplateWithParameters uriTemplate, parameters + + it 'should return no error', -> + assert.equal data['errors'].length, 0 + + it 'should return warning about pointlessness of default value of a required parameter', -> + assert.include data.warnings[0], 'Default value for a required parameter' + + it 'should use default value to URI parameter expansion', -> + assert.include data['uri'], parameters['name']['default'] + + it 'should return URI', -> + assert.isNotNull data['uri'] + describe 'when example and default values are given', -> before -> uriTemplate = '/machines/{name}' @@ -259,6 +309,34 @@ describe 'expandUriTemplateWithParameters', -> it 'should return URI', -> assert.isNotNull data['uri'] + describe 'when example is given as empty string and default is given as non-empty string', -> + before -> + uriTemplate = '/machines/{name}' + parameters = + name: + description: 'Machine name' + type: 'string' + required: true + example: '' + default: 'default-one' + + data = expandUriTemplateWithParameters uriTemplate, parameters + + it 'should return no error', -> + assert.equal data['errors'].length, 0 + + it 'should return one warning', -> + assert.equal data['warnings'].length, 1 + + it 'should return warning about pointlessness of default value of a required parameter', -> + assert.include data.warnings[0], 'Default value for a required parameter' + + it 'should use example value to URI parameter expansion', -> + assert.include data['uri'], parameters['name']['example'] + + it 'should return URI', -> + assert.isNotNull data['uri'] + describe 'when expression parameter is optional', -> before -> uriTemplate = '/machines/{name}' @@ -268,7 +346,7 @@ describe 'expandUriTemplateWithParameters', -> type: 'string' required: false example: 'example-one' - default: '' + default: null data = expandUriTemplateWithParameters uriTemplate, parameters @@ -293,7 +371,7 @@ describe 'expandUriTemplateWithParameters', -> type: 'string' required: false default: 'default-one' - example: '' + example: null data = expandUriTemplateWithParameters uriTemplate, parameters @@ -309,6 +387,31 @@ describe 'expandUriTemplateWithParameters', -> it 'should return URI', -> assert.isNotNull data['uri'] + describe 'when default value is given and example is empty string', -> + before -> + uriTemplate = '/machines/{name}' + parameters = + name: + description: 'Machine name' + type: 'string' + required: false + default: 'default-one' + example: '' + + data = expandUriTemplateWithParameters uriTemplate, parameters + + it 'should return no error', -> + assert.equal data['errors'].length, 0 + + it 'should return no warning', -> + assert.equal data['warnings'].length, 0 + + it 'should use example value to URI parameter expansion', -> + assert.include data['uri'], parameters['name']['example'] + + it 'should return URI', -> + assert.isNotNull data['uri'] + describe 'when example and default values are given', -> before -> uriTemplate = '/machines/{name}' @@ -342,8 +445,8 @@ describe 'expandUriTemplateWithParameters', -> description: 'Machine name' type: 'string' required: false - default: '' - example: '' + default: null + example: null data = expandUriTemplateWithParameters uriTemplate, parameters @@ -357,7 +460,7 @@ describe 'expandUriTemplateWithParameters', -> assert.isNotNull data['uri'] - describe 'when example value are not given', -> + describe 'when boolean example value is not given', -> before -> uriTemplate = '/machines/{name}' parameters = @@ -366,7 +469,7 @@ describe 'expandUriTemplateWithParameters', -> type: 'boolean' required: true default: false - example: '' + example: null data = expandUriTemplateWithParameters uriTemplate, parameters @@ -379,7 +482,7 @@ describe 'expandUriTemplateWithParameters', -> it 'should return some URI', -> assert.isNotNull data['uri'] - describe 'when default values are not given', -> + describe 'when boolean default value is not given', -> before -> uriTemplate = '/machines/{name}' parameters = @@ -387,7 +490,7 @@ describe 'expandUriTemplateWithParameters', -> description: 'Machine name' type: 'boolean' required: true - default: '' + default: null example: false data = expandUriTemplateWithParameters uriTemplate, parameters diff --git a/test/unit/validate-parameters-test.coffee b/test/unit/validate-parameters-test.coffee index 3b2a576..d982ccd 100644 --- a/test/unit/validate-parameters-test.coffee +++ b/test/unit/validate-parameters-test.coffee @@ -25,7 +25,7 @@ describe 'validateParameters', -> type: 'string' required: true example: '1.1' - default: '' + default: null values: [] result = validateParameters params @@ -42,7 +42,7 @@ describe 'validateParameters', -> type: 'string' required: true example: '6f7c1245' - default: '' + default: null values: [] result = validateParameters params @@ -55,7 +55,7 @@ describe 'validateParameters', -> type: 'string' required: true example: 'waldo' - default: '' + default: null values: [] result = validateParameters params @@ -69,7 +69,7 @@ describe 'validateParameters', -> type: 'number' required: true example: 'waldo' - default: '' + default: null values: [] result = validateParameters params @@ -85,7 +85,7 @@ describe 'validateParameters', -> type: 'number' required: true example: '1.1' - default: '' + default: null values: [] result = validateParameters params @@ -99,7 +99,7 @@ describe 'validateParameters', -> type: 'string' required: true example: 'D' - default: '' + default: null values: [ { "value": "A" }, { "value": "B" }, @@ -119,7 +119,7 @@ describe 'validateParameters', -> type: 'string' required: true example: 'A' - default: '' + default: null values: [ { "value": "A" }, { "value": "B" }, @@ -137,7 +137,7 @@ describe 'validateParameters', -> type: 'boolean' required: true example: 'booboo' - default: '' + default: null values: [] result = validateParameters params @@ -153,15 +153,15 @@ describe 'validateParameters', -> type: 'boolean' required: true example: 'true' - default: '' + default: null values: [] result = validateParameters params assert.equal result['errors'].length, 0 describe 'when parameter is required', () -> - describe 'and example and default value are empty', () -> - it 'should set descirptive error', () -> + describe 'and example and default value are empty strings', () -> + it 'should not set the error', () -> params = name: description: 'Machine name' @@ -171,6 +171,64 @@ describe 'validateParameters', -> default: '' values: [] + result = validateParameters params + assert.equal result['errors'].length, 0 + + describe 'and example is empty string and default value is null', () -> + it 'should not set the error', () -> + params = + name: + description: 'Machine name' + type: 'string' + required: true + example: '' + default: null + values: [] + + result = validateParameters params + assert.equal result['errors'].length, 0 + + describe 'and example is null and default value is empty string', () -> + it 'should not set the error', () -> + params = + name: + description: 'Machine name' + type: 'string' + required: true + example: null + default: '' + values: [] + + result = validateParameters params + assert.equal result['errors'].length, 0 + + describe 'and example and default value are null', () -> + it 'should set descirptive error', () -> + params = + name: + description: 'Machine name' + type: 'string' + required: true + example: null + default: null + values: [] + + result = validateParameters params + message = result['errors'][0] + assert.include message, 'name' + assert.include message, 'Required' + + describe 'and example and default value are undefined', () -> + it 'should set descirptive error', () -> + params = + name: + description: 'Machine name' + type: 'string' + required: true + example: undefined + default: undefined + values: [] + result = validateParameters params message = result['errors'][0] assert.include message, 'name' @@ -183,7 +241,7 @@ describe 'validateParameters', -> description: 'Machine name' type: 'string' required: true - example: '' + example: null default: 'bagaboo' values: [] @@ -198,7 +256,7 @@ describe 'validateParameters', -> type: 'string' required: true example: 'booboo' - default: '' + default: null values: [] result = validateParameters params @@ -206,14 +264,14 @@ describe 'validateParameters', -> describe 'when parameter is not required', () -> describe 'and example and default value are empty', () -> - it 'should not set descirptive error', -> + it 'should not set the error', -> params = name: description: 'Machine name' type: 'string' required: false - example: '' - default: '' + example: null + default: null values: [] result = validateParameters params @@ -227,7 +285,7 @@ describe 'validateParameters', -> description: 'Machine name' type: 'string' required: true - example: '' + example: null default: 'bagaboo' values: [] @@ -242,7 +300,7 @@ describe 'validateParameters', -> type: 'string' required: true example: 'booboo' - default: '' + default: null values: [] result = validateParameters params @@ -257,12 +315,28 @@ describe 'validateParameters', -> type: 'boolean' required: true example: 'false' - default: '' + default: null values: [] result = validateParameters params assert.equal result['errors'].length, 0 + describe 'when type is boolean and default value is parseable bool and example value is empty string', () -> + it 'should set descirptive error', () -> + params = + name: + description: 'Machine name' + type: 'boolean' + required: true + example: '' + default: 'false' + values: [] + + result = validateParameters params + message = result['errors'][0] + assert.include message, 'name' + assert.include message, 'boolean' + describe 'when type is boolean and default value is parseable bool and example value is empty', () -> it 'should not set the error', () -> params = @@ -270,9 +344,25 @@ describe 'validateParameters', -> description: 'Machine name' type: 'boolean' required: true - example: '' + example: null default: 'false' values: [] result = validateParameters params - assert.equal result['errors'].length, 1 + assert.equal result['errors'].length, 0 + + describe 'when type is boolean and default value is not parseable bool and example value is empty', () -> + it 'should not set the error', () -> + params = + name: + description: 'Machine name' + type: 'boolean' + required: true + example: null + default: 'booooo' + values: [] + + result = validateParameters params + message = result['errors'][0] + assert.include message, 'name' + assert.include message, 'boolean'