From aba2cc36b9da2dfa097ccdd3f24a375b2c660a6c Mon Sep 17 00:00:00 2001 From: suchothendav Date: Fri, 9 Sep 2016 13:25:00 -0700 Subject: [PATCH 01/10] es6 changes --- lib/generators/format.js | 70 ++++++++-------- lib/generators/index.js | 116 +++++++++++++-------------- lib/generators/paramtypes.js | 45 ++++++----- lib/index.js | 149 ++++++++++++++++++++--------------- lib/util/index.js | 2 - package.json | 4 + 6 files changed, 203 insertions(+), 183 deletions(-) diff --git a/lib/generators/format.js b/lib/generators/format.js index 6152660..ce907bf 100644 --- a/lib/generators/format.js +++ b/lib/generators/format.js @@ -1,54 +1,54 @@ 'use strict'; -var Moment = require('moment'); -var Chance = require('chance').Chance(); -var Randexp = require('randexp').randexp; +const Moment = require('moment'); +const Chance = require('chance').Chance(); +const Randexp = require('randexp').randexp; -module.exports = { - date: dateMock, - 'date-time': dataTimeMock, - uri: urlMock, - url: urlMock, - email: emailMock, - phone: phoneMock, - uuid: guidMock, - guid: guidMock, - ipv4: ipv4, - ipv6: ipv6, - hostname: hostname -}; - -function dateMock() { +const date = () => { return Moment().format('YYYY-MM-DD'); -} +}; -function dataTimeMock() { +const dataTimeMock = () => { return Moment().toISOString(); -} +}; -function urlMock() { +const url = () => { return Chance.url(); -} +}; -function emailMock() { +const email = () => { return Chance.email(); -} +}; -function phoneMock() { +const phone = () => { return Chance.phone(); -} +}; -function guidMock() { +const guid = () => { return Chance.guid(); -} +}; -function ipv4() { +const ipv4 = () => { return Chance.ip(); -} +}; -function ipv6() { +const ipv6 = () => { return Chance.ipv6(); -} +}; -function hostname() { +const hostname = () => { return Randexp(/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/gm); -} +}; + +module.exports = { + date, + 'date-time': dataTimeMock, + uri: url, + url, + email, + phone, + uuid: guid, + guid, + ipv4, + ipv6, + hostname +}; diff --git a/lib/generators/index.js b/lib/generators/index.js index 6b6cc7a..36e9505 100644 --- a/lib/generators/index.js +++ b/lib/generators/index.js @@ -1,38 +1,27 @@ 'use strict'; -var Chance = require('chance').Chance(); -var Format = require('./format'); -var Util = require('../util'); -var Randexp = require('randexp').randexp; +const Chance = require('chance').Chance(); +const Format = require('./format'); +const Util = require('../util'); +const Randexp = require('randexp').randexp; -var Generators = module.exports = { - object: objectMock, - array: arrayMock, - string: stringMock, - integer: integerMock, - number: numberMock, - boolean: booleanMock, - file: fileMock, - mock: mock -}; - -function mock(schema) { - var mock; +const mock = schema => { + let mock; if (schema) { - var type = schema.type || findType(schema); + let type = schema.type || findType(schema); /** * Get the mock generator from the `type` of the schema */ - var generator = Generators[type]; + const generator = Generators[type]; if (generator) { mock = generator.call(null, schema); } } return mock; -} +}; -function objectMock(schema) { - var mockObj = {}; - var props = schema.properties; +const objectMock = schema => { + let mockObj = {}; + let props = schema.properties; if (props) { Object.keys(props).forEach(function (key) { mockObj[key] = mock(props[key]); @@ -49,18 +38,18 @@ function objectMock(schema) { mockObj[Chance.word()] = mock(schema.additionalProperties); } return mockObj; -} +}; /** * Generates a mock `array` data of `items` * Supports: `minItems` and `maxItems` * TODO: Implement `uniqueItems` */ -function arrayMock(schema) { - var items = schema.items; - var min; - var max; - var numItems; - var arr = []; +const arrayMock = schema => { + let items = schema.items; + let min; + let max; + let numItems; + let arr = []; if (items) { //Use the min as the base @@ -77,20 +66,20 @@ function arrayMock(schema) { min: min, max: max }); - for (var i = 0; i < numItems; i++) { + for (let i = 0; i < numItems; i++) { arr.push(mock(items)); } } return arr; -} +}; /** * Generates a mock `integer` value * Supports `minimum`, `maximum`, `exclusiveMinimum` and `exclusiveMaximum` * TODO - Validate `minimum` and `maximum` values */ -function integerMock(schema) { - var opts = {}; - var intmock; +const integerMock = schema => { + let opts = {}; + let intmock; /** * If `enum` is defined for the property @@ -117,16 +106,16 @@ function integerMock(schema) { intmock = Chance.integer(opts); } return intmock; -} +}; /** * Generates a mock `number` value * Supports `minimum`, `maximum`, `exclusiveMinimum` and `exclusiveMaximum` * TODO - Validate `minimum` and `maximum` values */ -function numberMock(schema) { - var opts = {}; - var nummock; +const numberMock = schema => { + let opts = {}; + let nummock; /** * If `enum` is defined for the property @@ -153,9 +142,9 @@ function numberMock(schema) { nummock = Chance.floating(opts); } return nummock; -} +}; -function booleanMock(schema) { +const booleanMock = schema => { /** * If `enum` is defined for the property */ @@ -163,17 +152,17 @@ function booleanMock(schema) { return enumMock(schema); } return Chance.bool(); -} +}; /** * Geneartes a mock `string` value * Supports: `minLength`, `maxLength`, `enum`, `date`, and `date-time` - * TODO : `pattern` + * */ -function stringMock(schema) { - var mockStr; - var opts = {}; - var minLength = schema.minLength || 1; - var maxLength = schema.maxLength || minLength + 10; +const stringMock = schema => { + let mockStr; + let opts = {}; + let minLength = schema.minLength || 1; + let maxLength = schema.maxLength || minLength + 10; opts.min = minLength; opts.max = maxLength; @@ -200,29 +189,40 @@ function stringMock(schema) { } return mockStr; -} +}; -function enumMock(schema) { - var len = schema.enum.length; - var opts = { +const enumMock = schema => { + let len = schema.enum.length; + let opts = { min: 0, max: len - 1 }; return schema.enum[Chance.integer(opts)]; -} +}; -function fileMock() { +const fileMock = () => { return Chance.file(); -} +}; //Find out the type based on schema props //(This is not a complete list or full proof solution) -function findType(schema) { - var type = 'object';// Use 'object' as the default type +const findType = schema => { + let type = 'object';// Use 'object' as the default type if (schema.pattern) { type = 'string'; } else if (schema.items) { type = 'array'; } return type; -} +}; + +const Generators = module.exports = { + object: objectMock, + array: arrayMock, + string: stringMock, + integer: integerMock, + number: numberMock, + boolean: booleanMock, + file: fileMock, + mock +}; diff --git a/lib/generators/paramtypes.js b/lib/generators/paramtypes.js index 4b6ee0e..e5e0225 100644 --- a/lib/generators/paramtypes.js +++ b/lib/generators/paramtypes.js @@ -1,38 +1,29 @@ -'use strict'; -var Generators = require('./index'); +const Generators = require('./index'); -module.exports = { - query: queryMock, - path: queryMock, - formData: queryMock, - header: queryMock, - body: bodyMock -}; - -var collectionFormat = { - csv : function (val) { +const collectionFormat = { + csv : val => { return val.join(','); }, - ssv: function (val) { + ssv: val => { return val.join(' '); }, - tsv: function (val) { + tsv: val => { return val.join('\t'); }, - pipes: function (val) { + pipes: val => { return val.join('|'); }, - multi: function (val) { + multi: val => { return val; } }; /** * TODO : Handle type `file` */ -function queryMock(param) { - var mock = {}; - var value = Generators.mock(param); - var separator = collectionFormat.csv; +const queryMock = param => { + let mock = {}; + let value = Generators.mock(param); + let separator = collectionFormat.csv; //`collectionFormat` Determines the format of the array if type array is used. // Possible values are: csv, ssv, tsv. pipes and multi if (param.type === 'array' && param.collectionFormat) { @@ -43,11 +34,19 @@ function queryMock(param) { mock.name = param.name; mock.value = value; return mock; -} +}; -function bodyMock(param) { +const bodyMock = param => { return { name: param.name, value: Generators.mock(param.schema) }; -} +}; + +module.exports = { + query: queryMock, + path: queryMock, + formData: queryMock, + header: queryMock, + body: bodyMock +}; diff --git a/lib/index.js b/lib/index.js index a439353..3bf03fe 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,59 +1,56 @@ -'use strict'; -var Parser = require('swagger-parser'); -var Generators = require('./generators'); -var ParamTypes = require('./generators/paramtypes'); -var Util = require('./util'); -var Querystring = require('querystring'); +const Parser = require('swagger-parser'); +const Generators = require('./generators'); +const ParamTypes = require('./generators/paramtypes'); +const Util = require('./util'); +const Querystring = require('querystring'); +const Maybe = require('call-me-maybe'); -module.exports = function (apiPath) { - return new SwagMock(apiPath); +module.exports = (api, options) => { + return new SwagMock(api, options); }; -function SwagMock(apiPath) { - this.swagger = Parser.validate(apiPath); +function SwagMock(api, { validated } = {}) { + //If the api is an already validated Object, use it as it is. + //If not validated, Parse and validate using 'swagger-parser' + this.swagger = validated ? Promise.resolve(api) : Parser.validate(api); } -SwagMock.prototype.responses = function(options, callback) { - options = options || {}; +SwagMock.prototype.responses = function(options = {}, callback) { options.mockResponses = true; - this.mock(options, callback); + return Maybe(callback, this.mock(options)); }; -SwagMock.prototype.parameters = function(options, callback) { - options = options || {}; +SwagMock.prototype.parameters = function(options = {}, callback) { options.mockParams = true; - this.mock(options, callback); + return Maybe(callback, this.mock(options)); }; -SwagMock.prototype.requests = function(options, callback) { - options = options || {}; +SwagMock.prototype.requests = function(options = {}, callback) { options.mockRequest = true; - this.mock(options, callback); + return Maybe(callback, this.mock(options)); }; -SwagMock.prototype.mock = function(options, callback) { - options = options || {}; - this.swagger.then(function(api) { - callback(null, mockSchema(api, options)); - }).catch(function(error) { - callback(error); +SwagMock.prototype.mock = function(options = {}) { + + return this.swagger.then(api => { + return mockSchema(api, options); }); }; -function mockSchema(api, options) { - var mock = {}; - var paths = api.paths; +const mockSchema = (api, options) => { + let mock = {}; + let paths = api.paths; if (paths) { - var pathObj = paths[options.path]; + let pathObj = paths[options.path]; if (pathObj) { //Found the requested path mockPath(options.path, pathObj, mock, options); } else { //Generate Mocks for all the paths Object.keys(paths).forEach(function(pathStr) { - var pathObj = paths[pathStr]; + let pathObj = paths[pathStr]; if (pathObj) { - var pathMock = {}; + let pathMock = {}; mockPath(pathStr, pathObj, pathMock, options); mock[pathStr] = pathMock; } @@ -61,15 +58,15 @@ function mockSchema(api, options) { } } return mock; -} +}; /** - * + * Generate mock for the path */ -function mockPath(pathStr, pathObj, mock, options) { - var opsObj = pathObj[options.operation]; +const mockPath = (pathStr, pathObj, mock, options) => { + let opsObj = pathObj[options.operation]; //Common parameters - A list of parameters that are applicable for //all the operations described under this path - var commParams = pathObj.parameters; + let commParams = pathObj.parameters; if (opsObj) { //Found the operation mockOperation({ @@ -79,9 +76,9 @@ function mockPath(pathStr, pathObj, mock, options) { }, opsObj, mock, options); } else { Object.keys(pathObj).forEach(function(operation) { - if (pathObj[operation] && Util.OPERATIONS.indexOf(operation) !== -1) { + if (pathObj[operation] && Util.OPERATIONS.includes(operation)) { //Valid operation. - var opsMock = {}; + let opsMock = {}; mockOperation({ path: pathStr, operation: operation, @@ -91,11 +88,11 @@ function mockPath(pathStr, pathObj, mock, options) { } }); } -} +}; /** - * + * Generate mock for the operation */ -function mockOperation(resolved, opsObj, mock, options) { +const mockOperation = (resolved, opsObj, mock, options) => { //Mock response if (options.mockResponses) { mock.responses = mockResponses(opsObj, options); @@ -109,23 +106,23 @@ function mockOperation(resolved, opsObj, mock, options) { resolved.consumes = opsObj.consumes; mock.request = mockRequest(resolved, mock.parameters || mockParameters(resolved, opsObj, options)); } -} +}; /** * Generate a mock responses * */ -function mockResponses(opsObj, options) { - var mockResp; - var responses = opsObj.responses; +const mockResponses = (opsObj, options) => { + let mockResp; + let responses = opsObj.responses; if (responses) { - var response = responses[options.response]; + let response = responses[options.response]; if (response) { //Found the response mockResp = mockResponse(response); } else { mockResp = mockResp || {}; Object.keys(responses).forEach(function(responseStr) { - var response = responses[responseStr]; + let response = responses[responseStr]; if (response) { mockResp[responseStr] = mockResponse(response); } @@ -133,33 +130,32 @@ function mockResponses(opsObj, options) { } } return mockResp; -} +}; /** * */ -function mockResponse(response) { - var mockResp; - var schema = response.schema; +const mockResponse = response => { + let mockResp; + let schema = response.schema; if (schema) { mockResp = Generators.mock(schema); } return mockResp; -} +}; /** * Generate a mock parameter list * */ -function mockParameters(resolved, opsObj) { - var mockParam = {}; - var parameters = resolved.commonParams || []; +const mockParameters = (resolved, opsObj) => { + let mockParam = {}; //Combine common parameters - parameters = parameters.concat(opsObj.parameters || []); + let parameters = mergeParams(resolved.commonParams, opsObj.parameters); if (parameters.length > 0) { //Iterate over each parameter parameters.forEach(function(param) { // `in` - The location of the parameter. // Possible values are "query", "header", "path", "formData" or "body". - var paramType = param.in; + let paramType = param.in; if (ParamTypes[paramType]) { //Found the Mock generator for the param type (AKA `location`, AKA `in`). mockParam[paramType] = mockParam[paramType] || []; @@ -168,16 +164,16 @@ function mockParameters(resolved, opsObj) { }); } return mockParam; -} +}; /** * Generates the mock request objects that can be used for tests */ -function mockRequest(resolved, parameters) { - var mock = {}; - var queryObj = {}; - var headerObj = {}; - var formObj = {}; - var pathname = resolved.path; +const mockRequest = (resolved, parameters) => { + let mock = {}; + let queryObj = {}; + let headerObj = {}; + let formObj = {}; + let pathname = resolved.path; if (parameters) { //path @@ -228,4 +224,27 @@ function mockRequest(resolved, parameters) { mock.path = (mock.query) ? mock.pathname + '?' + mock.query : mock.pathname; } return mock; -} +}; + +/** + * Merge the common parameters at the path level to the operation parameters. + * Common parameters are a list of parameters that are applicable for all the operations + * described under a particular path. These parameters can be overridden at the operation level, + * but cannot be removed there. + */ +const mergeParams = (commonParams, opsParams) => { + let paramMap = new Map(); + if (commonParams) { + for (let param of commonParams) { + //A unique parameter is defined by a combination of a name and location + paramMap.set(param.name + param.in, param); + } + } + if (opsParams) { + for (let param of opsParams) { + //A unique parameter is defined by a combination of a name and location + paramMap.set(param.name + param.in, param); + } + } + return Array.from(paramMap.values()); +}; diff --git a/lib/util/index.js b/lib/util/index.js index 91e7c79..0af9fcd 100644 --- a/lib/util/index.js +++ b/lib/util/index.js @@ -1,5 +1,3 @@ -'use strict'; - module.exports = { OPERATIONS: ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'] }; diff --git a/package.json b/package.json index 4a5c282..de89817 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,9 @@ "version": "0.0.4", "description": "Mock data generator for swagger api", "main": "lib/index.js", + "engines": { + "node": ">=6.x" + }, "scripts": { "lint": "eslint lib", "test": "mocha tests/*.js", @@ -27,6 +30,7 @@ }, "homepage": "https://github.com/subeeshcbabu/swagmock#readme", "dependencies": { + "call-me-maybe": "^1.0.1", "chance": "^1.0.3", "moment": "^2.13.0", "randexp": "^0.4.2", From c6e9da4c20571b4d23a42c1d0b4aafd4b7e9f809 Mon Sep 17 00:00:00 2001 From: suchothendav Date: Fri, 9 Sep 2016 13:41:48 -0700 Subject: [PATCH 02/10] es6 changes --- lib/generators/format.js | 46 ++++++++---------------------------- lib/generators/index.js | 26 ++++++++++---------- lib/generators/paramtypes.js | 20 ++++------------ 3 files changed, 27 insertions(+), 65 deletions(-) diff --git a/lib/generators/format.js b/lib/generators/format.js index ce907bf..93b70eb 100644 --- a/lib/generators/format.js +++ b/lib/generators/format.js @@ -3,45 +3,19 @@ const Moment = require('moment'); const Chance = require('chance').Chance(); const Randexp = require('randexp').randexp; -const date = () => { - return Moment().format('YYYY-MM-DD'); -}; - -const dataTimeMock = () => { - return Moment().toISOString(); -}; - -const url = () => { - return Chance.url(); -}; - -const email = () => { - return Chance.email(); -}; - -const phone = () => { - return Chance.phone(); -}; - -const guid = () => { - return Chance.guid(); -}; - -const ipv4 = () => { - return Chance.ip(); -}; - -const ipv6 = () => { - return Chance.ipv6(); -}; - -const hostname = () => { - return Randexp(/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/gm); -}; +const date = () => Moment().format('YYYY-MM-DD'); +const dataTime = () => Moment().toISOString(); +const url = () => Chance.url(); +const email = () => Chance.email(); +const phone = () => Chance.phone(); +const guid = () => Chance.guid(); +const ipv4 = () => Chance.ip(); +const ipv6 = () => Chance.ipv6(); +const hostname = () => Randexp(/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/gm); module.exports = { date, - 'date-time': dataTimeMock, + 'date-time': dataTime, uri: url, url, email, diff --git a/lib/generators/index.js b/lib/generators/index.js index 36e9505..969dc31 100644 --- a/lib/generators/index.js +++ b/lib/generators/index.js @@ -19,12 +19,11 @@ const mock = schema => { return mock; }; -const objectMock = schema => { +const objectMock = ({ properties, additionalProperties }) => { let mockObj = {}; - let props = schema.properties; - if (props) { - Object.keys(props).forEach(function (key) { - mockObj[key] = mock(props[key]); + if (properties) { + Object.keys(properties).forEach(function (key) { + mockObj[key] = mock(properties[key]); }); /** * In the absense of `properties`, check if `additionalProperties` is defined or not. @@ -33,9 +32,9 @@ const objectMock = schema => { * * If present, use this to generate mocks. */ - } else if (schema.additionalProperties) { + } else if (additionalProperties) { //Create a random property - mockObj[Chance.word()] = mock(schema.additionalProperties); + mockObj[Chance.word()] = mock(additionalProperties); } return mockObj; }; @@ -44,8 +43,7 @@ const objectMock = schema => { * Supports: `minItems` and `maxItems` * TODO: Implement `uniqueItems` */ -const arrayMock = schema => { - let items = schema.items; +const arrayMock = ({ items, minItems, maxItems }) => { let min; let max; let numItems; @@ -53,10 +51,10 @@ const arrayMock = schema => { if (items) { //Use the min as the base - min = schema.minItems || 1; - if (schema.maxItems) { + min = minItems || 1; + if (maxItems) { //If min is greater than max, use min as max. - max = (schema.maxItems < min) ? min : schema.maxItems; + max = (maxItems < min) ? min : maxItems; } else { //If max is not defined, use min as max. max = min; @@ -99,7 +97,7 @@ const integerMock = schema => { //Use the muplilier as the min number opts.min = schema.multipleOf; //Use the max/muplilier as the new max value - opts.max = (Util.isInteger(opts.max)) ? (Math.floor(opts.max/schema.multipleOf)) : opts.max; + opts.max = (Util.isInteger(opts.max)) ? (Math.floor(opts.max / schema.multipleOf)) : opts.max; intmock = Chance.integer(opts); intmock = intmock * schema.multipleOf; } else { @@ -135,7 +133,7 @@ const numberMock = schema => { //Use the muplilier as the min number opts.min = schema.multipleOf; //Use the max/muplilier as the new max value - opts.max = (opts.max) ? opts.max/schema.multipleOf : opts.max; + opts.max = (opts.max) ? opts.max / schema.multipleOf : opts.max; nummock = Chance.floating(opts); nummock = nummock * schema.multipleOf; } else { diff --git a/lib/generators/paramtypes.js b/lib/generators/paramtypes.js index e5e0225..48650f0 100644 --- a/lib/generators/paramtypes.js +++ b/lib/generators/paramtypes.js @@ -1,21 +1,11 @@ const Generators = require('./index'); const collectionFormat = { - csv : val => { - return val.join(','); - }, - ssv: val => { - return val.join(' '); - }, - tsv: val => { - return val.join('\t'); - }, - pipes: val => { - return val.join('|'); - }, - multi: val => { - return val; - } + csv : val => val.join(','), + ssv: val => val.join(' '), + tsv: val => val.join('\t'), + pipes: val => val.join('|'), + multi: val => val }; /** * TODO : Handle type `file` From efcc692a7747e8bdac894cfbe2168f640b20e71e Mon Sep 17 00:00:00 2001 From: suchothendav Date: Fri, 9 Sep 2016 13:53:57 -0700 Subject: [PATCH 03/10] UNit test for parameter override at operation level #25 --- tests/fixture/petstore.json | 26 +++++++++++--------------- tests/param_mockgen.js | 21 ++++++++++++++++++++- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/tests/fixture/petstore.json b/tests/fixture/petstore.json index a251f5c..3f07f0a 100644 --- a/tests/fixture/petstore.json +++ b/tests/fixture/petstore.json @@ -172,6 +172,14 @@ } }, "/pet/{petId}": { + "parameters": [{ + "name": "petId", + "in": "path", + "description": "ID of pet to return", + "required": true, + "type": "integer", + "format": "int64" + }], "get": { "tags": ["pet"], "summary": "Find pet by ID", @@ -184,6 +192,8 @@ "description": "ID of pet to return", "required": true, "type": "integer", + "minimum": 1000, + "maximum": 2000, "format": "int64" }, { @@ -219,14 +229,7 @@ "operationId": "updatePetWithForm", "consumes": ["application/x-www-form-urlencoded"], "produces": ["application/xml", "application/json"], - "parameters": [{ - "name": "petId", - "in": "path", - "description": "ID of pet that needs to be updated", - "required": true, - "type": "integer", - "format": "int64" - }, { + "parameters": [ { "name": "name", "in": "formData", "description": "Updated name of the pet", @@ -259,13 +262,6 @@ "in": "header", "required": false, "type": "string" - }, { - "name": "petId", - "in": "path", - "description": "Pet id to delete", - "required": true, - "type": "integer", - "format": "int64" }], "responses": { "400": { diff --git a/tests/param_mockgen.js b/tests/param_mockgen.js index a45a5dc..e6f4038 100644 --- a/tests/param_mockgen.js +++ b/tests/param_mockgen.js @@ -56,7 +56,9 @@ describe('Parameter Mock generator', function () { Assert.ok(params.path, 'Generated path parameter'); Assert.ok(params.path[0].name === 'petId', 'generated mock parameter for petId'); Assert.ok(Number.isInteger(params.path[0].value), 'OK value for petId'); - + //Test the operation level overrides + Assert.ok(params.path[0].value > 1000 && params.path[0].value < 2000, 'OK value for petId'); + Assert.ok(params.query, 'Generated query parameter'); Assert.ok(params.query[0].name === 'petName', 'generated mock parameter for petName'); Assert.ok(/awesome+ (pet|cat|bird)/.test(params.query[0].value), 'OK value for petName'); @@ -64,6 +66,23 @@ describe('Parameter Mock generator', function () { }); }); + it('should generate parameter mock for path /pet/{petId} post - common parameter', function(done) { + swagmock.parameters({ + path: '/pet/{petId}', + operation: 'post' + }, function(err, mock) { + Assert.ok(!err, 'No error'); + Assert.ok(mock, 'Generated mock'); + var params = mock.parameters; + Assert.ok(params, 'Generated parameters'); + Assert.ok(params.path, 'Generated path parameter'); + Assert.ok(params.path[0].name === 'petId', 'generated mock parameter for petId'); + Assert.ok(Number.isInteger(params.path[0].value), 'OK value for petId'); + + done(); + }); + }); + it('should generate parameter mock for path /pet/{petId}/uploadImage', function(done) { swagmock.parameters({ path: '/pet/{petId}/uploadImage', From 293351b9240911eac17e2ba642a6fd4f0b6ae85d Mon Sep 17 00:00:00 2001 From: suchothendav Date: Fri, 9 Sep 2016 14:03:00 -0700 Subject: [PATCH 04/10] es6 Number.isInteger and get rid off util --- lib/generators/index.js | 9 ++++----- lib/index.js | 5 +++-- lib/util/index.js | 10 ---------- 3 files changed, 7 insertions(+), 17 deletions(-) delete mode 100644 lib/util/index.js diff --git a/lib/generators/index.js b/lib/generators/index.js index 969dc31..74e0808 100644 --- a/lib/generators/index.js +++ b/lib/generators/index.js @@ -1,7 +1,6 @@ 'use strict'; const Chance = require('chance').Chance(); const Format = require('./format'); -const Util = require('../util'); const Randexp = require('randexp').randexp; const mock = schema => { @@ -86,18 +85,18 @@ const integerMock = schema => { return enumMock(schema); } - if (Util.isInteger(schema.minimum)) { + if (Number.isInteger(schema.minimum)) { opts.min = (schema.exclusiveMinimum) ? schema.minimum : schema.minimum + 1; } - if (Util.isInteger(schema.maximum)) { + if (Number.isInteger(schema.maximum)) { opts.max = (schema.exclusiveMaximum) ? schema.maximum : schema.maximum - 1; } //Generate a number that is multiple of schema.multipleOf - if (Util.isInteger(schema.multipleOf) && schema.multipleOf > 0) { + if (Number.isInteger(schema.multipleOf) && schema.multipleOf > 0) { //Use the muplilier as the min number opts.min = schema.multipleOf; //Use the max/muplilier as the new max value - opts.max = (Util.isInteger(opts.max)) ? (Math.floor(opts.max / schema.multipleOf)) : opts.max; + opts.max = (Number.isInteger(opts.max)) ? (Math.floor(opts.max / schema.multipleOf)) : opts.max; intmock = Chance.integer(opts); intmock = intmock * schema.multipleOf; } else { diff --git a/lib/index.js b/lib/index.js index 3bf03fe..a1a4761 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,10 +1,11 @@ const Parser = require('swagger-parser'); const Generators = require('./generators'); const ParamTypes = require('./generators/paramtypes'); -const Util = require('./util'); const Querystring = require('querystring'); const Maybe = require('call-me-maybe'); +const OPERATIONS = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch']; + module.exports = (api, options) => { return new SwagMock(api, options); }; @@ -76,7 +77,7 @@ const mockPath = (pathStr, pathObj, mock, options) => { }, opsObj, mock, options); } else { Object.keys(pathObj).forEach(function(operation) { - if (pathObj[operation] && Util.OPERATIONS.includes(operation)) { + if (pathObj[operation] && OPERATIONS.includes(operation)) { //Valid operation. let opsMock = {}; mockOperation({ diff --git a/lib/util/index.js b/lib/util/index.js deleted file mode 100644 index 0af9fcd..0000000 --- a/lib/util/index.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - OPERATIONS: ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'] -}; - - -module.exports.isInteger = function(value) { - return typeof value === 'number' && - isFinite(value) && - Math.floor(value) === value; -}; From 279027c41fd12b9411d894b2509a679f41ac8cdc Mon Sep 17 00:00:00 2001 From: suchothendav Date: Fri, 9 Sep 2016 14:10:44 -0700 Subject: [PATCH 05/10] Unit test for option to set validated = true to generate mocks for already parsed api #24 --- tests/param_mockgen.js | 83 ++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/tests/param_mockgen.js b/tests/param_mockgen.js index e6f4038..8d66f37 100644 --- a/tests/param_mockgen.js +++ b/tests/param_mockgen.js @@ -1,24 +1,21 @@ -var Assert = require('assert'); -var Swagmock = require('../lib'); -var Path = require('path') -//isInteger pollyfil for pre es6 -Number.isInteger = Number.isInteger || function(value) { - return typeof value === "number" && - isFinite(value) && - Math.floor(value) === value; -}; +const Assert = require('assert'); +const Swagmock = require('../lib'); +const Path = require('path'); +const Parser = require('swagger-parser'); -describe('Parameter Mock generator', function () { - var apiPath = Path.resolve(__dirname, 'fixture/petstore.json'); - var swagmock = Swagmock(apiPath); - it('should generate parameter mock for path /store/order/{orderId}', function(done) { +describe('Parameter Mock generator', () => { + let apiPath = Path.resolve(__dirname, 'fixture/petstore.json'); + let apiResolver = Parser.validate(apiPath); + //Test case of valiadted api use case. + let swagmock = Swagmock(apiResolver, { validated: true }); + it('should generate parameter mock for path /store/order/{orderId}', done => { swagmock.parameters({ path: '/store/order/{orderId}', operation: 'get' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var params = mock.parameters; + let params = mock.parameters; Assert.ok(params, 'Generated parameters'); Assert.ok(params.path, 'Generated path parameter'); Assert.ok(params.path[0].name === 'orderId', 'generated mock parameter for orderId'); @@ -27,14 +24,14 @@ describe('Parameter Mock generator', function () { }); }); - it('should generate parameter mock for path /pet/findByStatus', function(done) { + it('should generate parameter mock for path /pet/findByStatus', done => { swagmock.parameters({ path: '/pet/findByStatus', operation: 'get' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var params = mock.parameters; + let params = mock.parameters; Assert.ok(params, 'Generated parameters'); Assert.ok(params.query, 'Generated query parameter'); Assert.ok(params.query[0].name === 'status', 'generated mock parameter for status'); @@ -44,21 +41,21 @@ describe('Parameter Mock generator', function () { }); }); - it('should generate parameter mock for path /pet/{petId}', function(done) { + it('should generate parameter mock for path /pet/{petId}', done => { swagmock.parameters({ path: '/pet/{petId}', operation: 'get' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var params = mock.parameters; + let params = mock.parameters; Assert.ok(params, 'Generated parameters'); Assert.ok(params.path, 'Generated path parameter'); Assert.ok(params.path[0].name === 'petId', 'generated mock parameter for petId'); Assert.ok(Number.isInteger(params.path[0].value), 'OK value for petId'); //Test the operation level overrides Assert.ok(params.path[0].value > 1000 && params.path[0].value < 2000, 'OK value for petId'); - + Assert.ok(params.query, 'Generated query parameter'); Assert.ok(params.query[0].name === 'petName', 'generated mock parameter for petName'); Assert.ok(/awesome+ (pet|cat|bird)/.test(params.query[0].value), 'OK value for petName'); @@ -66,14 +63,14 @@ describe('Parameter Mock generator', function () { }); }); - it('should generate parameter mock for path /pet/{petId} post - common parameter', function(done) { + it('should generate parameter mock for path /pet/{petId} post - common parameter', (done) => { swagmock.parameters({ path: '/pet/{petId}', operation: 'post' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var params = mock.parameters; + let params = mock.parameters; Assert.ok(params, 'Generated parameters'); Assert.ok(params.path, 'Generated path parameter'); Assert.ok(params.path[0].name === 'petId', 'generated mock parameter for petId'); @@ -83,14 +80,14 @@ describe('Parameter Mock generator', function () { }); }); - it('should generate parameter mock for path /pet/{petId}/uploadImage', function(done) { + it('should generate parameter mock for path /pet/{petId}/uploadImage', (done) => { swagmock.parameters({ path: '/pet/{petId}/uploadImage', operation: 'post' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var params = mock.parameters; + let params = mock.parameters; Assert.ok(params, 'Generated parameters'); Assert.ok(params.path, 'Generated path parameter'); Assert.ok(params.path[0].name === 'petId', 'generated mock parameter for petId'); @@ -103,31 +100,31 @@ describe('Parameter Mock generator', function () { }); }); - it('should generate parameter mock for path /store/inventory', function(done) { + it('should generate parameter mock for path /store/inventory', (done) => { swagmock.parameters({ path: '/store/inventory', operation: 'get' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var params = mock.parameters; + let params = mock.parameters; Assert.ok(params, 'Generated parameters'); done(); }); }); - it('should generate parameter mock for path /store/order', function(done) { + it('should generate parameter mock for path /store/order', (done) => { swagmock.parameters({ path: '/store/order', operation: 'post' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var params = mock.parameters; + let params = mock.parameters; Assert.ok(params, 'Generated parameters'); Assert.ok(params.body, 'Generated body parameter'); Assert.ok(params.body[0].name === 'body', 'generated mock parameter for body'); - var order = params.body[0].value; + let order = params.body[0].value; Assert.ok(typeof order === 'object', 'OK value for body'); Assert.ok(Number.isInteger(order.id), 'order.id is integer'); Assert.ok(Number.isInteger(order.petId), 'order.petId is integer'); @@ -139,21 +136,21 @@ describe('Parameter Mock generator', function () { }); }); - it('should generate parameter mock for path /user/createWithArray', function(done) { + it('should generate parameter mock for path /user/createWithArray', (done) => { swagmock.parameters({ path: '/user/createWithArray', operation: 'post' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var params = mock.parameters; + let params = mock.parameters; Assert.ok(params, 'Generated parameters'); Assert.ok(params.body, 'Generated body parameter'); Assert.ok(params.body[0].name === 'body', 'generated mock parameter for body'); - var users = params.body[0].value; + let users = params.body[0].value; Assert.ok(users.length === 1, 'Created a parameter array of users'); - var user = users[0]; + let user = users[0]; Assert.ok(typeof user === 'object', 'OK value for user parameter'); Assert.ok(Number.isInteger(user.id), 'user.id is integer'); Assert.ok(Number.isInteger(user.userStatus), 'user.userStatus is integer'); @@ -163,14 +160,14 @@ describe('Parameter Mock generator', function () { }); }); - it('should generate parameter mock for path /user/logout', function(done) { + it('should generate parameter mock for path /user/logout', (done) => { swagmock.parameters({ path: '/user/logout', operation: 'get' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var params = mock.parameters; + let params = mock.parameters; Assert.ok(params, 'Generated parameters'); Assert.ok(params.query, 'Generated path parameter'); Assert.ok(params.query[0].name === 'common', 'generated mock parameter for common parameter'); From 27477dd9e248d6b9eef31c6a7bb38d88c9f6a544 Mon Sep 17 00:00:00 2001 From: suchothendav Date: Fri, 9 Sep 2016 14:20:03 -0700 Subject: [PATCH 06/10] Unit test for promise response if callback is not provided as an argument #20 --- package.json | 2 +- tests/params_mockgen.js | 44 +++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index de89817..8e496f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "swagmock", - "version": "0.0.4", + "version": "1.0.0-alpha.1", "description": "Mock data generator for swagger api", "main": "lib/index.js", "engines": { diff --git a/tests/params_mockgen.js b/tests/params_mockgen.js index 0c3520e..6232d91 100644 --- a/tests/params_mockgen.js +++ b/tests/params_mockgen.js @@ -1,37 +1,36 @@ -var Assert = require('assert'); -var Swagmock = require('../lib'); -var Path = require('path') -//isInteger pollyfil for pre es6 -Number.isInteger = Number.isInteger || function(value) { - return typeof value === "number" && - isFinite(value) && - Math.floor(value) === value; -}; +const Assert = require('assert'); +const Swagmock = require('../lib'); +const Path = require('path') -describe('Parameters Mock generator', function () { - var apiPath = Path.resolve(__dirname, 'fixture/petstore.json'); - var swagmock = Swagmock(apiPath); - it('should generate parameter mock for path /store/order/{orderId} for all operations', function(done) { - swagmock.parameters({ +describe('Parameters Mock generator', () => { + let apiPath = Path.resolve(__dirname, 'fixture/petstore.json'); + let swagmock = Swagmock(apiPath); + it('should generate parameter mock for path /store/order/{orderId} for all operations', (done) => { + let mockgen = swagmock.parameters({ path: '/store/order/{orderId}' - }, function(err, mock) { - Assert.ok(!err, 'No error'); + }); + //Promise test case + mockgen.then(mock => { Assert.ok(mock, 'Generated mock'); Assert.ok(mock.get, 'Generated mock for get operation'); Assert.ok(mock.delete, 'Generated mock for delete operation'); - var params = mock.get.parameters; + let params = mock.get.parameters; Assert.ok(params, 'Generated parameters'); Assert.ok(params.path, 'Generated path parameter'); Assert.ok(params.path[0].name === 'orderId', 'generated mock parameter for orderId'); Assert.ok(params.path[0].value > 0 && params.path[0].value < 10, 'OK value for orderId'); done(); + }).catch(err => { + Assert.ok(!err, 'No error'); + done(); }); }); - it('should generate parameter mock for all the path', function(done) { - swagmock.parameters({}, function(err, mock) { - var testMock; - Assert.ok(!err, 'No error'); + it('should generate parameter mock for all the path', (done) => { + let mockgen = swagmock.parameters({}); + //Promise test case + mockgen.then(mock => { + let testMock; Assert.ok(mock, 'Generated mock'); Assert.ok(mock['/pet'], 'Generated mock for path /pet'); Assert.ok(mock['/pet/findByStatus'], 'Generated mock for path /pet/findByStatus'); @@ -54,6 +53,9 @@ describe('Parameters Mock generator', function () { testMock = mock['/user/createWithList'].post.parameters.body[0].value; Assert.ok(testMock.length <= 4, 'body parameter should have maximum 4 items'); done(); + }).catch(err => { + Assert.ok(!err, 'No error'); + done(); }); }); }); From f6ba2e35fb60d1d9255618626ad8f8c8897819b7 Mon Sep 17 00:00:00 2001 From: suchothendav Date: Fri, 9 Sep 2016 15:52:23 -0700 Subject: [PATCH 07/10] unit tests to es6 --- tests/request_mockgen.js | 66 ++++++++++++++++------------------ tests/response_mockgen.js | 72 +++++++++++++++++--------------------- tests/responses_mockgen.js | 69 +++++++++++++++++------------------- 3 files changed, 96 insertions(+), 111 deletions(-) diff --git a/tests/request_mockgen.js b/tests/request_mockgen.js index 0500ca3..cd805df 100644 --- a/tests/request_mockgen.js +++ b/tests/request_mockgen.js @@ -1,24 +1,18 @@ -var Assert = require('assert'); -var Swagmock = require('../lib'); -var Path = require('path') -//isInteger pollyfil for pre es6 -Number.isInteger = Number.isInteger || function(value) { - return typeof value === "number" && - isFinite(value) && - Math.floor(value) === value; -}; +const Assert = require('assert'); +const Swagmock = require('../lib'); +const Path = require('path') -describe('Request Mock generator', function () { - var apiPath = Path.resolve(__dirname, 'fixture/petstore.json'); - var swagmock = Swagmock(apiPath); - it('should generate request mock for path /store/order/{orderId}', function(done) { +describe('Request Mock generator', () => { + let apiPath = Path.resolve(__dirname, 'fixture/petstore.json'); + let swagmock = Swagmock(apiPath); + it('should generate request mock for path /store/order/{orderId}', (done) => { swagmock.requests({ path: '/store/order/{orderId}', operation: 'get' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var request = mock.request; + let request = mock.request; Assert.ok(request, 'Generated request'); Assert.ok(request.pathname, 'Generated pathname request'); Assert.ok(request.path, 'Generated path request'); @@ -26,42 +20,42 @@ describe('Request Mock generator', function () { }); }); - it('should generate request mock for path /pet/findByStatus', function(done) { + it('should generate request mock for path /pet/findByStatus', (done) => { swagmock.requests({ path: '/pet/findByStatus', operation: 'get' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var request = mock.request; + let request = mock.request; Assert.ok(request, 'Generated request'); Assert.ok(request.query, 'Generated query request'); done(); }); }); - it('should generate request mock for path /pet/{petId}', function(done) { + it('should generate request mock for path /pet/{petId}', (done) => { swagmock.requests({ path: '/pet/{petId}', operation: 'get' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var request = mock.request; + let request = mock.request; Assert.ok(request, 'Generated parameters'); Assert.ok(request.pathname, 'Generated path parameter'); done(); }); }); - it('should generate request mock for path /pet/{petId}/uploadImage', function(done) { + it('should generate request mock for path /pet/{petId}/uploadImage', (done) => { swagmock.requests({ path: '/pet/{petId}/uploadImage', operation: 'post' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var request = mock.request; + let request = mock.request; Assert.ok(request, 'Generated request'); Assert.ok(request.pathname, 'Generated path request'); Assert.ok(request.formData, 'Generated formData request'); @@ -69,30 +63,30 @@ describe('Request Mock generator', function () { }); }); - it('should generate request mock for path /store/inventory', function(done) { + it('should generate request mock for path /store/inventory', (done) => { swagmock.requests({ path: '/store/inventory', operation: 'get' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var request = mock.request; + let request = mock.request; Assert.ok(request, 'Generated request'); done(); }); }); - it('should generate request mock for path /store/order', function(done) { + it('should generate request mock for path /store/order', (done) => { swagmock.requests({ path: '/store/order', operation: 'post' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var request = mock.request; + let request = mock.request; Assert.ok(request, 'Generated request'); Assert.ok(request.body, 'Generated body request'); - var order = request.body; + let order = request.body; Assert.ok(typeof order === 'object', 'OK value for body'); Assert.ok(Number.isInteger(order.id), 'order.id is integer'); Assert.ok(Number.isInteger(order.petId), 'order.petId is integer'); @@ -104,19 +98,19 @@ describe('Request Mock generator', function () { }); }); - it('should generate request mock for path /user/createWithArray', function(done) { + it('should generate request mock for path /user/createWithArray', (done) => { swagmock.requests({ path: '/user/createWithArray', operation: 'post' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var request = mock.request; + let request = mock.request; Assert.ok(request, 'Generated request'); Assert.ok(request.body, 'Generated body request'); - var users = request.body; + let users = request.body; Assert.ok(users.length === 1, 'Created a request array of users'); - var user = users[0]; + let user = users[0]; Assert.ok(typeof user === 'object', 'OK value for user request'); Assert.ok(Number.isInteger(user.id), 'user.id is integer'); Assert.ok(Number.isInteger(user.userStatus), 'user.userStatus is integer'); diff --git a/tests/response_mockgen.js b/tests/response_mockgen.js index 7932cd2..eddda02 100644 --- a/tests/response_mockgen.js +++ b/tests/response_mockgen.js @@ -1,26 +1,20 @@ -var Assert = require('assert'); -var Swagmock = require('../lib'); -var Path = require('path') -//isInteger pollyfil for pre es6 -Number.isInteger = Number.isInteger || function(value) { - return typeof value === "number" && - isFinite(value) && - Math.floor(value) === value; -}; - -describe('Response Mock generator', function () { - var apiPath = Path.resolve(__dirname, 'fixture/petstore.json'); - var swagmock = Swagmock(apiPath); - - it('should generate response mock for path /store/order/{orderId}', function(done) { +const Assert = require('assert'); +const Swagmock = require('../lib'); +const Path = require('path') + +describe('Response Mock generator', () => { + let apiPath = Path.resolve(__dirname, 'fixture/petstore.json'); + let swagmock = Swagmock(apiPath); + + it('should generate response mock for path /store/order/{orderId}', (done) => { swagmock.responses({ path: '/store/order/{orderId}', operation: 'get', response: '200' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var resp = mock.responses; + let resp = mock.responses; Assert.ok(resp, 'Generated response'); Assert.ok(Number.isInteger(resp.id), 'id is integer'); Assert.ok(Number.isInteger(resp.petId), 'petId is integer'); @@ -32,19 +26,19 @@ describe('Response Mock generator', function () { }); }); - it('should generate response mock for path /pet/findByStatus', function(done) { + it('should generate response mock for path /pet/findByStatus', (done) => { swagmock.responses({ path: '/pet/findByStatus', operation: 'get', response: '200' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var resp = mock.responses; + let resp = mock.responses; Assert.ok(resp, 'Generated response'); Assert.ok(Array.isArray(resp), 'response is Pet array'); - var pet = resp[0]; + let pet = resp[0]; Assert.ok(pet, 'Ok Pet response'); Assert.ok(Number.isInteger(pet.id), 'id is integer'); //TODO add asserts for pending props @@ -52,96 +46,96 @@ describe('Response Mock generator', function () { }); }); - it('should generate response mock for path /pet/{petId}', function(done) { + it('should generate response mock for path /pet/{petId}', (done) => { swagmock.responses({ path: '/pet/{petId}', operation: 'get', response: '200' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var resp = mock.responses; + let resp = mock.responses; Assert.ok(resp, 'Generated response'); //TODO add asserts for pending props done(); }); }); - it('should generate response mock for path /pet/{petId}/uploadImage', function(done) { + it('should generate response mock for path /pet/{petId}/uploadImage', (done) => { swagmock.responses({ path: '/pet/{petId}/uploadImage', operation: 'post', response: '200' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var resp = mock.responses; + let resp = mock.responses; Assert.ok(resp, 'Generated response'); //TODO add asserts for pending props done(); }); }); - it('should generate response mock for path /store/inventory', function(done) { + it('should generate response mock for path /store/inventory', (done) => { swagmock.responses({ path: '/store/inventory', operation: 'get', response: '200' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var resp = mock.responses; + let resp = mock.responses; Assert.ok(resp, 'Generated response'); //TODO add asserts for pending props done(); }); }); - it('should generate response mock for path /store/order', function(done) { + it('should generate response mock for path /store/order', (done) => { swagmock.responses({ path: '/store/order', operation: 'post', response: '200' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var resp = mock.responses; + let resp = mock.responses; Assert.ok(resp, 'Generated response'); //TODO add asserts for pending props done(); }); }); - it('should generate response mock for path /user/login', function(done) { + it('should generate response mock for path /user/login', (done) => { swagmock.responses({ path: '/user/login', operation: 'get', response: '200' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var resp = mock.responses; + let resp = mock.responses; Assert.ok(resp, 'Generated response'); //TODO add asserts for pending props done(); }); }); - it('should generate response mock for path /pet', function(done) { + it('should generate response mock for path /pet', (done) => { swagmock.responses({ path: '/pet', operation: 'post', response: '405' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); - var resp = mock.responses; + let resp = mock.responses; Assert.ok(!resp, 'No response'); //TODO add asserts for pending props done(); diff --git a/tests/responses_mockgen.js b/tests/responses_mockgen.js index 2a83c68..0a1ab17 100644 --- a/tests/responses_mockgen.js +++ b/tests/responses_mockgen.js @@ -1,30 +1,26 @@ -var Assert = require('assert'); -var Swagmock = require('../lib'); -var Path = require('path') -//isInteger pollyfil for pre es6 -Number.isInteger = Number.isInteger || function(value) { - return typeof value === "number" && - isFinite(value) && - Math.floor(value) === value; -}; +const Assert = require('assert'); +const Swagmock = require('../lib'); +const Path = require('path') +const Parser = require('swagger-parser'); -describe('Responses Mock generator', function () { - var apiPath = Path.resolve(__dirname, 'fixture/petstore.json'); - var swagmock = Swagmock(apiPath); +describe('Responses Mock generator', () => { + let apiPath = Path.resolve(__dirname, 'fixture/petstore.json'); + let apiResolver = Parser.validate(apiPath); + let swagmock = Swagmock(apiResolver, { validated: true }); - it('should generate response mock for path /store/order/{orderId}, get operation', function(done) { - swagmock.responses({ + it('should generate response mock for path /store/order/{orderId}, get operation', (done) => { + let mockgen = swagmock.responses({ path: '/store/order/{orderId}', operation: 'get' - }, function(err, mock) { - Assert.ok(!err, 'No error'); + }); + mockgen.then(mock => { Assert.ok(mock, 'Generated mock'); - var resp = mock.responses; + let resp = mock.responses; Assert.ok(resp, 'Generated response'); Assert.ok(resp.hasOwnProperty('200'), 'Generated 200 response'); Assert.ok(resp.hasOwnProperty('400'), 'Generated 400 response'); Assert.ok(resp.hasOwnProperty('404'), 'Generated 404 response'); - var successResp = resp['200']; + let successResp = resp['200']; Assert.ok(Number.isInteger(successResp.id), 'id is integer'); Assert.ok(Number.isInteger(successResp.petId), 'petId is integer'); Assert.ok(Number.isInteger(successResp.quantity), 'quantity is integer'); @@ -32,44 +28,46 @@ describe('Responses Mock generator', function () { Assert.ok(['placed','approved','delivered'].indexOf(successResp.status) !== -1, 'status is enum'); Assert.ok(typeof successResp.complete === 'boolean', 'complete is boolean'); done(); + }).catch(err => { + Assert.ok(!err, 'No error'); + done(); }); }); - it('should generate response mock for path /pet/findByStatus, for all operations', function(done) { - swagmock.responses({ + it('should generate response mock for path /pet/findByStatus, for all operations', (done) => { + let mockgen = swagmock.responses({ path: '/pet/findByStatus' - }, function(err, mock) { - Assert.ok(!err, 'No error'); - + }); + mockgen.then(mock => { Assert.ok(mock, 'Generated mock'); Assert.ok(mock.get, 'Generated mock for `get` operation'); - var responses = mock.get.responses; - + let responses = mock.get.responses; Assert.ok(responses, 'Generated responses'); Assert.ok(responses.hasOwnProperty('200'), 'Generated 200 response'); Assert.ok(responses.hasOwnProperty('400'), 'Generated 400 response'); - - var resp = responses['200']; + let resp = responses['200']; Assert.ok(Array.isArray(resp), 'response is Pet array'); - var pet = resp[0]; + let pet = resp[0]; Assert.ok(pet, 'Ok Pet response'); Assert.ok(Number.isInteger(pet.id), 'id is integer'); - + done(); + }).catch(err => { + Assert.ok(!err, 'No error'); done(); }); }); - it('should generate response mock for path /pet/{petId} for all operations', function(done) { + it('should generate response mock for path /pet/{petId} for all operations', (done) => { swagmock.responses({ path: '/pet/{petId}' - }, function(err, mock) { + }, (err, mock) => { Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); Assert.ok(mock.get, 'Generated mock for get operation'); Assert.ok(mock.post, 'Generated mock for post operation'); Assert.ok(mock.delete, 'Generated mock for delete operation'); - var responses = mock.delete.responses; + let responses = mock.delete.responses; Assert.ok(responses, 'Generated response for delete operation'); Assert.ok(responses.hasOwnProperty('404'), 'Generated 404 response'); Assert.ok(responses.hasOwnProperty('400'), 'Generated 400 response'); @@ -77,9 +75,9 @@ describe('Responses Mock generator', function () { }); }); - it('should generate response mock for all paths', function(done) { - swagmock.responses({}, function(err, mock) { - var testMock; + it('should generate response mock for all paths', (done) => { + swagmock.responses({}, (err, mock) => { + let testMock; Assert.ok(!err, 'No error'); Assert.ok(mock, 'Generated mock'); Assert.ok(mock['/pet'], 'Generated mock for path /pet'); @@ -96,7 +94,6 @@ describe('Responses Mock generator', function () { Assert.ok(mock['/user'], 'Generated mock for path /user'); Assert.ok(mock['/user/createWithArray'], 'Generated mock for path /user/createWithArray'); Assert.ok(mock['/user/createWithList'], 'Generated mock for path /user/createWithList'); - done(); }); }); From 0770eca0443e26c176796bbbcfb8a998c2055bf8 Mon Sep 17 00:00:00 2001 From: suchothendav Date: Mon, 12 Sep 2016 14:02:08 -0700 Subject: [PATCH 08/10] fix exclusive limit issue #27 and multipleOf max value enhancement #26 --- lib/generators/index.js | 12 +++++++----- tests/fixture/petstore.json | 7 +++++++ tests/param_mockgen.js | 8 +++++--- tests/params_mockgen.js | 2 +- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/generators/index.js b/lib/generators/index.js index 74e0808..52c0808 100644 --- a/lib/generators/index.js +++ b/lib/generators/index.js @@ -86,17 +86,19 @@ const integerMock = schema => { } if (Number.isInteger(schema.minimum)) { - opts.min = (schema.exclusiveMinimum) ? schema.minimum : schema.minimum + 1; + opts.min = (schema.exclusiveMinimum) ? schema.minimum + 1 : schema.minimum; } if (Number.isInteger(schema.maximum)) { - opts.max = (schema.exclusiveMaximum) ? schema.maximum : schema.maximum - 1; + opts.max = (schema.exclusiveMaximum) ? schema.maximum - 1 : schema.maximum; } //Generate a number that is multiple of schema.multipleOf if (Number.isInteger(schema.multipleOf) && schema.multipleOf > 0) { - //Use the muplilier as the min number - opts.min = schema.multipleOf; + //Use the min/muplilier as the min number + //Use default min as 1 if min is not properly set. + opts.min = (Number.isInteger(opts.min) && opts.min > 0) ? (Math.ceil(opts.min / schema.multipleOf)) : 1; //Use the max/muplilier as the new max value - opts.max = (Number.isInteger(opts.max)) ? (Math.floor(opts.max / schema.multipleOf)) : opts.max; + //Use a default - min + 10 - if max value is not properly set. + opts.max = (Number.isInteger(opts.max)) ? (Math.floor(opts.max / schema.multipleOf)) : (opts.min + 10); intmock = Chance.integer(opts); intmock = intmock * schema.multipleOf; } else { diff --git a/tests/fixture/petstore.json b/tests/fixture/petstore.json index 3f07f0a..8e67f5c 100644 --- a/tests/fixture/petstore.json +++ b/tests/fixture/petstore.json @@ -290,6 +290,10 @@ "description": "ID of pet to update", "required": true, "type": "integer", + "exclusiveMinimum": true, + "exclusiveMaximum": true, + "minimum": 1000, + "maximum": 1010, "format": "int64" }, { "name": "additionalMetadata", @@ -754,6 +758,9 @@ }, "userStatus": { "type": "integer", + "multipleOf": 100, + "minimum": 1000, + "exclusiveMinimum": true, "format": "int32", "description": "User Status" } diff --git a/tests/param_mockgen.js b/tests/param_mockgen.js index 8d66f37..dc66d70 100644 --- a/tests/param_mockgen.js +++ b/tests/param_mockgen.js @@ -19,7 +19,7 @@ describe('Parameter Mock generator', () => { Assert.ok(params, 'Generated parameters'); Assert.ok(params.path, 'Generated path parameter'); Assert.ok(params.path[0].name === 'orderId', 'generated mock parameter for orderId'); - Assert.ok(params.path[0].value > 0 && params.path[0].value < 10, 'OK value for orderId'); + Assert.ok(params.path[0].value >= 1 && params.path[0].value <= 10, 'OK value for orderId'); done(); }); }); @@ -54,7 +54,7 @@ describe('Parameter Mock generator', () => { Assert.ok(params.path[0].name === 'petId', 'generated mock parameter for petId'); Assert.ok(Number.isInteger(params.path[0].value), 'OK value for petId'); //Test the operation level overrides - Assert.ok(params.path[0].value > 1000 && params.path[0].value < 2000, 'OK value for petId'); + Assert.ok(params.path[0].value >= 1000 && params.path[0].value <= 2000, 'OK value for petId'); Assert.ok(params.query, 'Generated query parameter'); Assert.ok(params.query[0].name === 'petName', 'generated mock parameter for petName'); @@ -92,7 +92,7 @@ describe('Parameter Mock generator', () => { Assert.ok(params.path, 'Generated path parameter'); Assert.ok(params.path[0].name === 'petId', 'generated mock parameter for petId'); Assert.ok(Number.isInteger(params.path[0].value), 'OK value for petId'); - + Assert.ok(params.path[0].value > 1000 && params.path[0].value < 1010, 'OK value for petId'); Assert.ok(params.formData, 'Generated formData parameter'); Assert.ok(params.formData[0].name === 'additionalMetadata', 'generated mock parameter for additionalMetadata'); Assert.ok(typeof params.formData[0].value === 'string', 'OK value for additionalMetadata'); @@ -154,6 +154,8 @@ describe('Parameter Mock generator', () => { Assert.ok(typeof user === 'object', 'OK value for user parameter'); Assert.ok(Number.isInteger(user.id), 'user.id is integer'); Assert.ok(Number.isInteger(user.userStatus), 'user.userStatus is integer'); + Assert.ok(user.userStatus > 1000, 'user.userStatus is greater than 1000'); + Assert.ok(user.userStatus % 100 === 0, 'user.userStatus is multipleOf 100'); Assert.ok(typeof user.username === 'string', 'user.username is string'); done(); diff --git a/tests/params_mockgen.js b/tests/params_mockgen.js index 6232d91..a4f5208 100644 --- a/tests/params_mockgen.js +++ b/tests/params_mockgen.js @@ -18,7 +18,7 @@ describe('Parameters Mock generator', () => { Assert.ok(params, 'Generated parameters'); Assert.ok(params.path, 'Generated path parameter'); Assert.ok(params.path[0].name === 'orderId', 'generated mock parameter for orderId'); - Assert.ok(params.path[0].value > 0 && params.path[0].value < 10, 'OK value for orderId'); + Assert.ok(params.path[0].value >= 1 && params.path[0].value <= 10, 'OK value for orderId'); done(); }).catch(err => { Assert.ok(!err, 'No error'); From 1420d9d3a39e22520d28e815229ceac05898769f Mon Sep 17 00:00:00 2001 From: suchothendav Date: Mon, 12 Sep 2016 17:19:41 -0700 Subject: [PATCH 09/10] Fix mock gen issue for type number with minimum =0 #28 --- lib/generators/index.js | 23 +++++++++++++---------- tests/fixture/petstore.json | 19 +++++++++++++++++++ tests/param_mockgen.js | 16 ++++++++++++++-- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/lib/generators/index.js b/lib/generators/index.js index 52c0808..1cf7fb8 100644 --- a/lib/generators/index.js +++ b/lib/generators/index.js @@ -95,7 +95,7 @@ const integerMock = schema => { if (Number.isInteger(schema.multipleOf) && schema.multipleOf > 0) { //Use the min/muplilier as the min number //Use default min as 1 if min is not properly set. - opts.min = (Number.isInteger(opts.min) && opts.min > 0) ? (Math.ceil(opts.min / schema.multipleOf)) : 1; + opts.min = (Number.isInteger(opts.min)) ? (Math.ceil(opts.min / schema.multipleOf)) : 1; //Use the max/muplilier as the new max value //Use a default - min + 10 - if max value is not properly set. opts.max = (Number.isInteger(opts.max)) ? (Math.floor(opts.max / schema.multipleOf)) : (opts.min + 10); @@ -123,19 +123,22 @@ const numberMock = schema => { return enumMock(schema); } - if (schema.minimum) { - opts.min = (schema.exclusiveMinimum) ? schema.minimum : schema.minimum + 0.1; + if (Number.isFinite(schema.minimum)) { + opts.min = (schema.exclusiveMinimum) ? schema.minimum + 0.1 : schema.minimum; } - if (schema.maximum) { - opts.max = (schema.exclusiveMaximum) ? schema.maximum : schema.maximum - 0.1; + if (Number.isFinite(schema.maximum)) { + opts.max = (schema.exclusiveMaximum) ? schema.maximum - 0.1 : schema.maximum ; } //Generate a number that is multiple of schema.multipleOf - if (schema.multipleOf > 0) { - //Use the muplilier as the min number - opts.min = schema.multipleOf; + if (Number.isFinite(schema.multipleOf) && schema.multipleOf > 0) { + //Use the min/muplilier as the min number + //Use default min as 1 if min is not properly set + opts.min = (Number.isFinite(opts.min)) ? (Math.ceil(opts.min / schema.multipleOf)) : 1; //Use the max/muplilier as the new max value - opts.max = (opts.max) ? opts.max / schema.multipleOf : opts.max; - nummock = Chance.floating(opts); + //Use a default - min + 10 - if max value is not properly set. + opts.max = (Number.isFinite(opts.max)) ? (Math.floor(opts.max / schema.multipleOf)) : (opts.min + 10); + + nummock = Chance.integer(opts); nummock = nummock * schema.multipleOf; } else { nummock = Chance.floating(opts); diff --git a/tests/fixture/petstore.json b/tests/fixture/petstore.json index 8e67f5c..cf8c6a3 100644 --- a/tests/fixture/petstore.json +++ b/tests/fixture/petstore.json @@ -203,6 +203,25 @@ "required": true, "type": "string", "pattern": "awesome+ (pet|cat|bird)" + }, + { + "name": "petWeight", + "in": "query", + "description": "Weight of pet to return", + "required": false, + "type": "number", + "minimum": 10, + "maximum": 500 + }, + { + "name": "bmi", + "in": "query", + "description": "bmi of the pet", + "required": false, + "type": "number", + "minimum": 0, + "maximum": 1, + "multipleOf": 0.2 }], "responses": { "200": { diff --git a/tests/param_mockgen.js b/tests/param_mockgen.js index dc66d70..2d45b1a 100644 --- a/tests/param_mockgen.js +++ b/tests/param_mockgen.js @@ -57,8 +57,20 @@ describe('Parameter Mock generator', () => { Assert.ok(params.path[0].value >= 1000 && params.path[0].value <= 2000, 'OK value for petId'); Assert.ok(params.query, 'Generated query parameter'); - Assert.ok(params.query[0].name === 'petName', 'generated mock parameter for petName'); - Assert.ok(/awesome+ (pet|cat|bird)/.test(params.query[0].value), 'OK value for petName'); + params.query.forEach(param => { + if (param.name === 'petName') { + Assert.ok(/awesome+ (pet|cat|bird)/.test(param.value), 'OK value for petName'); + } + if (param.name === 'petWeight') { + Assert.ok(Number.isFinite(param.value), 'OK value for petWeight'); + Assert.ok(param.value <= 500 && param.value >= 10, 'OK value for petWeight'); + } + if (param.name === 'bmi') { + Assert.ok(Number.isFinite(param.value), 'OK value for bmi'); + Assert.ok(param.value <= 1 && param.value >= 0, 'OK value for bmi'); + } + }); + done(); }); }); From 38e3c7f1fde1886673b2dc18fa456a62363d970f Mon Sep 17 00:00:00 2001 From: suchothendav Date: Tue, 13 Sep 2016 11:16:14 -0700 Subject: [PATCH 10/10] travis ci to es6 --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d59297b..f2b232a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,10 @@ language: node_js node_js: - - "0.10" - - "4" + - "6" script: - - "npm run-script cover" + - "npm run lint" + - "npm run cover" sudo: false