diff --git a/CHANGELOG.md b/CHANGELOG.md index dad09e1f8..a107d8730 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## 4.0.0 + +**Revitalized documentation.js command line interface!** + +The `documentation` utility now takes commands: + +* `documentation build` extracts and formats documentation +* `documentation serve` provides an auto-reloading server +* `documentation lint` reviews files for inconsistencies + +This functionality was previously included in `dev-documentation` and has +been folded into `documentation` proper. + ## 3.0.4 * Allow parameter types to be mixed into explicit parameter documentation. (#239 and #232) diff --git a/bin/documentation.js b/bin/documentation.js index 112862541..fceab47ea 100755 --- a/bin/documentation.js +++ b/bin/documentation.js @@ -5,41 +5,80 @@ 'use strict'; var documentation = require('../'), + chokidar = require('chokidar'), + debounce = require('debounce'), streamArray = require('stream-array'), fs = require('fs'), vfs = require('vinyl-fs'), - lint = require('../lib/lint'), - args = require('../lib/args.js'); + errorPage = require('../lib/error_page'), + Server = require('../lib/server'), + args = require('../lib/args'); -var parsedArgs = args(process.argv.slice(2)), - formatterOptions = parsedArgs.formatterOptions, - outputLocation = parsedArgs.output, - formatter = documentation.formats[parsedArgs.formatter]; +var parsedArgs = args(process.argv.slice(2)); -documentation(parsedArgs.inputs, parsedArgs.options, function (err, comments) { +var generator = documentation.bind(null, + parsedArgs.inputs, parsedArgs.options, onDocumented.bind(null, parsedArgs)); + +var server = new Server(); +server.on('listening', function () { + process.stdout.write('documentation.js serving on port 4001\n'); +}); + +function onDocumented(parsedArgs, err, comments) { if (err) { + if (parsedArgs.command === 'serve') { + return server.setFiles([errorPage(err)]).start(); + } throw err; } - if (parsedArgs.options.lint) { - var lintOutput = lint.format(comments); + documentation.formats[parsedArgs.formatter]( + comments, parsedArgs.formatterOptions, + onFormatted.bind(null, parsedArgs)); +} + +function onFormatted(parsedArgs, err, output) { + if (parsedArgs.watch) { + updateWatcher(); + } + + if (parsedArgs.command === 'serve') { + server.setFiles(output).start(); + } else if (parsedArgs.output === 'stdout') { + process.stdout.write(output); + } else if (Array.isArray(output)) { + streamArray(output).pipe(vfs.dest(parsedArgs.output)); + } else { + fs.writeFileSync(parsedArgs.output, output); + } +} + +if (parsedArgs.command === 'lint') { + documentation.lint(parsedArgs.inputs, parsedArgs.options, function (err, lintOutput) { + if (err) { + throw err; + } if (lintOutput) { console.log(lintOutput); process.exit(1); } else { process.exit(0); } + }); +} else { + generator(); + if (parsedArgs.watch) { + var watcher = chokidar.watch(parsedArgs.inputs); + watcher.on('all', debounce(generator, 300)); } +} - formatter(comments, formatterOptions, function (err, output) { - if (outputLocation !== 'stdout') { - if (parsedArgs.formatter === 'html') { - streamArray(output).pipe(vfs.dest(outputLocation)); - } else { - fs.writeFileSync(outputLocation, output); - } - } else { - process.stdout.write(output); - } - }); -}); +function updateWatcher() { + documentation.expandInputs(parsedArgs.inputs, parsedArgs.options, addNewFiles); +} + +function addNewFiles(err, files) { + watcher.add(files.map(function (data) { + return data.file; + })); +} diff --git a/index.js b/index.js index 743fe9006..87ae9e1dc 100644 --- a/index.js +++ b/index.js @@ -16,7 +16,8 @@ var sort = require('./lib/sort'), inferProperties = require('./lib/infer/properties'), inferMembership = require('./lib/infer/membership'), inferReturn = require('./lib/infer/return'), - lint = require('./lib/lint'); + formatLint = require('./lib/lint').formatLint, + lintComments = require('./lib/lint').lintComments; /** * Build a pipeline of comment handlers. @@ -45,6 +46,20 @@ function noop(comment) { return comment; } +/** + * Given an array of indexes and options for whether to resolve shallow + * or deep dependencies, resolve dependencies. + * + * @param {Array|string} indexes files to process + * @param {Object} options options + * @param {Function} callback called with results + * @returns {undefined} + */ +function expandInputs(indexes, options, callback) { + var inputFn = (options.polyglot || options.shallow) ? shallow : dependency; + inputFn(indexes, options, callback); +} + /** * Generate JavaScript documentation as a list of parsed JSDoc * comments, given a root file as a path. @@ -75,17 +90,16 @@ module.exports = function (indexes, options, callback) { indexes = [indexes]; } - var inputFn = (options.polyglot || options.shallow) ? shallow : dependency; var parseFn = (options.polyglot) ? polyglot : parseJavaScript; - return inputFn(indexes, options, function (error, inputs) { + return expandInputs(indexes, options, function (error, inputs) { if (error) { return callback(error); } try { callback(null, filterAccess( - (options.private || options.lint) ? [] : undefined, + options.private ? [] : undefined, hierarchy( inputs .filter(filterJS) @@ -93,7 +107,6 @@ module.exports = function (indexes, options, callback) { return memo.concat(parseFn(file)); }, []) .map(pipeline( - lint.lint, inferName(), inferKind(), inferParams(), @@ -111,6 +124,62 @@ module.exports = function (indexes, options, callback) { }); }; +/** + * Lint files for non-standard or incorrect documentation + * information, returning a potentially-empty string + * of lint information intended for human-readable output. + * + * @param {Array|string} indexes files to process + * @param {Object} options options + * @param {Array} options.external a string regex / glob match pattern + * that defines what external modules will be whitelisted and included in the + * generated documentation. + * @param {Array} options.transform source transforms given as strings + * passed to [the module-deps transform option](https://github.com/substack/module-deps) + * @param {boolean} [options.polyglot=false] parse comments with a regex rather than + * a proper parser. This enables support of non-JavaScript languages but + * reduces documentation's ability to infer structure of code. + * @param {boolean} [options.shallow=false] whether to avoid dependency parsing + * even in JavaScript code. With the polyglot option set, this has no effect. + * @param {Function} callback to be called when the documentation generation + * is complete, with (err, result) argumentsj + * @returns {undefined} calls callback + */ +module.exports.lint = function lint(indexes, options, callback) { + options = options || {}; + + if (typeof indexes === 'string') { + indexes = [indexes]; + } + + var parseFn = (options.polyglot) ? polyglot : parseJavaScript; + + return expandInputs(indexes, options, function (error, inputs) { + if (error) { + return callback(error); + } + callback(null, + formatLint(hierarchy( + inputs + .filter(filterJS) + .reduce(function (memo, file) { + return memo.concat(parseFn(file)); + }, []) + .map(pipeline( + lintComments, + inferName(), + inferKind(), + inferParams(), + inferProperties(), + inferReturn(), + inferMembership(), + nest)) + .filter(Boolean)))); + }); +}; + +module.exports.expandInputs = expandInputs; + module.exports.formats = { html: require('./lib/output/html'), md: require('./lib/output/markdown'), diff --git a/lib/args.js b/lib/args.js index 8199d9104..e6501346c 100644 --- a/lib/args.js +++ b/lib/args.js @@ -2,70 +2,100 @@ var path = require('path'), yargs = require('yargs'), loadConfig = require('../lib/load_config.js'); -function parse(args) { - // reset() needs to be called at parse time because the yargs module uses an - // internal global variable to hold option state - return yargs.reset() - .usage('Usage: $0 [options]') - - .option('f', { - alias: 'format', - default: 'json', - choices: ['json', 'md', 'html'] - }) - - .option('lint', { - describe: 'check output for common style and uniformity mistakes', - type: 'boolean' - }) - - .describe('t', 'specify a theme: this must be a valid theme module') - .alias('t', 'theme') - - .boolean('p') - .describe('p', 'generate documentation tagged as private') - .alias('p', 'private') - - .version(function () { - return require('../package').version; - }) - - .describe('name', 'project name. by default, inferred from package.json') - .describe('project-version', 'project version. by default, inferred from package.json') - - .option('shallow', { +function commonOptions(parser) { + return parser.option('shallow', { describe: 'shallow mode turns off dependency resolution, ' + 'only processing the specified files (or the main script specified in package.json)', default: false, type: 'boolean' }) - - .boolean('polyglot') - .describe('polyglot', 'polyglot mode turns off dependency resolution and ' + - 'enables multi-language support. use this to document c++') - - .boolean('g') - .describe('g', 'infer links to github in documentation') - .alias('g', 'github') - - .option('o', { - describe: 'output location. omit for stdout, otherwise is a filename ' + - 'for single-file outputs and a directory name for multi-file outputs like html', - alias: 'output', - default: 'stdout' + .option('config', { + describe: 'configuration file. an array defining explicit sort order', + alias: 'c' + }) + .option('polyglot', { + type: 'boolean', + describe: 'polyglot mode turns off dependency resolution and ' + + 'enables multi-language support. use this to document c++' }) + .help('help'); +} - .describe('c', 'configuration file. an array defining explicit sort order') - .alias('c', 'config') +function outputOptions(parser) { + return parser.option('theme', { + describe: 'specify a theme: this must be a valid theme module', + alias: 't' + }) + .option('private', { + describe: 'generate documentation tagged as private', + type: 'boolean', + default: false, + alias: 'p' + }) + .option('name', { + describe: 'project name. by default, inferred from package.json' + }) + .option('github', { + type: 'boolean', + describe: 'infer links to github in documentation', + alias: 'g' + }) + .option('watch', { + describe: 'watch input files and rebuild documentation when they change', + alias: 'w', + type: 'boolean' + }) + .option('project-version', { + describe: 'project version. by default, inferred from package.json' + }); +} - .help('h') - .alias('h', 'help') +function parse(args) { + // reset() needs to be called at parse time because the yargs module uses an + // internal global variable to hold option state + var command = yargs.reset() + .usage('Usage: $0 [options]') + .demand(1) + .command('build', 'build documentation') + .command('lint', 'check for common style and uniformity mistakes') + .command('serve', 'generate, update, and display HTML documentation') + .version(function () { + return require('../package').version; + }) + .parse(args)._[0]; + + if (command === 'build') { + return outputOptions(commonOptions(yargs.reset())) + .option('format', { + alias: 'f', + default: 'json', + choices: ['json', 'md', 'html'] + }) + .option('output', { + describe: 'output location. omit for stdout, otherwise is a filename ' + + 'for single-file outputs and a directory name for multi-file outputs like html', + default: 'stdout', + alias: 'o' + }) + .example('$0 build foo.js -f md > API.md', 'parse documentation in a ' + + 'file and generate API documentation as Markdown') + .parse(args); + } - .example('$0 foo.js', 'parse documentation in a given file') + if (command === 'serve') { + return outputOptions(commonOptions(yargs.reset())).parse(args); + } - .parse(args) + if (command === 'lint') { + return commonOptions(yargs.reset()) + .example('$0 lint project.js', 'check documentation style') + .parse(args); + } + yargs.showHelp(); + process.exit(1); } + /** * Parse and validate command-line options for documentation. * @param {Array} args The array of arguments to parse; e.g. process.argv.slice(2). @@ -73,16 +103,14 @@ function parse(args) { * @private */ module.exports = function (args) { - var argv = parse(args); - - var inputs, + var argv = parse(args), + command = argv._[0], + inputs = argv._.slice(1), name = argv.name, version = argv['project-version'], transform; - if (argv._.length > 0) { - inputs = argv._; - } else { + if (inputs.length == 0) { try { var p = require(path.resolve('package.json')); inputs = [p.main || 'index.js']; @@ -97,11 +125,15 @@ module.exports = function (args) { } } - if (argv.f === 'html' && argv.o === 'stdout') { + if (argv.f === 'html' && argv.o === 'stdout' && !argv.serve) { yargs.showHelp(); throw new Error('The HTML output mode requires a destination directory set with -o'); } + if (command === 'serve') { + argv.format = 'html'; + } + var config = {}; if (argv.config) { @@ -110,16 +142,17 @@ module.exports = function (args) { return { inputs: inputs, + command: command, options: { private: argv.private, transform: transform, - lint: argv.lint, github: argv.github, polyglot: argv.polyglot, order: config.order || [], shallow: argv.shallow }, - formatter: argv.f, + formatter: argv.format, + watch: argv.w, formatterOptions: { name: name, version: version, @@ -128,5 +161,3 @@ module.exports = function (args) { output: argv.o } } - - diff --git a/lib/error_page.js b/lib/error_page.js new file mode 100644 index 000000000..9a94bd534 --- /dev/null +++ b/lib/error_page.js @@ -0,0 +1,25 @@ +var File = require('vinyl'); +var ansiHTML = require('ansi-html'); + +var template = ''; + +/** + * Given an error, generate an HTML page that represents the error. + * @param {Error} error parse or generation error + * @returns {Object} vinyl file object + */ +function errorPage(error) { + var errorText = error.toString(); + if (error.codeFrame) { + errorText += '
' + ansiHTML(error.codeFrame) + '
'; + } + return new File({ + path: 'index.html', + contents: new Buffer(template + errorText) + }); +} + +module.exports = errorPage; diff --git a/lib/infer/membership.js b/lib/infer/membership.js index 05540c9d3..645ad99f6 100644 --- a/lib/infer/membership.js +++ b/lib/infer/membership.js @@ -134,6 +134,7 @@ module.exports = function () { } return function inferMembership(comment) { + if (comment.module) { currentModule = comment; } diff --git a/lib/lint.js b/lib/lint.js index c2e69ee2c..0bc3f3c43 100644 --- a/lib/lint.js +++ b/lib/lint.js @@ -23,7 +23,7 @@ var CANONICAL = { * @param {Object} comment parsed comment * @returns {Array} array of errors */ -function lint(comment) { +function lintComments(comment) { comment.tags.forEach(function (tag) { function nameInvariant(name) { if (CANONICAL[name]) { @@ -37,13 +37,14 @@ function lint(comment) { function checkCanonical(type) { if (type.type === 'NameExpression') { nameInvariant(type.name); - } else if (type.type === 'UnionType') { - type.elements.forEach(checkCanonical); - } else if (type.type === 'OptionalType') { - checkCanonical(type.expression); - } else if (type.type === 'TypeApplication') { - checkCanonical(type.expression); - type.applications.map(checkCanonical); + } + + [type.elements, type.applications].forEach(checkSubtypes); + } + + function checkSubtypes(subtypes) { + if (Array.isArray(subtypes)) { + subtypes.forEach(checkCanonical); } } @@ -54,7 +55,7 @@ function lint(comment) { return comment; } -function format(comments) { +function formatLint(comments) { var vFiles = {}; walk(comments, function (comment) { comment.errors.forEach(function (error) { @@ -74,5 +75,5 @@ function format(comments) { })); } -module.exports.lint = lint; -module.exports.format = format; +module.exports.lintComments = lintComments; +module.exports.formatLint = formatLint; diff --git a/lib/server.js b/lib/server.js new file mode 100644 index 000000000..d3c0f7431 --- /dev/null +++ b/lib/server.js @@ -0,0 +1,105 @@ +var http = require('http'), + mime = require('mime'), + util = require('util'), + EventEmitter = require('events').EventEmitter, + liveReload = require('tiny-lr'); + +/** + * A static file server designed to support documentation.js's --serve + * option. It serves from an array of Vinyl File objects (virtual files in + * memory) and exposes a `setFiles` method that both replaces the set + * of files and notifies any browsers using LiveReload to reload + * and display the new content. + * @class + */ +function Server() { + this._files = []; +} + +util.inherits(Server, EventEmitter); + +/** + * Update the set of files exposed by this server and notify LiveReload + * clients + * + * @param {Array} files new content. replaces any previously-set content. + * @returns {Server} self + */ +Server.prototype.setFiles = function (files) { + this._files = files; + if (this._lr) { + this._lr.changed({ body: { files: '*' } }); + } + return this; +}; + +Server.prototype.handler = function (request, response) { + var path = request.url.substring(1); + if (path === '') { + path = 'index.html'; + } + for (var i = 0; i < this._files.length; i++) { + if (this._files[i].relative === path) { + response.writeHead(200, { 'Content-Type': mime.lookup(path) }); + this._files[i].pipe(response); + return; + } + } + response.writeHead(404, { 'Content-Type': 'text/plain' }); + response.end('Not found'); +}; + +/** + * Boot up the server's HTTP & LiveReload endpoints. This method + * can be called multiple times. + * + * @param {Function} [callback=] called when server is started + * @returns {undefined} + */ +Server.prototype.start = function (callback) { + + callback = callback || noop; + + // idempotent + if (this._lr) { + return callback(); + } + + this._lr = liveReload(); + this._http = http.createServer(this.handler.bind(this)); + + this._lr.listen(35729, function () { + this._http.listen(4001, function () { + this.emit('listening'); + callback(); + }.bind(this)); + }.bind(this)); +}; + +/** + * Shut down the server's HTTP & LiveReload endpoints. This method + * can be called multiple times. + * + * @param {Function} [callback=] called when server is closed + * @returns {undefined} + */ +Server.prototype.stop = function (callback) { + + callback = callback || noop; + + // idempotent + if (!this._lr) { + return callback(); + } + + this._http.close(function () { + this._lr.close(); + this._http = null; + this._lr = null; + callback(); + }.bind(this)); +}; + +function noop() {} + +module.exports = Server; diff --git a/package.json b/package.json index 70593f4e5..ef57bca02 100644 --- a/package.json +++ b/package.json @@ -15,13 +15,17 @@ "vinyl-fs": false }, "dependencies": { + "ansi-html": "0.0.4", "ast-types": "^0.8.12", - "babelify": "^6.3.0", "babel-core": "^5.0.0", + "babelify": "^6.3.0", "brfs": "^1.4.0", + "chokidar": "^1.2.0", "concat-stream": "^1.5.0", + "debounce": "^1.0.0", "doctrine": "^0.7.1", "documentation-theme-default": "^1.0.0", + "events": "^1.1.0", "extend": "^3.0.0", "get-comments": "^1.0.1", "github-url-from-git": "^1.4.0", @@ -34,6 +38,7 @@ "mdast-html": "^1.2.1", "mdast-toc": "^1.1.0", "micromatch": "^2.1.6", + "mime": "^1.3.4", "module-deps": "^3.7.3", "parse-filepath": "^0.6.3", "remote-origin-url": "^0.4.0", @@ -41,6 +46,7 @@ "slugg": "^0.1.2", "stream-array": "^1.1.0", "strip-json-comments": "^1.0.2", + "tiny-lr": "^0.2.1", "traverse": "^0.6.6", "unist-builder": "^1.0.0", "vfile": "^1.1.2", diff --git a/test/bin-watch-serve.js b/test/bin-watch-serve.js new file mode 100644 index 000000000..07a2616b9 --- /dev/null +++ b/test/bin-watch-serve.js @@ -0,0 +1,109 @@ +'use strict'; + +var test = require('tap').test, + path = require('path'), + os = require('os'), + get = require('./utils').get, + spawn = require('child_process').spawn, + fs = require('fs'); + +function documentation(args, options, callback, parseJSON) { + if (!callback) { + callback = options; + options = {}; + } + + if (!options.cwd) { + options.cwd = __dirname; + } + + options.maxBuffer = 1024 * 1024; + + return spawn( + path.join(__dirname, '../bin/documentation.js'), + args, + options); +} + +function normalize(result) { + result.forEach(function (item) { + item.context.file = '[path]'; + }); + return result; +} + +var options = { timeout: 1000 * 120 }; + +test('harness', function (t) { + var docProcess = documentation(['fixture/simple.input.js', '--serve']); + t.ok(docProcess, 'creates a subprocess object'); + docProcess.kill(); + t.end(); +}, options); + +test('provides index.html', function (t) { + var docProcess = documentation(['serve', 'fixture/simple.input.js']); + docProcess.stdout.on('data', function (data) { + t.equal(data.toString().trim(), 'documentation.js serving on port 4001', 'shows listening message'); + get('http://localhost:4001/', function (text) { + t.ok(text.match(//), 'sends an html index file'); + docProcess.kill(); + t.end(); + }); + }); +}, options); + +test('--watch', function (t) { + var tmpFile = path.join(os.tmpdir(), '/simple.js'); + fs.writeFileSync(tmpFile, '/** a function */function apples() {}'); + var docProcess = documentation(['serve', tmpFile, '--watch']); + docProcess.stdout.on('data', function (data) { + get('http://localhost:4001/', function (text) { + t.ok(text.match(/apples/), 'sends an html index file'); + fs.writeFileSync(tmpFile, '/** a function */function bananas() {}'); + setTimeout(function () { + get('http://localhost:4001/', function (text) { + t.ok(text.match(/bananas/), 'updates the file content'); + docProcess.kill(); + t.end(); + }); + }, 1000); + }); + }); +}, options); + +test('--watch', function (t) { + var tmpDir = os.tmpdir(); + var a = path.join(tmpDir, '/simple.js'); + var b = path.join(tmpDir, '/required.js'); + fs.writeFileSync(a, 'require("./required")'); + fs.writeFileSync(b, '/** soup */function soup() {}'); + var docProcess = documentation(['serve', a, '--watch']); + docProcess.stdout.on('data', function (data) { + get('http://localhost:4001/', function (text) { + t.ok(text.match(/soup/), 'sends an html index file'); + fs.writeFileSync(b, '/** nuts */function nuts() {}'); + setTimeout(function () { + get('http://localhost:4001/', function (text) { + t.ok(text.match(/nuts/), 'updates the file content even behind a require'); + docProcess.kill(); + t.end(); + }); + }, 1000); + }); + }); +}, options); + +test('error page', function (t) { + var tmpDir = os.tmpdir(); + var a = path.join(tmpDir, '/simple.js'); + fs.writeFileSync(a, '**'); + var docProcess = documentation(['serve', a, '--watch']); + docProcess.stdout.on('data', function (data) { + get('http://localhost:4001/', function (text) { + t.ok(text.match(/Unexpected token/), 'emits an error page'); + docProcess.kill(); + t.end(); + }); + }); +}, options); diff --git a/test/bin.js b/test/bin.js index b6ae2550d..57b73225e 100644 --- a/test/bin.js +++ b/test/bin.js @@ -42,7 +42,7 @@ function normalize(result) { var options = { timeout: 1000 * 120 }; test('documentation binary', function (t) { - documentation(['fixture/simple.input.js'], function (err, data) { + documentation(['build fixture/simple.input.js'], function (err, data) { t.error(err); t.equal(data.length, 1, 'simple has no dependencies'); t.end(); @@ -50,7 +50,7 @@ test('documentation binary', function (t) { }, options); test('defaults to parsing package.json main', function (t) { - documentation([], { cwd: path.join(__dirname, '..') }, function (err, data) { + documentation(['build'], { cwd: path.join(__dirname, '..') }, function (err, data) { t.error(err); t.ok(data.length, 'we document ourself'); t.end(); @@ -58,7 +58,7 @@ test('defaults to parsing package.json main', function (t) { }, options); test('accepts config file', function (t) { - documentation(['fixture/sorting/input.js -c fixture/config.json'], + documentation(['build fixture/sorting/input.js -c fixture/config.json'], function (err, data) { t.error(err); if (process.env.UPDATE) { @@ -80,19 +80,32 @@ test('accepts config file', function (t) { }, options); test('--shallow option', function (t) { - documentation(['--shallow fixture/internal.input.js'], function (err, data) { + documentation(['build --shallow fixture/internal.input.js'], function (err, data) { t.error(err); t.equal(data.length, 0, 'should not check dependencies'); t.end(); }); }, options); -test('bad -f option', function (t) { - documentation(['-f DOES-NOT-EXIST fixture/internal.input.js'], function (err) { - t.ok(err, 'returns error'); - t.end(); - }); -}, options); +test('invalid arguments', function (group) { + group.test('bad -f option', function (t) { + documentation(['build -f DOES-NOT-EXIST fixture/internal.input.js'], function (err) { + t.ok(err, 'returns error'); + t.end(); + }); + }, options); + + group.test('html with no destination', function (t) { + documentation(['build -f html fixture/internal.input.js'], function (err) { + t.ok(err.toString() + .match(/The HTML output mode requires a destination directory set with -o/), + 'needs dest for html'); + t.end(); + }); + }, options); + + group.end(); +}); test('--version', function (t) { documentation(['--version'], {}, function (err, output) { @@ -101,38 +114,41 @@ test('--version', function (t) { }, false); }, options); -test('html with no destination', function (t) { - documentation(['-f html fixture/internal.input.js'], function (err) { - t.ok(err.toString() - .match(/The HTML output mode requires a destination directory set with -o/), - 'needs dest for html'); - t.end(); - }); -}, options); +test('lint command', function (group) { -test('--lint option', function (t) { - documentation(['--lint fixture/lint/lint.input.js'], function (err, data) { - var output = path.join(__dirname, 'fixture/lint/lint.output.js'); - data = data.toString().split('\n').slice(2).join('\n'); - if (process.env.UPDATE) { - fs.writeFileSync(output, data); - } - t.equal(err.code, 1); - t.equal(data, fs.readFileSync(output, 'utf8'), 'outputs lint'); - t.end(); - }); -}, options); + group.test('generates lint output', function (t) { + documentation(['lint fixture/lint/lint.input.js'], function (err, data) { + var output = path.join(__dirname, 'fixture/lint/lint.output.js'); + data = data.toString().split('\n').slice(2).join('\n'); + if (process.env.UPDATE) { + fs.writeFileSync(output, data); + } + t.equal(err.code, 1); + t.equal(data, fs.readFileSync(output, 'utf8'), 'outputs lint'); + t.end(); + }); + }, options); -test('--lint option on good file', function (t) { - documentation(['--lint fixture/simple.input.js'], {}, function (err, data) { - t.equal(err, null); - t.equal(data, '', 'no output'); - t.end(); - }, false); -}, options); + group.test('generates no output on a good file', function (t) { + documentation(['lint fixture/simple.input.js'], {}, function (err, data) { + t.equal(err, null); + t.equal(data, '', 'no output'); + t.end(); + }, false); + }, options); + + group.test('exposes syntax error on a bad file', function (t) { + documentation(['lint fixture/bad/syntax.input.js'], {}, function (err, data) { + t.ok(err.code > 0, 'exits with a > 0 exit code'); + t.end(); + }, false); + }, options); + + group.end(); +}); test('given no files', function (t) { - documentation([''], function (err) { + documentation(['build'], function (err) { t.ok(err.toString() .match(/documentation was given no files and was not run in a module directory/), 'no files given'); @@ -140,11 +156,18 @@ test('given no files', function (t) { }); }, options); +test('with an invalid command', function (t) { + documentation(['invalid'], function (err) { + t.ok(err, 'returns error'); + t.end(); + }); +}, options); + test('write to file', function (t) { var dst = path.join(os.tmpdir(), (Date.now() + Math.random()).toString()); - documentation(['--shallow fixture/internal.input.js -o ' + dst], {}, function (err, data) { + documentation(['build --shallow fixture/internal.input.js -o ' + dst], {}, function (err, data) { t.error(err); t.equal(data, ''); t.ok(fs.existsSync(dst), 'created file'); @@ -157,7 +180,7 @@ test('write to html', function (t) { var dstDir = path.join(os.tmpdir(), (Date.now() + Math.random()).toString()); fs.mkdirSync(dstDir); - documentation(['--shallow fixture/internal.input.js -f html -o ' + dstDir], {}, + documentation(['build --shallow fixture/internal.input.js -f html -o ' + dstDir], {}, function (err, data) { t.error(err); t.equal(data, ''); @@ -168,7 +191,7 @@ test('write to html', function (t) { test('fatal error', function (t) { - documentation(['--shallow fixture/bad/syntax.input.js'], {}, + documentation(['build --shallow fixture/bad/syntax.input.js'], {}, function (err) { t.ok(err.toString().match(/Unexpected token/), 'reports syntax error'); t.end(); diff --git a/test/fixture/_multi-file-input.json b/test/fixture/_multi-file-input.json index 2fbcb8890..0cdfd8a73 100644 --- a/test/fixture/_multi-file-input.json +++ b/test/fixture/_multi-file-input.json @@ -50,12 +50,7 @@ }, "code": "/**\n * This function returns the number plus two.\n *\n * @param {Number} a the number\n * @returns {Number} numbertwo\n * @example\n * var result = returnTwo(4);\n * // result is 6\n */\nfunction returnTwo(a) {\n // this returns a + 2\n return a + 2;\n}\n" }, - "errors": [ - { - "message": "type Number found, number is standard", - "commentLineNumber": 3 - } - ], + "errors": [], "params": [ { "title": "param", diff --git a/test/fixture/es6-import.output.custom.md b/test/fixture/es6-import.output.custom.md index f0c828649..983c493c9 100644 --- a/test/fixture/es6-import.output.custom.md +++ b/test/fixture/es6-import.output.custom.md @@ -17,6 +17,12 @@ Is it empty This method says hello +# es6.input + +This function returns the number one. + +Returns **Number** numberone + # foo This is an async method diff --git a/test/fixture/es6-import.output.json b/test/fixture/es6-import.output.json index 84ca5cde2..aba0c2aba 100644 --- a/test/fixture/es6-import.output.json +++ b/test/fixture/es6-import.output.json @@ -23,7 +23,7 @@ "column": 1 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "Sink", @@ -75,7 +75,7 @@ "column": 3 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "params": [ @@ -137,7 +137,7 @@ "column": 3 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "empty", @@ -179,7 +179,7 @@ "column": 3 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "hello", @@ -201,6 +201,64 @@ "Sink" ] }, + { + "description": "This function returns the number one.", + "tags": [ + { + "title": "returns", + "description": "numberone", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "Number" + } + } + ], + "loc": { + "start": { + "line": 59, + "column": 0 + }, + "end": { + "line": 62, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 63, + "column": 0 + }, + "end": { + "line": 63, + "column": 38 + } + }, + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" + }, + "errors": [], + "returns": [ + { + "title": "returns", + "description": "numberone", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "Number" + } + } + ], + "name": "es6.input", + "kind": "function", + "members": { + "instance": [], + "static": [] + }, + "path": [ + "es6.input" + ] + }, { "description": "This is an async method", "tags": [], @@ -225,7 +283,7 @@ "column": 24 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "foo", @@ -262,7 +320,7 @@ "column": 1 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "functionWithRest", @@ -308,7 +366,7 @@ "column": 1 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "functionWithRestAndType", @@ -368,7 +426,7 @@ "column": 31 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "returns": [ @@ -493,7 +551,7 @@ "column": 18 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "staticProp", diff --git a/test/fixture/es6-import.output.md b/test/fixture/es6-import.output.md index f0c828649..983c493c9 100644 --- a/test/fixture/es6-import.output.md +++ b/test/fixture/es6-import.output.md @@ -17,6 +17,12 @@ Is it empty This method says hello +# es6.input + +This function returns the number one. + +Returns **Number** numberone + # foo This is an async method diff --git a/test/fixture/es6-import.output.md.json b/test/fixture/es6-import.output.md.json index 35ad9125e..38f14171a 100644 --- a/test/fixture/es6-import.output.md.json +++ b/test/fixture/es6-import.output.md.json @@ -273,6 +273,100 @@ "indent": [] } }, + { + "depth": 1, + "type": "heading", + "children": [ + { + "type": "text", + "value": "es6.input" + } + ] + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "This function returns the number one.", + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 38 + }, + "indent": [] + } + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Returns " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "Number" + } + ] + }, + { + "type": "text", + "value": " " + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "numberone", + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 10 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 10 + }, + "indent": [] + } + } + ] + }, { "depth": 1, "type": "heading", diff --git a/test/fixture/es6.input.js b/test/fixture/es6.input.js index b3013a86c..bef93423d 100644 --- a/test/fixture/es6.input.js +++ b/test/fixture/es6.input.js @@ -55,3 +55,9 @@ function functionWithRestAndType(...someParams: number) { async function foo() { } export default multiply; + +/** + * This function returns the number one. + * @returns {Number} numberone + */ +module.exports = () => (

hello

); diff --git a/test/fixture/es6.output.custom.md b/test/fixture/es6.output.custom.md index 7a1550d98..2596ed6cf 100644 --- a/test/fixture/es6.output.custom.md +++ b/test/fixture/es6.output.custom.md @@ -17,6 +17,12 @@ Is it empty This method says hello +# es6.input + +This function returns the number one. + +Returns **Number** numberone + # foo This is an async method diff --git a/test/fixture/es6.output.json b/test/fixture/es6.output.json index b94a8eaca..5a1d10444 100644 --- a/test/fixture/es6.output.json +++ b/test/fixture/es6.output.json @@ -23,7 +23,7 @@ "column": 1 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "Sink", @@ -75,7 +75,7 @@ "column": 3 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "params": [ @@ -137,7 +137,7 @@ "column": 3 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "empty", @@ -179,7 +179,7 @@ "column": 3 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "hello", @@ -201,6 +201,64 @@ "Sink" ] }, + { + "description": "This function returns the number one.", + "tags": [ + { + "title": "returns", + "description": "numberone", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "Number" + } + } + ], + "loc": { + "start": { + "line": 59, + "column": 0 + }, + "end": { + "line": 62, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 63, + "column": 0 + }, + "end": { + "line": 63, + "column": 38 + } + }, + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" + }, + "errors": [], + "returns": [ + { + "title": "returns", + "description": "numberone", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "Number" + } + } + ], + "name": "es6.input", + "kind": "function", + "members": { + "instance": [], + "static": [] + }, + "path": [ + "es6.input" + ] + }, { "description": "This is an async method", "tags": [], @@ -225,7 +283,7 @@ "column": 24 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "foo", @@ -262,7 +320,7 @@ "column": 1 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "functionWithRest", @@ -308,7 +366,7 @@ "column": 1 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "functionWithRestAndType", @@ -368,7 +426,7 @@ "column": 31 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "returns": [ @@ -428,7 +486,7 @@ "column": 18 } }, - "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n" + "code": "/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nvar multiply = (a, b) => a * b;\n\n/**\n * This is a sink\n */\nclass Sink {\n /**\n * This is a property of the sink.\n */\n staticProp = 42;\n\n /**\n * Is it empty\n */\n empty() {\n return 1;\n }\n\n /**\n * This method says hello\n */\n static hello() {\n return 'hello';\n }\n\n /**\n * @param {number} height the height of the thing\n * @param {number} width the width of the thing\n */\n constructor(height, width) {\n this.height = height;\n this.width = width;\n }\n}\n\n/**\n * This function takes rest params\n */\nfunction functionWithRest(...someParams) {\n}\n\n/**\n * So does this one, with types\n */\nfunction functionWithRestAndType(...someParams: number) {\n}\n\n/**\n * This is an async method\n */\nasync function foo() { }\n\nexport default multiply;\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = () => (

