diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 5ae3e97..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/schema/swagger-spec"] - path = lib/schema/swagger-spec - url = https://github.com/wordnik/swagger-spec.git diff --git a/CHANGELOG.md b/CHANGELOG.md index 751670f..7af1123 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +### 1.0.0-rc.1 + +* `options.docs` is `options.docspath` and defaults to `/`. + ### 0.1.0-alpha.6 WARNING: Breaking changes! diff --git a/README.md b/README.md index 46e5715..9e00fd1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # swaggerize-express -- **Version:** `0.1.0-alpha.6` +- **Version:** `1.0.0-rc.1` - **Stability:** `unstable` - **Changelog:** [https://github.com/krakenjs/swaggerize-express/blob/master/CHANGELOG.md](https://github.com/krakenjs/swaggerize-express/blob/master/CHANGELOG.md) @@ -33,7 +33,7 @@ var swaggerize = require('swaggerize-express'); app.use(swaggerize({ api: require('./api.json'), - docs: '/api-docs', + docspath: '/api-docs', handlers: './handlers' })); ``` @@ -41,7 +41,7 @@ app.use(swaggerize({ Options: - `api` - a valid Swagger 1.2 document. -- `docs` - the path to expose api docs for swagger-ui, etc. Defaults to `/api-docs`. +- `docspath` - the path to expose api docs for swagger-ui, etc. Defaults to `/`. - `handlers` - either a directory structure for route handlers or a premade object (see *Handlers Object* below). The base url for the api can also be updated via the `setUrl` function on the middleware. @@ -59,7 +59,7 @@ var server = http.createServer(app); var swagger = swaggerize({ api: require('./api.json'), - docs: '/api-docs', + docspath: '/api-docs', handlers: './handlers' }); @@ -86,11 +86,13 @@ handlers |--baz.js ``` -Matches: +Routes as: -- `foo.js : /foo` -- `foo/bar.js : /foo/bar` -- `baz.js : /baz` +``` +foo.js => /foo +foo/bar.js => /foo/bar +baz.js => /baz +``` ### Path Parameters @@ -178,13 +180,3 @@ swaggerize --api config/api.json --models resources/models --handlers resources/ ``` `--api` is required, but only one of `--models` or `--handlers` or `--tests` is required. - -### Contribution - -In order to run the swaggerize-express unit tests, execute the following commands: - -```bash -$ git submodule update --init --recursive -$ npm install -$ npm test -``` diff --git a/bin/lib/swaggerize.js b/bin/lib/swaggerize.js index 1edae20..bc80f1a 100644 --- a/bin/lib/swaggerize.js +++ b/bin/lib/swaggerize.js @@ -4,7 +4,7 @@ var minimist = require('minimist'), fs = require('fs'), path = require('path'), mkdirp = require('mkdirp'), - schema = require('../../lib/schema'), + schema = require('swaggerize-builder/lib/schema'), create = require('./create'); module.exports = function (argp) { diff --git a/bin/swaggerize.js b/bin/swaggerize.js index 14d2dd7..dc3d544 100755 --- a/bin/swaggerize.js +++ b/bin/swaggerize.js @@ -1,8 +1,7 @@ #!/usr/bin/env node 'use strict'; -var minimist = require('minimist'), - swaggerize = require('swaggerize-express/bin/lib/swaggerize'); +var swaggerize = require('swaggerize-express/bin/lib/swaggerize'); var result = swaggerize(process.argv); diff --git a/lib/buildroutes.js b/lib/buildroutes.js deleted file mode 100644 index 45287ee..0000000 --- a/lib/buildroutes.js +++ /dev/null @@ -1,84 +0,0 @@ -'use strict'; - -var utils = require('./utils'), - validation = require('./validation'), - readhandlers = require('./readhandlers'); - -/** - * Convert definition of api to something we can work with. - * @param options - * @returns {Array} - */ -function buildroutes(options) { - var routes, handlers; - - handlers = readhandlers(options.handlers); - - routes = []; - - options.api.apis.forEach(function (def) { - var path, models; - - path = def.path; - - models = options.api.models; - - def.operations.forEach(function (operation) { - var route, pathnames, model; - - route = { - name: operation.nickname, - path: utils.convertPath(path), - method: undefined, - validators: [], - handler: undefined - }; - - route.method = operation.method.toLowerCase(); - - model = models && models[operation.type] || operation.type; - - operation.parameters && operation.parameters.forEach(function (parameter) { - var model = models && models[parameter.type] || parameter.type; - - route.validators.push(validation.input(parameter, model)); - }); - - pathnames = []; - - //Figure out the names from the params. - path.split('/').forEach(function (element) { - if (element) { - pathnames.push(element); - } - }); - - route.handler = matchpath('$' + operation.method.toLowerCase(), pathnames, handlers[pathnames[0]]); - - routes.push(route); - }); - }); - - return routes; -} - -/** - * Match a route handler to a given path name set. - * @param method - * @param pathnames - * @param handlers - * @returns {*} - */ -function matchpath(method, pathnames, handlers) { - if (!handlers) { - return null; - } - if (pathnames.length > 1) { - pathnames.shift(); - return matchpath(method, pathnames, handlers[pathnames[0]]); - } - - return handlers[pathnames[0]] ? handlers[pathnames[0]] : handlers[method]; -} - -module.exports = buildroutes; diff --git a/lib/expressroutes.js b/lib/expressroutes.js index d974fa1..c9ef0f7 100644 --- a/lib/expressroutes.js +++ b/lib/expressroutes.js @@ -1,8 +1,7 @@ 'use strict'; var path = require('path'), - utils = require('./utils'), - buildroutes = require('./buildroutes'), + utils = require('swaggerize-builder/lib/utils'), thing = require('core-util-is'); /** @@ -12,34 +11,57 @@ var path = require('path'), * @param options */ function expressroutes(router, options) { - var routes; + var routes = options.routes || []; - routes = buildroutes(options); - - router.get(options.api.resourcePath + utils.prefix(options.docs || '/api-docs', '/'), function (req, res) { + router.get(options.api.resourcePath + utils.prefix(options.docspath || '', '/'), function (req, res) { res.json(options.api); }); routes.forEach(function (route) { - var args; + var args, path, before; + + path = route.path.replace(/{([^}]+)}/g, ':$1'); + args = [options.api.resourcePath + utils.prefix(path, '/')]; + before = []; + + route.validators.forEach(function (validator) { + var parameter, validate; + + parameter = validator.parameter; + validate = validator.validate; + + before.push(function validateInput(req, res, next) { + var value, isPath; + + isPath = parameter.paramType === 'path' || parameter.paramType === 'query'; + value = isPath ? req.param(parameter.name) : req.body; + + validate(value, function (error, newvalue) { + if (error) { + res.statusCode = 400; + next(error); + return; + } + + if (isPath) { + req.params[parameter.name] = newvalue; + } - //If a handler exists, add it. - if (route.handler) { - args = [options.api.resourcePath + utils.prefix(route.path, '/')]; + next(); + }); + }); + }); - if (thing.isArray(route.handler)) { - if (route.handler.length > 1) { - Array.prototype.push.apply(route.validators, route.handler.slice(0, route.handler.length - 1)); - } - route.handler = route.handler[route.handler.length - 1]; + if (thing.isArray(route.handler)) { + if (route.handler.length > 1) { + Array.prototype.push.apply(before, route.handler.slice(0, route.handler.length - 1)); } - Array.prototype.push.apply(args, route.validators); - args.push(route.handler); - router[route.method].apply(router, args); - return; + route.handler = route.handler[route.handler.length - 1]; } - utils.debuglog('no matching handler for %s.', route.path); + Array.prototype.push.apply(args, before); + args.push(route.handler); + router[route.method].apply(router, args); }); } diff --git a/lib/index.js b/lib/index.js index 123c2db..d900f63 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,36 +1,25 @@ 'use strict'; var assert = require('assert'), - schema = require('./schema'), express = require('express'), thing = require('core-util-is'), path = require('path'), - fs = require('fs'), caller = require('caller'), expressroutes = require('./expressroutes'), - utils = require('./utils'), - url = require('url'); + url = require('url'), + builder = require('swaggerize-builder'); function swaggerize(options) { - var app, validation, basePath; + var app; assert.ok(thing.isObject(options), 'Expected options to be an object.'); assert.ok(thing.isObject(options.api), 'Expected an api definition.'); - basePath = url.parse(options.api.basePath); - options.api.resourcePath = utils.prefix(options.api.resourcePath || '/', '/'); - basePath.path = basePath.pathname = options.api.resourcePath; - options.api.basePath = url.format(basePath); + options.basedir = path.dirname(caller()); - validation = schema.validate(options.api); + options.routes = builder(options); - assert.ifError(validation.error); - - if (thing.isString(options.handlers) || !options.handlers) { - options.handlers = options.handlers && path.resolve(options.handlers) || path.join(path.dirname(caller()), 'handlers'); - } - - options.docs = options.docs || '/api-docs'; + options.docspath = options.docspath || '/'; app = express(); @@ -44,8 +33,9 @@ function swaggerize(options) { Object.defineProperty(app, 'setUrl', { enumerable: true, value: function (value) { - value = url.parse(value); + var basePath = url.parse(options.api.basePath); + value = url.parse(value); value.protocol && (basePath.protocol = value.protocol); value.host && (basePath.host = value.host); @@ -64,7 +54,6 @@ function swaggerize(options) { function mount(options) { return function onmount(parent) { parent._router.stack.pop(); - expressroutes(parent._router, options); }; } diff --git a/lib/readhandlers.js b/lib/readhandlers.js deleted file mode 100644 index 52fb6b9..0000000 --- a/lib/readhandlers.js +++ /dev/null @@ -1,70 +0,0 @@ -'use strict'; - -var assert = require('assert'), - thing = require('core-util-is'), - path = require('path'), - fs = require('fs'); - -/** - * Reads the given path and requires all .js files. - * @param path - * @returns {{}} - */ -function read(dir) { - var routes, obj; - - if (thing.isString(dir)) { - assert.ok(fs.existsSync(dir), 'Specifed or default \'handlers\' directory does not exist.'); - - routes = {}; - - fs.readdirSync(dir).forEach(function (name) { - var abspath, key, stat; - - abspath = path.join(dir, name); - stat = fs.statSync(abspath); - key = name.replace(/\.js/, ''); - - if (stat.isFile()) { - if (name.match(/^.*\.(js)$/)) { - obj = require(abspath); - - if (!routes[key]) { - routes[key] = {}; - } - - Object.keys(obj).forEach(function (k) { - routes[key][isHttpMethod(k) ? '$' + k.toLowerCase() : k] = obj[k]; - }); - } - } - if (stat.isDirectory()) { - routes[key] = read(abspath); - } - }); - - return routes; - } - return dir; -} - -/** - * Determines if the given method is a supported HTTP method. - * @param method - * @returns {boolean} - */ -function isHttpMethod(method) { - return (typeof method === 'string') && { - get: 'GET', - post: 'POST', - put: 'PUT', - delete: 'DELETE', - head: 'HEAD', - options: 'OPTIONS', - trace: 'TRACE', - connect: 'CONNECT', - patch: 'PATCH' - }.hasOwnProperty(method.toLowerCase()); -} - -module.exports = read; \ No newline at end of file diff --git a/lib/schema/index.js b/lib/schema/index.js deleted file mode 100644 index b46cdd6..0000000 --- a/lib/schema/index.js +++ /dev/null @@ -1,41 +0,0 @@ -'use strict'; - -var tv4 = require('tv4'), - assert = require('assert'), - fs = require('fs'), - path = require('path'); - -var schemaPath, baseSchemaPath, baseSchema, modelSchema; - -schemaPath = path.join(__dirname, 'swagger-spec/schemas/v1.2'); -baseSchemaPath = path.join(schemaPath, 'apiDeclaration.json'); -modelSchema = require(path.join(schemaPath, 'modelsObject')); - -assert.ok(fs.existsSync(schemaPath)); -assert.ok(fs.existsSync(baseSchemaPath)); - -baseSchema = require(baseSchemaPath); - -fs.readdirSync(schemaPath).forEach(function (file) { - var schema; - - schema = require(path.join(schemaPath, file)); - - tv4.addSchema(schema); -}); - -module.exports = { - /** - * Validate against an optional schema, defaulting to base api schema. - * @param data - * @param schema - * @returns {*} - */ - validate: function validate(data, schema) { - var results; - - results = tv4.validateResult(data, schema || baseSchema, true); - - return results; - } -}; diff --git a/lib/schema/swagger-spec b/lib/schema/swagger-spec deleted file mode 160000 index 6d932fc..0000000 --- a/lib/schema/swagger-spec +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6d932fcb84323a3e5704cf1abdee443e1086ca69 diff --git a/lib/utils.js b/lib/utils.js deleted file mode 100644 index e4cc7db..0000000 --- a/lib/utils.js +++ /dev/null @@ -1,63 +0,0 @@ -'use strict'; - -var pkg = require('../package.json'); - -module.exports = { - debuglog: require('debuglog')(pkg.name), - - convertPath: function (path) { - return path.replace(/{([^}]+)}/g, ':$1'); - }, - - endsWith: function (haystack, needle) { - if (!haystack || !needle) { - return false; - } - - if (needle.length === 1) { - return haystack[haystack.length - 1] === needle; - } - - return haystack.slice(haystack.length - needle.length) === needle; - }, - - prefix: function (str, pre) { - str = str || ''; - if (str.indexOf(pre) === 0) { - return str; - } - - str = pre + str; - return str; - }, - - unprefix: function (str, pre) { - str = str || ''; - if (str.indexOf(pre) === 0) { - str = str.substr(pre.length); - return str; - } - - return str; - }, - - suffix: function (str, suff) { - str = str || ''; - if (this.endsWith(str, suff)) { - return str; - } - - str = str + suff; - return str; - }, - - unsuffix: function (str, suff) { - str = str || ''; - if (this.endsWith(str, suff)) { - str = str.substr(0, str.length - suff.length); - return str; - } - - return str; - } -}; diff --git a/lib/validation.js b/lib/validation.js deleted file mode 100644 index 11203da..0000000 --- a/lib/validation.js +++ /dev/null @@ -1,180 +0,0 @@ -'use strict'; - -var thing = require('core-util-is'), - schema = require('./schema'), - utils = require('./utils'); - -/** - * Creates validation middleware for a parameter. - * @param parameter - * @param model - * @returns {validateInput} - */ -function inputValidator(parameter, model) { - var coerce, validate, isPath; - - validate = model && map(model); - - isPath = parameter.paramType === 'path' || parameter.paramType === 'query'; - - if (parameter.type !== 'string') { - coerce = coercion(model); - } - - return function validateInput(req, res, next) { - var value = isPath ? req.param(parameter.name) : req.body; - - if (!value && parameter.required) { - utils.debuglog('required parameter \'%s\' missing.', parameter.name); - res.statusCode = 400; - next(new Error('required parameter \'' + parameter.name + '\' missing.')); - return; - } - - if (validate) { - coerce && (value = coerce(value)); - isPath && (req.params[parameter.name] = value); - - if (!value && !parameter.required) { - next(); - return; - } - - validate(value, function (error) { - if (error) { - utils.debuglog('error validating model schema \'%s\' for \'%s\'.', model, parameter.name); - res.statusCode = 400; - next(new Error(error.message)); - return; - } - - next(); - }); - - return; - } - - next(); - }; -} - -/** - * Create an output validator for the given model. - * @param model - * @returns {Function} - */ -function outputValidator(model) { - var coerce, validate; - - validate = model && map(model); - coerce = validate && coercion(model); - - return function validateOutput(data, callback) { - var value; - - if (validate) { - value = data && coerce ? coerce(data) : data; - - validate(value, function (error) { - if (error) { - callback(error); - return; - } - callback(null); - }); - } - }; -} - -/** - * Maps a type to a schema. - * @param type - * @returns {validate} - */ -function map(model) { - if (thing.isString(model)) { - model = { - type: model - }; - } - - return function validate(data, callback) { - var value, result, error; - - value = !thing.isObject(data) && model.id ? {} : data || def(model.type); - - result = schema.validate(value, model); - result.valid || (error = result.error); - - callback(error); - }; -} - -/** - * Default value for a null value of type. - * @param type - * @returns {*} - */ -function def(type) { - if (!type) { - return undefined; - } - - switch (type) { - case 'integer': - case 'float': - case 'long': - case 'double': - case 'byte': - return 0; - case 'string': - return String(); - case 'boolean': - return false; - default: - return undefined; - } -} - -/** - * Returns a function that coerces a type. - * Coercion of doubles and longs are not supported in Javascript and strings should be used instead for 64bit numbers. - * @param type - */ -function coercion(type) { - var fn; - - switch (type) { - case 'integer': - case 'float': - case 'long': - case 'double': - fn = function (data) { - if (isNaN(data)) { - return data; - } - return Number(data); - }; - break; - case 'string': - fn = String; - break; - case 'byte': - fn = function (data) { - return isNaN(data) ? new Buffer(data)[0] : Number(data); - }; - break; - case 'boolean': - fn = Boolean; - break; - case 'date': - case 'dateTime': - fn = Date.parse; - break; - } - - return fn; -} - -module.exports.input = inputValidator; -module.exports.output = outputValidator; diff --git a/package.json b/package.json index 8a8bde9..929d7f0 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,13 @@ { "name": "swaggerize-express", - "version": "0.1.0-alpha.6", + "version": "1.0.0-rc.1", "author": "Trevor Livingston ", - "description": "Spec-first driven swagger express routing.", + "description": "Spec-first REST services with Swagger and Express.", "keywords": [ "swagger", + "swagger-node", + "swagger-express", + "swagger-ui", "express", "node", "node.js", @@ -26,14 +29,13 @@ "node": "0.10.x" }, "dependencies": { - "async": "^0.9.0", + "swaggerize-builder": "^1.0.0", "caller": "^0.0.1", "core-util-is": "^1.0.1", "debuglog": "^1.0.1", "lodash": "^2.4.1", "minimist": "^0.2.0", - "mkdirp": "^0.5.0", - "tv4": "^1.1.0" + "mkdirp": "^0.5.0" }, "peerDependencies": { "express": "^4.0.0" diff --git a/test/test-expressroutes.js b/test/test-expressroutes.js index 48fe40d..aced579 100644 --- a/test/test-expressroutes.js +++ b/test/test-expressroutes.js @@ -2,13 +2,12 @@ var test = require('tape'), expressroutes = require('../lib/expressroutes'), - express = require('express'), - request = require('supertest'); + express = require('express'); test('express routes', function (t) { t.test('test api', function (t) { - t.plan(6); + t.plan(3); var app = express(), child = express(); @@ -17,17 +16,22 @@ test('express routes', function (t) { expressroutes(app, { api: require('./fixtures/api.json'), - handlers: require('path').join(__dirname, 'handlers') + docspath: '/api-docs', + routes: [ + { + method: 'get', + path: '/hello/:subject', + validators: [], + handler: function (req, res) {} + } + ] }); stack = Array.prototype.slice.call(parent._router.stack, 3); - t.strictEqual(stack.length, 5, 'routes added.'); + t.strictEqual(stack.length, 2, '2 routes added.'); t.strictEqual(stack[0].route.path, '/v1/greetings/api-docs', 'api-docs added.'); t.strictEqual(stack[1].route.path, '/v1/greetings/hello/:subject', 'hello added.'); - t.strictEqual(stack[2].route.path, '/v1/greetings/sub/:id', 'sub added.'); - t.strictEqual(stack[3].route.path, '/v1/greetings/sub/:id', 'sub added (head).'); - t.strictEqual(stack[4].route.path, '/v1/greetings/sub/:id/path', 'sub/path added.'); }); app.use(child); @@ -43,9 +47,9 @@ test('express routes', function (t) { expressroutes(app, { api: require('./fixtures/api.json'), - handlers: { - - } + docspath: '/api-docs', + validators: [], + routes: [] }); stack = Array.prototype.slice.call(parent._router.stack, 3); @@ -57,8 +61,8 @@ test('express routes', function (t) { app.use(child); }); - t.test('test variable filenames', function (t) { - t.plan(7); + t.test('test middlewares in handler', function (t) { + t.plan(4); var app = express(), child = express(); @@ -67,18 +71,26 @@ test('express routes', function (t) { expressroutes(app, { api: require('./fixtures/collections.json'), - handlers: require('path').join(__dirname, 'handlers') + docspath: '/api-docs', + routes: [ + { + method: 'get', + path: '/middlewares', + validators: [], + handler: [ + function m1(req, res, next) {}, + function (req, res) {} + ] + } + ] }); stack = Array.prototype.slice.call(parent._router.stack, 3); - t.strictEqual(stack.length, 4, 'three routes added.'); - t.strictEqual(stack[0].route.path, '/v1/collections/api-docs', 'api-docs added.'); - t.strictEqual(stack[1].route.path, '/v1/collections/stuffs', '/stuffs added.'); - t.strictEqual(stack[2].route.path, '/v1/collections/stuffs/:id', '/stuffs/:id added.'); - t.strictEqual(stack[3].route.path, '/v1/collections/middlewares', '/middlewares added.'); - t.strictEqual(stack[3].route.stack.length, 2, '/middlewares has middleware.'); - t.strictEqual(stack[3].route.stack[0].name, 'm1', '/middlewares has middleware named m1.'); + t.strictEqual(stack.length, 2, '2 routes added.'); + t.strictEqual(stack[1].route.path, '/v1/collections/middlewares', '/middlewares added.'); + t.strictEqual(stack[1].route.stack.length, 2, '/middlewares has middleware.'); + t.strictEqual(stack[1].route.stack[0].name, 'm1', '/middlewares has middleware named m1.'); }); app.use(child); diff --git a/test/test-routebuilder.js b/test/test-routebuilder.js deleted file mode 100644 index fd5989f..0000000 --- a/test/test-routebuilder.js +++ /dev/null @@ -1,52 +0,0 @@ -'use strict'; - -var test = require('tape'), - api = require('./fixtures/api.json'), - path = require('path'), - buildroutes = require('../lib/buildroutes'); - -test('routebuilder', function (t) { - - t.test('build', function (t) { - var routes; - - routes = buildroutes({ api: api, handlers: path.join(__dirname, 'handlers') }); - - t.strictEqual(routes.length, 5, 'added 5 routes.'); - - routes.forEach(function (route) { - t.ok(route.hasOwnProperty('method'), 'has method property.'); - t.ok(route.hasOwnProperty('name'), 'has name property.'); - t.ok(route.hasOwnProperty('path'), 'has path property.'); - t.ok(route.hasOwnProperty('validators'), 'has validators property.'); - }); - - t.end(); - }); - - t.test('collections', function (t) { - var routes; - - routes = buildroutes({ api: require('./fixtures/collections.json'), handlers: path.join(__dirname, 'handlers') }); - - t.strictEqual(routes.length, 3, 'added 2 routes.'); - - routes.forEach(function (route) { - t.ok(route.hasOwnProperty('method'), 'has method property.'); - t.ok(route.hasOwnProperty('name'), 'has name property.'); - t.ok(route.hasOwnProperty('path'), 'has path property.'); - t.ok(route.hasOwnProperty('validators'), 'has validators property.'); - }); - - t.end(); - }); - - t.test('bad dir', function (t) { - t.plan(1); - - t.throws(function () { - buildroutes({ api: api, handlers: 'asdf' }); - }, 'throws error for bad directory.'); - }); - -}); diff --git a/test/test-schema.js b/test/test-schema.js deleted file mode 100644 index fe5598c..0000000 --- a/test/test-schema.js +++ /dev/null @@ -1,101 +0,0 @@ -'use strict'; - -var test = require('tape'), - schema = require('../lib/schema'), - apiDefinition = require('./fixtures/api.json'); - -test('schema', function (t) { - - t.test('good api', function (t) { - t.plan(1); - - var results = schema.validate(apiDefinition); - - t.ok(results.valid, 'no errors'); - }); - - t.test('bad api', function (t) { - t.plan(2); - - var results = schema.validate({ - "swaggerVersion": "1.2", - "basePath": "http://localhost:8000/greetings", - "apis": [ - { - "path": "/hello/{subject}", - "operations": [ - { - "method": "GET", - "summary": "Greet our subject with hello!", - "type": "string", - "parameters": [ - { - "name": "subject", - "description": "The subject to be greeted.", - "required": true, - "type": "string", - "paramType": "path" - } - ] - } - ] - } - ] - }); - - t.ok(!results.valid, 'bad'); - t.ok(results.error, 'has error.'); - }); - - t.test('good model', function (t) { - t.plan(1); - - var modelSchema = { - "id": "User", - "required": ["id", "name"], - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - } - } - }; - - var results = schema.validate({ - "id": 123, - "name": "John Doe" - }, modelSchema); - - t.ok(results.valid, 'no errors'); - }); - - t.test('bad model', function (t) { - t.plan(2); - - var modelSchema = { - "id": "User", - "required": ["id", "name"], - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - } - } - }; - - var results = schema.validate({ - "id": "asdf", - "name": "John Doe" - }, modelSchema); - - t.ok(!results.valid, 'bad'); - t.ok(results.error, 'has error.'); - }); - -}); diff --git a/test/test-swaggerize.js b/test/test-swaggerize.js index da5ad41..4dd5997 100644 --- a/test/test-swaggerize.js +++ b/test/test-swaggerize.js @@ -5,33 +5,33 @@ var test = require('tape'), express = require('express'), request = require('supertest'); -test('swaggycat valid input/output', function (t) { +test('swagger valid input/output', function (t) { var app = express(); - var swaggycat = swaggerize({ + var swagger = swaggerize({ api: require('./fixtures/api.json') }); - app.use(swaggycat); + app.use(swagger); t.test('api', function (t) { t.plan(5); - t.ok(swaggycat.hasOwnProperty('_api'), 'has _api property.'); - t.ok(swaggycat._api, '_api is an object.'); + t.ok(swagger.hasOwnProperty('_api'), 'has _api property.'); + t.ok(swagger._api, '_api is an object.'); - t.ok(swaggycat.hasOwnProperty('setUrl'), 'has setUrl property.'); - t.strictEqual(typeof swaggycat.setUrl, 'function', 'setUrl is a function.'); + t.ok(swagger.hasOwnProperty('setUrl'), 'has setUrl property.'); + t.strictEqual(typeof swagger.setUrl, 'function', 'setUrl is a function.'); - swaggycat.setUrl('http://localhost:8080'); + swagger.setUrl('http://localhost:8080'); - t.strictEqual(swaggycat._api.basePath, 'http://localhost:8080/v1/greetings'); + t.strictEqual(swagger._api.basePath, 'http://localhost:8080/v1/greetings'); }); t.test('docs', function (t) { t.plan(2); - request(app).get('/v1/greetings/api-docs').end(function (error, response) { + request(app).get('/v1/greetings/').end(function (error, response) { t.ok(!error, 'no error.'); t.strictEqual(response.statusCode, 200, '200 status.'); }); @@ -77,7 +77,7 @@ test('swaggycat valid input/output', function (t) { }); -test('swaggycat invalid input', function (t) { +test('input validators', function (t) { var app = express(); @@ -86,14 +86,14 @@ test('swaggycat invalid input', function (t) { handlers: { sub: { '{id}': { - $get: function (req, reply) { - reply('foobar'); + $get: function (req, res) { + res.send('foobar'); } } }, goodbye: { - $get: function (req, reply) { - reply('baz'); + $get: function (req, res) { + res.send('baz'); } } } diff --git a/test/test-utils.js b/test/test-utils.js deleted file mode 100644 index ab3bab5..0000000 --- a/test/test-utils.js +++ /dev/null @@ -1,95 +0,0 @@ -'use strict'; - -var test = require('tape'), - utils = require('../lib/utils'); - -test('utils', function (t) { - - t.test('convertPath', function (t) { - t.plan(1); - - var path = utils.convertPath('/foo/{id}/asdf/{name}'); - - t.strictEqual(path, '/foo/:id/asdf/:name', 'is converted.'); - }); - - t.test('prefix', function (t) { - t.plan(3); - - var str = 'foobar'; - - str = utils.prefix(str, 'foo'); - - t.equal(str, 'foobar', 'string had prefix so is the same.'); - - str = 'bar'; - - str = utils.prefix(str, 'foo'); - - t.equal(str, 'foobar', 'string did not have prefix so was changed.'); - - t.equal(utils.prefix(undefined, 'foo'), 'foo', 'handled undefined.'); - }); - - t.test('unprefix', function (t) { - t.plan(3); - - var str = 'foobar'; - - str = utils.unprefix(str, 'foo'); - - t.equal(str, 'bar', 'string had prefix so is changed.'); - - str = 'bar'; - - str = utils.unprefix(str, 'foo'); - - t.equal(str, 'bar', 'string did not have prefix so was not changed.'); - - t.equal(utils.unprefix(undefined, 'foo'), '', 'handled undefined.'); - }); - - t.test('suffix', function (t) { - t.plan(3); - - var str = 'foobar'; - - str = utils.suffix(str, 'bar'); - - t.equal(str, 'foobar', 'string had suffix so is the same.'); - - str = 'foo'; - - str = utils.suffix(str, 'bar'); - - t.equal(str, 'foobar', 'string did not have suffix so was changed.'); - - t.equal(utils.suffix(undefined, 'foo'), 'foo', 'handled undefined.'); - }); - - t.test('unsuffix', function (t) { - t.plan(3); - - var str = 'foobar'; - - str = utils.unsuffix(str, 'bar'); - - t.equal(str, 'foo', 'string had suffix so is changed.'); - - str = 'foo'; - - str = utils.unsuffix(str, 'bar'); - - t.equal(str, 'foo', 'string did not have suffix so was not changed.'); - - t.equal(utils.unsuffix(undefined, 'foo'), '', 'handled undefined.'); - }); - - t.test('ends with', function (t) { - t.plan(2); - t.ok(utils.endsWith('foobar', 'bar'), 'foobar ends with bar'); - t.ok(!utils.endsWith('foobar', 'x'), 'foobar doesn\'t end with x'); - }); - - -}); diff --git a/test/test-validation.js b/test/test-validation.js deleted file mode 100644 index f93a2ed..0000000 --- a/test/test-validation.js +++ /dev/null @@ -1,94 +0,0 @@ -'use strict'; - -var test = require('tape'), - validation = require('../lib/validation'); - -test('validation', function (t) { - var outputvalid, inputvalid; - - outputvalid = validation.output({ - "id": "User", - "required": ["id", "name"], - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer" - } - } - }); - - inputvalid = validation.input({ - paramType: 'query', - name: 'id', - required: true - }, 'integer'); - - t.test('input pass', function (t) { - t.plan(1); - - inputvalid({ - param: function () { - return this.params.id; - }, - params: { - id: 1 - }, - }, {}, function (error) { - t.ok(!error, 'no error.'); - }); - }); - - t.test('input fail (not present)', function (t) { - t.plan(1); - - inputvalid({ - param: function () { - return undefined; - }, - params: { - }, - }, {}, function (error) { - t.ok(error, 'error.'); - }); - }); - - t.test('input fail (wrong type)', function (t) { - t.plan(1); - - inputvalid({ - param: function () { - return this.params.id; - }, - params: { - id: 'a' - }, - }, {}, function (error) { - t.ok(error, 'error.'); - }); - }); - - t.test('output pass', function (t) { - t.plan(1); - - outputvalid({ - id: 1, - name: 'Joe' - }, function (error) { - t.ok(!error, 'no error.'); - }); - }); - - t.test('output fail', function (t) { - t.plan(1); - - outputvalid({ - id: 'a', - name: 'Joe' - }, function (error) { - t.ok(error, 'error.'); - }); - }); - -});