hello

);\n" }, "errors": [], "name": "staticProp", diff --git a/test/fixture/es6.output.md b/test/fixture/es6.output.md index 7a1550d98..2596ed6cf 100644 --- a/test/fixture/es6.output.md +++ b/test/fixture/es6.output.md @@ -17,6 +17,12 @@ Is it empty This method says hello +# es6.input + +This function returns the number one. + +Returns **Number** numberone + # foo This is an async method diff --git a/test/fixture/es6.output.md.json b/test/fixture/es6.output.md.json index 9170f4e6b..116d4448c 100644 --- a/test/fixture/es6.output.md.json +++ b/test/fixture/es6.output.md.json @@ -273,6 +273,100 @@ "indent": [] } }, + { + "depth": 1, + "type": "heading", + "children": [ + { + "type": "text", + "value": "es6.input" + } + ] + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "This function returns the number one.", + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 38 + }, + "indent": [] + } + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Returns " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "Number" + } + ] + }, + { + "type": "text", + "value": " " + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "numberone", + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 10 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 10 + }, + "indent": [] + } + } + ] + }, { "depth": 1, "type": "heading", diff --git a/test/fixture/flow-default.input.js b/test/fixture/flow-default.input.js deleted file mode 100644 index 11ef49b86..000000000 --- a/test/fixture/flow-default.input.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Very Important Transform - */ -function veryImportantTransform( - input: Array, - options: Object = {} -): string { - return "42"; -} diff --git a/test/fixture/flow-default.output.custom.md b/test/fixture/flow-default.output.custom.md deleted file mode 100644 index a2ce4f83b..000000000 --- a/test/fixture/flow-default.output.custom.md +++ /dev/null @@ -1,10 +0,0 @@ -# veryImportantTransform - -Very Important Transform - -**Parameters** - -- `input` **Array<string>** -- `options` **[Object]** (optional, default `{}`) - -Returns **string** diff --git a/test/fixture/flow-default.output.json b/test/fixture/flow-default.output.json deleted file mode 100644 index c8cb8c044..000000000 --- a/test/fixture/flow-default.output.json +++ /dev/null @@ -1,79 +0,0 @@ -[ - { - "description": "Very Important Transform", - "tags": [], - "loc": { - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 3, - "column": 3 - } - }, - "context": { - "loc": { - "start": { - "line": 4, - "column": 0 - }, - "end": { - "line": 9, - "column": 1 - } - }, - "code": "/**\n * Very Important Transform\n */\nfunction veryImportantTransform(\n input: Array,\n options: Object = {}\n): string {\n return \"42\";\n}\n" - }, - "errors": [], - "name": "veryImportantTransform", - "kind": "function", - "params": [ - { - "title": "param", - "name": "input", - "lineNumber": 5, - "type": { - "type": "TypeApplication", - "expression": { - "type": "NameExpression", - "name": "Array" - }, - "applications": [ - { - "type": "NameExpression", - "name": "string" - } - ] - } - }, - { - "title": "param", - "name": "options", - "default": "{}", - "type": { - "type": "OptionalType", - "expression": { - "type": "NameExpression", - "name": "Object" - } - } - } - ], - "returns": [ - { - "type": { - "type": "NameExpression", - "name": "string" - } - } - ], - "members": { - "instance": [], - "static": [] - }, - "path": [ - "veryImportantTransform" - ] - } -] \ No newline at end of file diff --git a/test/fixture/flow-default.output.md b/test/fixture/flow-default.output.md deleted file mode 100644 index a2ce4f83b..000000000 --- a/test/fixture/flow-default.output.md +++ /dev/null @@ -1,10 +0,0 @@ -# veryImportantTransform - -Very Important Transform - -**Parameters** - -- `input` **Array<string>** -- `options` **[Object]** (optional, default `{}`) - -Returns **string** diff --git a/test/fixture/flow-default.output.md.json b/test/fixture/flow-default.output.md.json deleted file mode 100644 index 8e49af1a9..000000000 --- a/test/fixture/flow-default.output.md.json +++ /dev/null @@ -1,162 +0,0 @@ -{ - "type": "root", - "children": [ - { - "depth": 1, - "type": "heading", - "children": [ - { - "type": "text", - "value": "veryImportantTransform" - } - ] - }, - { - "type": "paragraph", - "children": [ - { - "type": "text", - "value": "Very Important Transform", - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 25 - }, - "indent": [] - } - } - ], - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 25 - }, - "indent": [] - } - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "Parameters" - } - ] - }, - { - "ordered": false, - "type": "list", - "children": [ - { - "type": "listItem", - "children": [ - { - "type": "paragraph", - "children": [ - { - "type": "inlineCode", - "value": "input" - }, - { - "type": "text", - "value": " " - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "Array<string>" - } - ] - }, - { - "type": "text", - "value": " " - } - ] - } - ] - }, - { - "type": "listItem", - "children": [ - { - "type": "paragraph", - "children": [ - { - "type": "inlineCode", - "value": "options" - }, - { - "type": "text", - "value": " " - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "[Object]" - } - ] - }, - { - "type": "text", - "value": " " - }, - { - "type": "paragraph", - "children": [ - { - "type": "text", - "value": " (optional, default " - }, - { - "type": "inlineCode", - "value": "{}" - }, - { - "type": "text", - "value": ")" - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "paragraph", - "children": [ - { - "type": "text", - "value": "Returns " - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "string" - } - ] - }, - { - "type": "text", - "value": " " - } - ] - } - ] -} \ No newline at end of file diff --git a/test/fixture/flow-types.input.js b/test/fixture/flow-types.input.js index e36d6273a..f67adb036 100644 --- a/test/fixture/flow-types.input.js +++ b/test/fixture/flow-types.input.js @@ -35,3 +35,13 @@ type Two = { * Just an alias for an array of strings */ type T = Array; + +/** + * Very Important Transform + */ +function veryImportantTransform( + input: Array, + options: Object = {} +): string { + return "42"; +} diff --git a/test/fixture/flow-types.output.custom.md b/test/fixture/flow-types.output.custom.md index 5eff0597c..8176b5407 100644 --- a/test/fixture/flow-types.output.custom.md +++ b/test/fixture/flow-types.output.custom.md @@ -39,3 +39,14 @@ This function returns the number one. - `f` **Named** Returns **number** + +# veryImportantTransform + +Very Important Transform + +**Parameters** + +- `input` **Array<string>** +- `options` **[Object]** (optional, default `{}`) + +Returns **string** diff --git a/test/fixture/flow-types.output.json b/test/fixture/flow-types.output.json index 38ab5892d..670504a38 100644 --- a/test/fixture/flow-types.output.json +++ b/test/fixture/flow-types.output.json @@ -34,7 +34,7 @@ "column": 2 } }, - "code": "/**\n * This function returns the number one.\n */\nfunction addThem(a: Point, b: string, c: ?boolean, d: Array, e: Object, f: Named): number {\n return a + b + c + d + e;\n}\n\n/**\n * A 2D point.\n *\n * @property {number} x this is a prop\n */\ntype Point = {\n x: number,\n y: number,\n rgb: {\n hex: string\n },\n props: {\n radius: {\n x: number\n }\n }\n};\n\n/**\n * A type with entirely derived properties\n */\ntype Two = {\n x: number,\n y: number\n};\n\n/**\n * Just an alias for an array of strings\n */\ntype T = Array;\n" + "code": "/**\n * This function returns the number one.\n */\nfunction addThem(a: Point, b: string, c: ?boolean, d: Array, e: Object, f: Named): number {\n return a + b + c + d + e;\n}\n\n/**\n * A 2D point.\n *\n * @property {number} x this is a prop\n */\ntype Point = {\n x: number,\n y: number,\n rgb: {\n hex: string\n },\n props: {\n radius: {\n x: number\n }\n }\n};\n\n/**\n * A type with entirely derived properties\n */\ntype Two = {\n x: number,\n y: number\n};\n\n/**\n * Just an alias for an array of strings\n */\ntype T = Array;\n\n/**\n * Very Important Transform\n */\nfunction veryImportantTransform(\n input: Array,\n options: Object = {}\n): string {\n return \"42\";\n}\n" }, "errors": [], "properties": [ @@ -143,7 +143,7 @@ "column": 23 } }, - "code": "/**\n * This function returns the number one.\n */\nfunction addThem(a: Point, b: string, c: ?boolean, d: Array, e: Object, f: Named): number {\n return a + b + c + d + e;\n}\n\n/**\n * A 2D point.\n *\n * @property {number} x this is a prop\n */\ntype Point = {\n x: number,\n y: number,\n rgb: {\n hex: string\n },\n props: {\n radius: {\n x: number\n }\n }\n};\n\n/**\n * A type with entirely derived properties\n */\ntype Two = {\n x: number,\n y: number\n};\n\n/**\n * Just an alias for an array of strings\n */\ntype T = Array;\n" + "code": "/**\n * This function returns the number one.\n */\nfunction addThem(a: Point, b: string, c: ?boolean, d: Array, e: Object, f: Named): number {\n return a + b + c + d + e;\n}\n\n/**\n * A 2D point.\n *\n * @property {number} x this is a prop\n */\ntype Point = {\n x: number,\n y: number,\n rgb: {\n hex: string\n },\n props: {\n radius: {\n x: number\n }\n }\n};\n\n/**\n * A type with entirely derived properties\n */\ntype Two = {\n x: number,\n y: number\n};\n\n/**\n * Just an alias for an array of strings\n */\ntype T = Array;\n\n/**\n * Very Important Transform\n */\nfunction veryImportantTransform(\n input: Array,\n options: Object = {}\n): string {\n return \"42\";\n}\n" }, "errors": [], "name": "T", @@ -180,7 +180,7 @@ "column": 2 } }, - "code": "/**\n * This function returns the number one.\n */\nfunction addThem(a: Point, b: string, c: ?boolean, d: Array, e: Object, f: Named): number {\n return a + b + c + d + e;\n}\n\n/**\n * A 2D point.\n *\n * @property {number} x this is a prop\n */\ntype Point = {\n x: number,\n y: number,\n rgb: {\n hex: string\n },\n props: {\n radius: {\n x: number\n }\n }\n};\n\n/**\n * A type with entirely derived properties\n */\ntype Two = {\n x: number,\n y: number\n};\n\n/**\n * Just an alias for an array of strings\n */\ntype T = Array;\n" + "code": "/**\n * This function returns the number one.\n */\nfunction addThem(a: Point, b: string, c: ?boolean, d: Array, e: Object, f: Named): number {\n return a + b + c + d + e;\n}\n\n/**\n * A 2D point.\n *\n * @property {number} x this is a prop\n */\ntype Point = {\n x: number,\n y: number,\n rgb: {\n hex: string\n },\n props: {\n radius: {\n x: number\n }\n }\n};\n\n/**\n * A type with entirely derived properties\n */\ntype Two = {\n x: number,\n y: number\n};\n\n/**\n * Just an alias for an array of strings\n */\ntype T = Array;\n\n/**\n * Very Important Transform\n */\nfunction veryImportantTransform(\n input: Array,\n options: Object = {}\n): string {\n return \"42\";\n}\n" }, "errors": [], "name": "Two", @@ -237,7 +237,7 @@ "column": 1 } }, - "code": "/**\n * This function returns the number one.\n */\nfunction addThem(a: Point, b: string, c: ?boolean, d: Array, e: Object, f: Named): number {\n return a + b + c + d + e;\n}\n\n/**\n * A 2D point.\n *\n * @property {number} x this is a prop\n */\ntype Point = {\n x: number,\n y: number,\n rgb: {\n hex: string\n },\n props: {\n radius: {\n x: number\n }\n }\n};\n\n/**\n * A type with entirely derived properties\n */\ntype Two = {\n x: number,\n y: number\n};\n\n/**\n * Just an alias for an array of strings\n */\ntype T = Array;\n" + "code": "/**\n * This function returns the number one.\n */\nfunction addThem(a: Point, b: string, c: ?boolean, d: Array, e: Object, f: Named): number {\n return a + b + c + d + e;\n}\n\n/**\n * A 2D point.\n *\n * @property {number} x this is a prop\n */\ntype Point = {\n x: number,\n y: number,\n rgb: {\n hex: string\n },\n props: {\n radius: {\n x: number\n }\n }\n};\n\n/**\n * A type with entirely derived properties\n */\ntype Two = {\n x: number,\n y: number\n};\n\n/**\n * Just an alias for an array of strings\n */\ntype T = Array;\n\n/**\n * Very Important Transform\n */\nfunction veryImportantTransform(\n input: Array,\n options: Object = {}\n): string {\n return \"42\";\n}\n" }, "errors": [], "name": "addThem", @@ -325,5 +325,82 @@ "path": [ "addThem" ] + }, + { + "description": "Very Important Transform", + "tags": [], + "loc": { + "start": { + "line": 39, + "column": 0 + }, + "end": { + "line": 41, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 42, + "column": 0 + }, + "end": { + "line": 47, + "column": 1 + } + }, + "code": "/**\n * This function returns the number one.\n */\nfunction addThem(a: Point, b: string, c: ?boolean, d: Array, e: Object, f: Named): number {\n return a + b + c + d + e;\n}\n\n/**\n * A 2D point.\n *\n * @property {number} x this is a prop\n */\ntype Point = {\n x: number,\n y: number,\n rgb: {\n hex: string\n },\n props: {\n radius: {\n x: number\n }\n }\n};\n\n/**\n * A type with entirely derived properties\n */\ntype Two = {\n x: number,\n y: number\n};\n\n/**\n * Just an alias for an array of strings\n */\ntype T = Array;\n\n/**\n * Very Important Transform\n */\nfunction veryImportantTransform(\n input: Array,\n options: Object = {}\n): string {\n return \"42\";\n}\n" + }, + "errors": [], + "name": "veryImportantTransform", + "kind": "function", + "params": [ + { + "title": "param", + "name": "input", + "lineNumber": 43, + "type": { + "type": "TypeApplication", + "expression": { + "type": "NameExpression", + "name": "Array" + }, + "applications": [ + { + "type": "NameExpression", + "name": "string" + } + ] + } + }, + { + "title": "param", + "name": "options", + "default": "{}", + "type": { + "type": "OptionalType", + "expression": { + "type": "NameExpression", + "name": "Object" + } + } + } + ], + "returns": [ + { + "type": { + "type": "NameExpression", + "name": "string" + } + } + ], + "members": { + "instance": [], + "static": [] + }, + "path": [ + "veryImportantTransform" + ] } ] \ No newline at end of file diff --git a/test/fixture/flow-types.output.md b/test/fixture/flow-types.output.md index 5eff0597c..8176b5407 100644 --- a/test/fixture/flow-types.output.md +++ b/test/fixture/flow-types.output.md @@ -39,3 +39,14 @@ This function returns the number one. - `f` **Named** Returns **number** + +# veryImportantTransform + +Very Important Transform + +**Parameters** + +- `input` **Array<string>** +- `options` **[Object]** (optional, default `{}`) + +Returns **string** diff --git a/test/fixture/flow-types.output.md.json b/test/fixture/flow-types.output.md.json index 0deeebd45..7a197eb2e 100644 --- a/test/fixture/flow-types.output.md.json +++ b/test/fixture/flow-types.output.md.json @@ -745,6 +745,163 @@ "value": " " } ] + }, + { + "depth": 1, + "type": "heading", + "children": [ + { + "type": "text", + "value": "veryImportantTransform" + } + ] + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Very Important Transform", + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 25 + }, + "indent": [] + } + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "Parameters" + } + ] + }, + { + "ordered": false, + "type": "list", + "children": [ + { + "type": "listItem", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "inlineCode", + "value": "input" + }, + { + "type": "text", + "value": " " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "Array<string>" + } + ] + }, + { + "type": "text", + "value": " " + } + ] + } + ] + }, + { + "type": "listItem", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "inlineCode", + "value": "options" + }, + { + "type": "text", + "value": " " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "[Object]" + } + ] + }, + { + "type": "text", + "value": " " + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": " (optional, default " + }, + { + "type": "inlineCode", + "value": "{}" + }, + { + "type": "text", + "value": ")" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Returns " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "string" + } + ] + }, + { + "type": "text", + "value": " " + } + ] } ] } \ No newline at end of file diff --git a/test/fixture/jsx.input.js b/test/fixture/jsx.input.js deleted file mode 100644 index f8d352467..000000000 --- a/test/fixture/jsx.input.js +++ /dev/null @@ -1,7 +0,0 @@ -var util = require('util'); - -/** - * This function returns the number one. - * @returns {Number} numberone - */ -module.exports = (

hello

); diff --git a/test/fixture/jsx.output.custom.md b/test/fixture/jsx.output.custom.md deleted file mode 100644 index 655199fa7..000000000 --- a/test/fixture/jsx.output.custom.md +++ /dev/null @@ -1,5 +0,0 @@ -# jsx.input - -This function returns the number one. - -Returns **Number** numberone diff --git a/test/fixture/jsx.output.json b/test/fixture/jsx.output.json deleted file mode 100644 index d52a33202..000000000 --- a/test/fixture/jsx.output.json +++ /dev/null @@ -1,59 +0,0 @@ -[ - { - "description": "This function returns the number one.", - "tags": [ - { - "title": "returns", - "description": "numberone", - "lineNumber": 2, - "type": { - "type": "NameExpression", - "name": "Number" - } - } - ], - "loc": { - "start": { - "line": 3, - "column": 0 - }, - "end": { - "line": 6, - "column": 3 - } - }, - "context": { - "loc": { - "start": { - "line": 7, - "column": 0 - }, - "end": { - "line": 7, - "column": 32 - } - }, - "code": "var util = require('util');\n\n/**\n * This function returns the number one.\n * @returns {Number} numberone\n */\nmodule.exports = (

hello

);\n" - }, - "errors": [], - "returns": [ - { - "title": "returns", - "description": "numberone", - "lineNumber": 2, - "type": { - "type": "NameExpression", - "name": "Number" - } - } - ], - "name": "jsx.input", - "members": { - "instance": [], - "static": [] - }, - "path": [ - "jsx.input" - ] - } -] \ No newline at end of file diff --git a/test/fixture/jsx.output.md b/test/fixture/jsx.output.md deleted file mode 100644 index 655199fa7..000000000 --- a/test/fixture/jsx.output.md +++ /dev/null @@ -1,5 +0,0 @@ -# jsx.input - -This function returns the number one. - -Returns **Number** numberone diff --git a/test/fixture/jsx.output.md.json b/test/fixture/jsx.output.md.json deleted file mode 100644 index bb594e312..000000000 --- a/test/fixture/jsx.output.md.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "type": "root", - "children": [ - { - "depth": 1, - "type": "heading", - "children": [ - { - "type": "text", - "value": "jsx.input" - } - ] - }, - { - "type": "paragraph", - "children": [ - { - "type": "text", - "value": "This function returns the number one.", - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 38 - }, - "indent": [] - } - } - ], - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 38 - }, - "indent": [] - } - }, - { - "type": "paragraph", - "children": [ - { - "type": "text", - "value": "Returns " - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "Number" - } - ] - }, - { - "type": "text", - "value": " " - }, - { - "type": "paragraph", - "children": [ - { - "type": "text", - "value": "numberone", - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 10 - }, - "indent": [] - } - } - ], - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 10 - }, - "indent": [] - } - } - ] - } - ] -} \ No newline at end of file diff --git a/test/fixture/lint/lint.input.js b/test/fixture/lint/lint.input.js index a8b8c6970..dd4d8a3ed 100644 --- a/test/fixture/lint/lint.input.js +++ b/test/fixture/lint/lint.input.js @@ -1,5 +1,8 @@ /** * @param {String} foo bar + * @param {Array} foo bar + * @param {Array} foo bar + * @param {Array|Number} foo bar * @memberof notfound */ diff --git a/test/fixture/lint/lint.output.js b/test/fixture/lint/lint.output.js index 4480c6609..6e21bed22 100644 --- a/test/fixture/lint/lint.output.js +++ b/test/fixture/lint/lint.output.js @@ -1,6 +1,10 @@ 1:1 warning could not determine @name for hierarchy + 1:1 warning could not determine @name for hierarchy 2:1 warning type String found, string is standard - 3:1 warning @memberof reference to notfound not found - 7:1 warning type String found, string is standard + 3:1 warning type Number found, number is standard + 4:1 warning type Number found, number is standard + 5:1 warning type Number found, number is standard + 6:1 warning @memberof reference to notfound not found + 10:1 warning type String found, string is standard -⚠ 5 warnings +⚠ 8 warnings diff --git a/test/fixture/nearby_params.output.json b/test/fixture/nearby_params.output.json index aea2d0d7b..d23bce7ec 100644 --- a/test/fixture/nearby_params.output.json +++ b/test/fixture/nearby_params.output.json @@ -112,12 +112,7 @@ }, "code": "/** Attempt to establish a cookie-based session in exchange for credentials.\n * @function\n * @name sessions.create\n * @param {object} credentials\n * @param {string} credentials.name Login username. Also accepted as `username` or `email`.\n * @param {string} credentials.password Login password\n * @param {function} [callback] Gets passed `(err, { success:Boolean })`.\n * @returns {Promise} promise, to be resolved on success or rejected on failure\n */\nsessions.addMethod('create', 'POST / form', {\n // normalize request body params\n before({ body }) {\n }\n});\n" }, - "errors": [ - { - "message": "type object found, Object is standard", - "commentLineNumber": 4 - } - ], + "errors": [], "function": null, "name": "sessions.create", "params": [ diff --git a/test/fixture/nest_params.input.js b/test/fixture/nest_params.input.js index 5ce5d9dc6..9e31827e4 100644 --- a/test/fixture/nest_params.input.js +++ b/test/fixture/nest_params.input.js @@ -5,3 +5,15 @@ */ function foo(employee) { } + +/** + * @name foo + * @param {Object} options some options + * @param {number} options.much how much + * @param {number} bar something else + * @property {Object} theTime the current time + * @property {number} theTime.hours + * @property {number} theTime.minutes + * @property {number} theTime.seconds + * @returns {Object} foo something else + */ diff --git a/test/fixture/nest_params.output.custom.md b/test/fixture/nest_params.output.custom.md index bbe424e62..61a9e0998 100644 --- a/test/fixture/nest_params.output.custom.md +++ b/test/fixture/nest_params.output.custom.md @@ -6,3 +6,20 @@ - `employees[].name` **string** The name of an employee. - `employees[].department` **string** The employee's department. - `employee` + +# foo + +**Parameters** + +- `options` **Object** some options + - `options.much` **number** how much +- `bar` **number** something else + +**Properties** + +- `theTime` **Object** the current time + - `theTime.hours` **number** + - `theTime.minutes` **number** + - `theTime.seconds` **number** + +Returns **Object** foo something else diff --git a/test/fixture/nest_params.output.json b/test/fixture/nest_params.output.json index fe3278520..dac14c74a 100644 --- a/test/fixture/nest_params.output.json +++ b/test/fixture/nest_params.output.json @@ -85,7 +85,7 @@ "column": 1 } }, - "code": "/**\n * @param {Object[]} employees - The employees who are responsible for the project.\n * @param {string} employees[].name - The name of an employee.\n * @param {string} employees[].department - The employee's department.\n */\nfunction foo(employee) {\n}\n" + "code": "/**\n * @param {Object[]} employees - The employees who are responsible for the project.\n * @param {string} employees[].name - The name of an employee.\n * @param {string} employees[].department - The employee's department.\n */\nfunction foo(employee) {\n}\n\n/**\n * @name foo\n * @param {Object} options some options\n * @param {number} options.much how much\n * @param {number} bar something else\n * @property {Object} theTime the current time\n * @property {number} theTime.hours\n * @property {number} theTime.minutes\n * @property {number} theTime.seconds\n * @returns {Object} foo something else\n */\n" }, "errors": [], "params": [ @@ -145,5 +145,259 @@ "path": [ "foo" ] + }, + { + "description": "", + "tags": [ + { + "title": "name", + "description": null, + "lineNumber": 1, + "name": "foo" + }, + { + "title": "param", + "description": "some options", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "Object" + }, + "name": "options", + "properties": [ + { + "title": "param", + "description": "how much", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "options.much" + } + ] + }, + { + "title": "param", + "description": "how much", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "options.much" + }, + { + "title": "param", + "description": "something else", + "lineNumber": 4, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "bar" + }, + { + "title": "property", + "description": "the current time", + "lineNumber": 5, + "type": { + "type": "NameExpression", + "name": "Object" + }, + "name": "theTime", + "properties": [ + { + "title": "property", + "description": null, + "lineNumber": 6, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "theTime.hours" + }, + { + "title": "property", + "description": null, + "lineNumber": 7, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "theTime.minutes" + }, + { + "title": "property", + "description": null, + "lineNumber": 8, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "theTime.seconds" + } + ] + }, + { + "title": "property", + "description": null, + "lineNumber": 6, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "theTime.hours" + }, + { + "title": "property", + "description": null, + "lineNumber": 7, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "theTime.minutes" + }, + { + "title": "property", + "description": null, + "lineNumber": 8, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "theTime.seconds" + }, + { + "title": "returns", + "description": "foo something else", + "lineNumber": 9, + "type": { + "type": "NameExpression", + "name": "Object" + } + } + ], + "loc": { + "start": { + "line": 9, + "column": 0 + }, + "end": { + "line": 19, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 6, + "column": 0 + }, + "end": { + "line": 7, + "column": 1 + } + } + }, + "errors": [], + "name": "foo", + "params": [ + { + "title": "param", + "description": "some options", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "Object" + }, + "name": "options", + "properties": [ + { + "title": "param", + "description": "how much", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "options.much" + } + ] + }, + { + "title": "param", + "description": "something else", + "lineNumber": 4, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "bar" + } + ], + "properties": [ + { + "title": "property", + "description": "the current time", + "lineNumber": 5, + "type": { + "type": "NameExpression", + "name": "Object" + }, + "name": "theTime", + "properties": [ + { + "title": "property", + "description": null, + "lineNumber": 6, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "theTime.hours" + }, + { + "title": "property", + "description": null, + "lineNumber": 7, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "theTime.minutes" + }, + { + "title": "property", + "description": null, + "lineNumber": 8, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "theTime.seconds" + } + ] + } + ], + "returns": [ + { + "title": "returns", + "description": "foo something else", + "lineNumber": 9, + "type": { + "type": "NameExpression", + "name": "Object" + } + } + ], + "members": { + "instance": [], + "static": [] + }, + "path": [ + "foo" + ] } ] \ No newline at end of file diff --git a/test/fixture/nest_params.output.md b/test/fixture/nest_params.output.md index bbe424e62..61a9e0998 100644 --- a/test/fixture/nest_params.output.md +++ b/test/fixture/nest_params.output.md @@ -6,3 +6,20 @@ - `employees[].name` **string** The name of an employee. - `employees[].department` **string** The employee's department. - `employee` + +# foo + +**Parameters** + +- `options` **Object** some options + - `options.much` **number** how much +- `bar` **number** something else + +**Properties** + +- `theTime` **Object** the current time + - `theTime.hours` **number** + - `theTime.minutes` **number** + - `theTime.seconds` **number** + +Returns **Object** foo something else diff --git a/test/fixture/nest_params.output.md.json b/test/fixture/nest_params.output.md.json index c9746f18a..7282f0130 100644 --- a/test/fixture/nest_params.output.md.json +++ b/test/fixture/nest_params.output.md.json @@ -239,6 +239,452 @@ ] } ] + }, + { + "depth": 1, + "type": "heading", + "children": [ + { + "type": "text", + "value": "foo" + } + ] + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "Parameters" + } + ] + }, + { + "ordered": false, + "type": "list", + "children": [ + { + "type": "listItem", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "inlineCode", + "value": "options" + }, + { + "type": "text", + "value": " " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "Object" + } + ] + }, + { + "type": "text", + "value": " " + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "some options", + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 13 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 13 + }, + "indent": [] + } + } + ] + }, + { + "ordered": false, + "type": "list", + "children": [ + { + "type": "listItem", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "inlineCode", + "value": "options.much" + }, + { + "type": "text", + "value": " " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "number" + } + ] + }, + { + "type": "text", + "value": " " + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "how much", + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 9 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 9 + }, + "indent": [] + } + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "listItem", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "inlineCode", + "value": "bar" + }, + { + "type": "text", + "value": " " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "number" + } + ] + }, + { + "type": "text", + "value": " " + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "something else", + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 15 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 15 + }, + "indent": [] + } + } + ] + } + ] + } + ] + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "Properties" + } + ] + }, + { + "ordered": false, + "type": "list", + "children": [ + { + "type": "listItem", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "inlineCode", + "value": "theTime" + }, + { + "type": "text", + "value": " " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "Object" + } + ] + }, + { + "type": "text", + "value": " " + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "the current time", + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 17 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 17 + }, + "indent": [] + } + } + ] + }, + { + "ordered": false, + "type": "list", + "children": [ + { + "type": "listItem", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "inlineCode", + "value": "theTime.hours" + }, + { + "type": "text", + "value": " " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "number" + } + ] + }, + { + "type": "text", + "value": " " + } + ] + } + ] + }, + { + "type": "listItem", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "inlineCode", + "value": "theTime.minutes" + }, + { + "type": "text", + "value": " " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "number" + } + ] + }, + { + "type": "text", + "value": " " + } + ] + } + ] + }, + { + "type": "listItem", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "inlineCode", + "value": "theTime.seconds" + }, + { + "type": "text", + "value": " " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "number" + } + ] + }, + { + "type": "text", + "value": " " + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Returns " + }, + { + "type": "strong", + "children": [ + { + "type": "text", + "value": "Object" + } + ] + }, + { + "type": "text", + "value": " " + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "foo something else", + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 19 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 19 + }, + "indent": [] + } + } + ] } ] } \ No newline at end of file diff --git a/test/fixture/nested_properties.input.js b/test/fixture/nested_properties.input.js deleted file mode 100644 index 4fb8d5b50..000000000 --- a/test/fixture/nested_properties.input.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @name foo - * @param {Object} options some options - * @param {number} options.much how much - * @param {number} bar something else - * @property {Object} theTime the current time - * @property {number} theTime.hours - * @property {number} theTime.minutes - * @property {number} theTime.seconds - * @returns {Object} foo something else - */ diff --git a/test/fixture/nested_properties.output.custom.md b/test/fixture/nested_properties.output.custom.md deleted file mode 100644 index 1a3827c86..000000000 --- a/test/fixture/nested_properties.output.custom.md +++ /dev/null @@ -1,16 +0,0 @@ -# foo - -**Parameters** - -- `options` **Object** some options - - `options.much` **number** how much -- `bar` **number** something else - -**Properties** - -- `theTime` **Object** the current time - - `theTime.hours` **number** - - `theTime.minutes` **number** - - `theTime.seconds` **number** - -Returns **Object** foo something else diff --git a/test/fixture/nested_properties.output.json b/test/fixture/nested_properties.output.json deleted file mode 100644 index 4d0d7e03d..000000000 --- a/test/fixture/nested_properties.output.json +++ /dev/null @@ -1,256 +0,0 @@ -[ - { - "description": "", - "tags": [ - { - "title": "name", - "description": null, - "lineNumber": 1, - "name": "foo" - }, - { - "title": "param", - "description": "some options", - "lineNumber": 2, - "type": { - "type": "NameExpression", - "name": "Object" - }, - "name": "options", - "properties": [ - { - "title": "param", - "description": "how much", - "lineNumber": 3, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "options.much" - } - ] - }, - { - "title": "param", - "description": "how much", - "lineNumber": 3, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "options.much" - }, - { - "title": "param", - "description": "something else", - "lineNumber": 4, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "bar" - }, - { - "title": "property", - "description": "the current time", - "lineNumber": 5, - "type": { - "type": "NameExpression", - "name": "Object" - }, - "name": "theTime", - "properties": [ - { - "title": "property", - "description": null, - "lineNumber": 6, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "theTime.hours" - }, - { - "title": "property", - "description": null, - "lineNumber": 7, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "theTime.minutes" - }, - { - "title": "property", - "description": null, - "lineNumber": 8, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "theTime.seconds" - } - ] - }, - { - "title": "property", - "description": null, - "lineNumber": 6, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "theTime.hours" - }, - { - "title": "property", - "description": null, - "lineNumber": 7, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "theTime.minutes" - }, - { - "title": "property", - "description": null, - "lineNumber": 8, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "theTime.seconds" - }, - { - "title": "returns", - "description": "foo something else", - "lineNumber": 9, - "type": { - "type": "NameExpression", - "name": "Object" - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 11, - "column": 3 - } - }, - "context": { - "loc": { - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 12, - "column": 0 - } - } - }, - "errors": [], - "name": "foo", - "params": [ - { - "title": "param", - "description": "some options", - "lineNumber": 2, - "type": { - "type": "NameExpression", - "name": "Object" - }, - "name": "options", - "properties": [ - { - "title": "param", - "description": "how much", - "lineNumber": 3, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "options.much" - } - ] - }, - { - "title": "param", - "description": "something else", - "lineNumber": 4, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "bar" - } - ], - "properties": [ - { - "title": "property", - "description": "the current time", - "lineNumber": 5, - "type": { - "type": "NameExpression", - "name": "Object" - }, - "name": "theTime", - "properties": [ - { - "title": "property", - "description": null, - "lineNumber": 6, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "theTime.hours" - }, - { - "title": "property", - "description": null, - "lineNumber": 7, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "theTime.minutes" - }, - { - "title": "property", - "description": null, - "lineNumber": 8, - "type": { - "type": "NameExpression", - "name": "number" - }, - "name": "theTime.seconds" - } - ] - } - ], - "returns": [ - { - "title": "returns", - "description": "foo something else", - "lineNumber": 9, - "type": { - "type": "NameExpression", - "name": "Object" - } - } - ], - "members": { - "instance": [], - "static": [] - }, - "path": [ - "foo" - ] - } -] \ No newline at end of file diff --git a/test/fixture/nested_properties.output.md b/test/fixture/nested_properties.output.md deleted file mode 100644 index 1a3827c86..000000000 --- a/test/fixture/nested_properties.output.md +++ /dev/null @@ -1,16 +0,0 @@ -# foo - -**Parameters** - -- `options` **Object** some options - - `options.much` **number** how much -- `bar` **number** something else - -**Properties** - -- `theTime` **Object** the current time - - `theTime.hours` **number** - - `theTime.minutes` **number** - - `theTime.seconds` **number** - -Returns **Object** foo something else diff --git a/test/fixture/nested_properties.output.md.json b/test/fixture/nested_properties.output.md.json deleted file mode 100644 index 16088319b..000000000 --- a/test/fixture/nested_properties.output.md.json +++ /dev/null @@ -1,451 +0,0 @@ -{ - "type": "root", - "children": [ - { - "depth": 1, - "type": "heading", - "children": [ - { - "type": "text", - "value": "foo" - } - ] - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "Parameters" - } - ] - }, - { - "ordered": false, - "type": "list", - "children": [ - { - "type": "listItem", - "children": [ - { - "type": "paragraph", - "children": [ - { - "type": "inlineCode", - "value": "options" - }, - { - "type": "text", - "value": " " - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "Object" - } - ] - }, - { - "type": "text", - "value": " " - }, - { - "type": "paragraph", - "children": [ - { - "type": "text", - "value": "some options", - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 13 - }, - "indent": [] - } - } - ], - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 13 - }, - "indent": [] - } - } - ] - }, - { - "ordered": false, - "type": "list", - "children": [ - { - "type": "listItem", - "children": [ - { - "type": "paragraph", - "children": [ - { - "type": "inlineCode", - "value": "options.much" - }, - { - "type": "text", - "value": " " - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "number" - } - ] - }, - { - "type": "text", - "value": " " - }, - { - "type": "paragraph", - "children": [ - { - "type": "text", - "value": "how much", - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 9 - }, - "indent": [] - } - } - ], - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 9 - }, - "indent": [] - } - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "listItem", - "children": [ - { - "type": "paragraph", - "children": [ - { - "type": "inlineCode", - "value": "bar" - }, - { - "type": "text", - "value": " " - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "number" - } - ] - }, - { - "type": "text", - "value": " " - }, - { - "type": "paragraph", - "children": [ - { - "type": "text", - "value": "something else", - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 15 - }, - "indent": [] - } - } - ], - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 15 - }, - "indent": [] - } - } - ] - } - ] - } - ] - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "Properties" - } - ] - }, - { - "ordered": false, - "type": "list", - "children": [ - { - "type": "listItem", - "children": [ - { - "type": "paragraph", - "children": [ - { - "type": "inlineCode", - "value": "theTime" - }, - { - "type": "text", - "value": " " - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "Object" - } - ] - }, - { - "type": "text", - "value": " " - }, - { - "type": "paragraph", - "children": [ - { - "type": "text", - "value": "the current time", - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 17 - }, - "indent": [] - } - } - ], - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 17 - }, - "indent": [] - } - } - ] - }, - { - "ordered": false, - "type": "list", - "children": [ - { - "type": "listItem", - "children": [ - { - "type": "paragraph", - "children": [ - { - "type": "inlineCode", - "value": "theTime.hours" - }, - { - "type": "text", - "value": " " - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "number" - } - ] - }, - { - "type": "text", - "value": " " - } - ] - } - ] - }, - { - "type": "listItem", - "children": [ - { - "type": "paragraph", - "children": [ - { - "type": "inlineCode", - "value": "theTime.minutes" - }, - { - "type": "text", - "value": " " - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "number" - } - ] - }, - { - "type": "text", - "value": " " - } - ] - } - ] - }, - { - "type": "listItem", - "children": [ - { - "type": "paragraph", - "children": [ - { - "type": "inlineCode", - "value": "theTime.seconds" - }, - { - "type": "text", - "value": " " - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "number" - } - ] - }, - { - "type": "text", - "value": " " - } - ] - } - ] - } - ] - } - ] - } - ] - }, - { - "type": "paragraph", - "children": [ - { - "type": "text", - "value": "Returns " - }, - { - "type": "strong", - "children": [ - { - "type": "text", - "value": "Object" - } - ] - }, - { - "type": "text", - "value": " " - }, - { - "type": "paragraph", - "children": [ - { - "type": "text", - "value": "foo something else", - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 19 - }, - "indent": [] - } - } - ], - "position": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 19 - }, - "indent": [] - } - } - ] - } - ] -} \ No newline at end of file diff --git a/test/fixture/newline-in-description.output.json b/test/fixture/newline-in-description.output.json index 707ee9315..5ec1a8780 100644 --- a/test/fixture/newline-in-description.output.json +++ b/test/fixture/newline-in-description.output.json @@ -36,10 +36,6 @@ } }, "errors": [ - { - "message": "type Number found, number is standard", - "commentLineNumber": 2 - }, { "message": "could not determine @name for hierarchy" } diff --git a/test/fixture/simple-two.output.json b/test/fixture/simple-two.output.json index d3e464978..220a3c41d 100644 --- a/test/fixture/simple-two.output.json +++ b/test/fixture/simple-two.output.json @@ -50,12 +50,7 @@ }, "code": "/**\n * This function returns the number plus two.\n *\n * @param {Number} a the number\n * @returns {Number} numbertwo\n * @example\n * var result = returnTwo(4);\n * // result is 6\n */\nfunction returnTwo(a) {\n // this returns a + 2\n return a + 2;\n}\n" }, - "errors": [ - { - "message": "type Number found, number is standard", - "commentLineNumber": 3 - } - ], + "errors": [], "params": [ { "title": "param", diff --git a/test/fixture/throws.output.json b/test/fixture/throws.output.json index ae9f2d352..0aee1450f 100644 --- a/test/fixture/throws.output.json +++ b/test/fixture/throws.output.json @@ -59,12 +59,7 @@ }, "code": "/**\n * This function returns the number plus two.\n *\n * @param {Number} a the number\n * @returns {Number} numbertwo\n * @throws {Error} if number is 3\n * @example\n * var result = returnTwo(4);\n * // result is 6\n */\nfunction returnTwo(a) {\n if (a === 3) throw new Error('cannot be 3');\n // this returns a + 2\n return a + 2;\n}\n" }, - "errors": [ - { - "message": "type Number found, number is standard", - "commentLineNumber": 3 - } - ], + "errors": [], "params": [ { "title": "param", diff --git a/test/lib/lint.js b/test/lib/lint.js index 944fc9a87..ffcbf8222 100644 --- a/test/lib/lint.js +++ b/test/lib/lint.js @@ -2,8 +2,8 @@ var test = require('tap').test, parse = require('../../lib/parsers/javascript'), - lint = require('../../lib/lint').lint, - format = require('../../lib/lint').format; + lintComments = require('../../lib/lint').lintComments, + formatLint = require('../../lib/lint').formatLint; function toComment(fn, filename) { return parse({ @@ -13,10 +13,10 @@ function toComment(fn, filename) { } function evaluate(fn) { - return lint(toComment(fn, 'input.js')); + return lintComments(toComment(fn, 'input.js')); } -test('lint', function (t) { +test('lintComments', function (t) { t.deepEqual(evaluate(function () { /** * @param {String} foo @@ -45,7 +45,7 @@ test('lint', function (t) { t.end(); }); -test('format', function (t) { +test('formatLint', function (t) { var comment = evaluate(function () { /** * @param {String} foo @@ -54,7 +54,7 @@ test('format', function (t) { */ }); - var formatted = format([comment]); + var formatted = formatLint([comment]); t.contains(formatted, 'input.js'); t.contains(formatted, /1:1[^\n]+Braces are not balanced/); diff --git a/test/lib/server.js b/test/lib/server.js new file mode 100644 index 000000000..23df44bc6 --- /dev/null +++ b/test/lib/server.js @@ -0,0 +1,83 @@ +'use strict'; + +var test = require('tap').test, + get = require('../utils').get, + File = require('vinyl'), + Server = require('../../lib/server'); + +var jsFile = new File({ + cwd: '/', + base: '/test/', + path: '/test/file.js', + contents: new Buffer('var test = 123;') +}); + +var coffeeFile = new File({ + cwd: '/', + base: '/test/', + path: '/test/file.coffee', + contents: new Buffer('test = 123') +}); + +var indexFile = new File({ + cwd: '/', + base: '/test/', + path: '/test/index.html', + contents: new Buffer('') +}); + +test('server', function (t) { + var server = new Server(); + t.ok(server, 'server is initialized'); + server.start(function () { + + t.test('start can be called more than once, without a callback', function (tt) { + server.start(); + tt.end(); + }); + + t.test('base path', function (tt) { + get('http://localhost:4001/file.coffee', function (code) { + tt.equal(code, 404, 'does not have a file, emits 404'); + tt.end(); + }); + }); + + t.test('base path', function (tt) { + server.setFiles([coffeeFile]); + get('http://localhost:4001/file.coffee', function (text) { + tt.equal(text, 'test = 123', 'emits response'); + tt.end(); + }); + }); + + t.test('reset files', function (tt) { + server.setFiles([coffeeFile, jsFile]); + get('http://localhost:4001/file.js', function (text) { + tt.equal(text, 'var test = 123;', 'emits response'); + tt.end(); + }); + }); + + t.test('index.html special case', function (tt) { + server.setFiles([coffeeFile, indexFile, jsFile]); + get('http://localhost:4001/', function (text) { + tt.equal(text, '', 'sends index.html when / is requested'); + tt.end(); + }); + }); + + t.test('cleanup', function (tt) { + server.stop(function () { + tt.end(); + }); + }); + + t.test('stop can be called more than once, without a callback', function (tt) { + server.stop(); + tt.end(); + }); + + t.end(); + }); +}); diff --git a/test/test.js b/test/test.js index d6a1b89ef..b75d25a53 100644 --- a/test/test.js +++ b/test/test.js @@ -229,3 +229,22 @@ test('accepts simple relative paths', function (t) { }); }); }); + +test('.lint', function (t) { + chdir(__dirname, function () { + documentation.lint('fixture/simple.input.js', null, function (err, data) { + t.ifError(err); + t.equal(data, '', 'outputs lint information'); + t.end(); + }); + }); +}); + +test('.lint with bad input', function (t) { + chdir(__dirname, function () { + documentation.lint('fixture/bad/syntax.input.js', null, function (err, data) { + t.ok(err, 'returns an error when syntax is incorrect'); + t.end(); + }); + }); +}); diff --git a/test/utils.js b/test/utils.js new file mode 100644 index 000000000..e9b075614 --- /dev/null +++ b/test/utils.js @@ -0,0 +1,15 @@ +var http = require('http'), + concat = require('concat-stream'); + +function get(url, callback) { + http.get(url, function (res) { + res.pipe(concat(function (text) { + if (res.statusCode >= 400) { + return callback(res.statusCode); + } + callback(text.toString()); + })); + }); +} + +module.exports.get = get;