mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
Merge pull request #117 from jannon/SmartTestRunner
Upgrade testing framework
This commit is contained in:
commit
7d97a17421
@ -72,12 +72,18 @@ JavaScript. Luckily it comes with a full-on debugger included that can be much
|
|||||||
more useful than a simple stack trace. To invoke JSDoc with the debugger try the
|
more useful than a simple stack trace. To invoke JSDoc with the debugger try the
|
||||||
following command:
|
following command:
|
||||||
|
|
||||||
|
jsdoc --debug
|
||||||
|
|
||||||
|
or the long form version:
|
||||||
|
|
||||||
$ java -classpath lib/js.jar \
|
$ java -classpath lib/js.jar \
|
||||||
org.mozilla.javascript.tools.debugger.Main -debug \
|
org.mozilla.javascript.tools.debugger.Main -debug \
|
||||||
-modules node_modules -modules rhino_modules -modules . \
|
-modules node_modules -modules rhino_modules -modules . \
|
||||||
jsdoc.js \
|
jsdoc.js \
|
||||||
your/script.js
|
your/script.js
|
||||||
|
|
||||||
|
Note: ```--debug``` must be the first argument to the short form command
|
||||||
|
|
||||||
This will open a debugging window. Choose "Break on Exceptions" from the "Debug"
|
This will open a debugging window. Choose "Break on Exceptions" from the "Debug"
|
||||||
menu, then press the "Run" button. If there is an error, you should see exactly
|
menu, then press the "Run" button. If there is an error, you should see exactly
|
||||||
where it is in the source code.
|
where it is in the source code.
|
||||||
|
|||||||
21
jsdoc
21
jsdoc
@ -4,6 +4,23 @@
|
|||||||
SOURCE="$0"
|
SOURCE="$0"
|
||||||
while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done
|
while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done
|
||||||
BASEDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
BASEDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||||
java -classpath ${BASEDIR}/lib/js.jar org.mozilla.javascript.tools.shell.Main -modules ${BASEDIR}/node_modules -modules ${BASEDIR}/rhino_modules -modules ${BASEDIR} ${BASEDIR}/jsdoc.js --dirname=${BASEDIR} $@
|
|
||||||
|
|
||||||
#java -classpath ${BASEDIR}/lib/js.jar org.mozilla.javascript.tools.debugger.Main -debug -modules ${BASEDIR}/node_modules -modules ${BASEDIR}/rhino_modules -modules ${BASEDIR} ${BASEDIR}/jsdoc.js --dirname=${BASEDIR} $@
|
if test $1 = "--debug"
|
||||||
|
then
|
||||||
|
CMD="org.mozilla.javascript.tools.debugger.Main -debug"
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
CMD="org.mozilla.javascript.tools.shell.Main"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#Conditionally execute different command lines depending on whether we're running tests or not
|
||||||
|
if test $1 = "-T"
|
||||||
|
then
|
||||||
|
echo "Running Tests"
|
||||||
|
java -classpath ${BASEDIR}/lib/js.jar ${CMD} -opt -1 -modules ${BASEDIR}/node_modules -modules ${BASEDIR}/rhino_modules -modules ${BASEDIR} ${BASEDIR}/jsdoc.js --dirname=${BASEDIR} $@
|
||||||
|
else
|
||||||
|
echo "Running Normal"
|
||||||
|
java -classpath ${BASEDIR}/lib/js.jar ${CMD} -modules ${BASEDIR}/node_modules -modules ${BASEDIR}/rhino_modules -modules ${BASEDIR} ${BASEDIR}/jsdoc.js --dirname=${BASEDIR} $@
|
||||||
|
fi
|
||||||
|
|
||||||
|
#java -classpath ${BASEDIR}/lib/js.jar ${CMD} -modules ${BASEDIR}/node_modules -modules ${BASEDIR}/rhino_modules -modules ${BASEDIR} ${BASEDIR}/jsdoc.js --dirname=${BASEDIR} $@
|
||||||
112
jsdoc.js
112
jsdoc.js
@ -34,7 +34,7 @@ load(__dirname + '/lib/rhino-shim.js');
|
|||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
|
||||||
|
|
||||||
/** Data representing the environment in which this app is running.
|
/** Data representing the environment in which this app is running.
|
||||||
@namespace
|
@namespace
|
||||||
*/
|
*/
|
||||||
@ -44,20 +44,20 @@ env = {
|
|||||||
start: new Date(),
|
start: new Date(),
|
||||||
finish: null
|
finish: null
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The command line arguments passed into jsdoc.
|
The command line arguments passed into jsdoc.
|
||||||
@type Array
|
@type Array
|
||||||
*/
|
*/
|
||||||
args: Array.prototype.slice.call(args, 0),
|
args: Array.prototype.slice.call(args, 0),
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The parsed JSON data from the configuration file.
|
The parsed JSON data from the configuration file.
|
||||||
@type Object
|
@type Object
|
||||||
*/
|
*/
|
||||||
conf: {},
|
conf: {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The command line arguments, parsed into a key/value hash.
|
The command line arguments, parsed into a key/value hash.
|
||||||
@type Object
|
@type Object
|
||||||
@ -79,12 +79,13 @@ app = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try { main(); }
|
try { main(); }
|
||||||
catch(e) {
|
catch(e) {
|
||||||
if (e.rhinoException != null) {
|
if (e.rhinoException != null) {
|
||||||
e.rhinoException.printStackTrace();
|
e.rhinoException.printStackTrace();
|
||||||
}
|
} else {
|
||||||
else throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
finally { env.run.finish = new Date(); }
|
finally { env.run.finish = new Date(); }
|
||||||
|
|
||||||
/** Print string/s out to the console.
|
/** Print string/s out to the console.
|
||||||
@ -119,7 +120,7 @@ function include(filepath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Cause the VM running jsdoc to exit running.
|
Cause the VM running jsdoc to exit running.
|
||||||
@param {number} [n = 0] The exit status.
|
@param {number} [n = 0] The exit status.
|
||||||
*/
|
*/
|
||||||
@ -128,6 +129,33 @@ function exit(n) {
|
|||||||
java.lang.System.exit(n);
|
java.lang.System.exit(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function installPlugins(plugins, p) {
|
||||||
|
var dictionary = require('jsdoc/tag/dictionary'),
|
||||||
|
parser = p || app.jsdoc.parser;
|
||||||
|
|
||||||
|
// allow user-defined plugins to...
|
||||||
|
for (var i = 0, leni = plugins.length; i < leni; i++) {
|
||||||
|
var plugin = require(plugins[i]);
|
||||||
|
|
||||||
|
//...register event handlers
|
||||||
|
if (plugin.handlers) {
|
||||||
|
for (var eventName in plugin.handlers) {
|
||||||
|
parser.on(eventName, plugin.handlers[eventName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//...define tags
|
||||||
|
if (plugin.defineTags) {
|
||||||
|
plugin.defineTags(dictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
//...add a node visitor
|
||||||
|
if (plugin.nodeVisitor) {
|
||||||
|
parser.addNodeVisitor(plugin.nodeVisitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
|
||||||
|
|
||||||
@ -144,11 +172,10 @@ function main() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
resolver,
|
resolver,
|
||||||
dictionary = require('jsdoc/tag/dictionary'),
|
|
||||||
fs = require('fs');
|
fs = require('fs');
|
||||||
|
|
||||||
env.opts = jsdoc.opts.parser.parse(env.args);
|
env.opts = jsdoc.opts.parser.parse(env.args);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
env.conf = JSON.parse(
|
env.conf = JSON.parse(
|
||||||
fs.readFileSync( env.opts.configure || __dirname + '/conf.json' )
|
fs.readFileSync( env.opts.configure || __dirname + '/conf.json' )
|
||||||
@ -162,10 +189,10 @@ function main() {
|
|||||||
env.conf = JSON.parse(example);
|
env.conf = JSON.parse(example);
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
throw('Configuration file cannot be evaluated. ' + e);
|
throw('Configuration file cannot be evaluated. ' + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow to pass arguments from configuration file
|
// allow to pass arguments from configuration file
|
||||||
if (env.conf.opts) {
|
if (env.conf.opts) {
|
||||||
for (var opt in env.conf.opts) {
|
for (var opt in env.conf.opts) {
|
||||||
@ -179,47 +206,26 @@ function main() {
|
|||||||
env.opts._ = env.conf.opts._.concat( env.opts._ );
|
env.opts._ = env.conf.opts._.concat( env.opts._ );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env.opts.query) {
|
if (env.opts.query) {
|
||||||
env.opts.query = require('common/query').toObject(env.opts.query);
|
env.opts.query = require('common/query').toObject(env.opts.query);
|
||||||
}
|
}
|
||||||
|
|
||||||
// which version of javascript will be supported? (rhino only)
|
// which version of javascript will be supported? (rhino only)
|
||||||
if (typeof version === 'function') {
|
if (typeof version === 'function') {
|
||||||
version(env.conf.jsVersion || 180);
|
version(env.conf.jsVersion || 180);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env.opts.help) {
|
if (env.opts.help) {
|
||||||
console.log( jsdoc.opts.parser.help() );
|
console.log( jsdoc.opts.parser.help() );
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
} else if (env.opts.test) {
|
||||||
else if (env.opts.test) {
|
|
||||||
include('test/runner.js');
|
include('test/runner.js');
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow user-defined plugins to...
|
|
||||||
if (env.conf.plugins) {
|
if (env.conf.plugins) {
|
||||||
for (var i = 0, leni = env.conf.plugins.length; i < leni; i++) {
|
installPlugins(env.conf.plugins);
|
||||||
var plugin = require(env.conf.plugins[i]);
|
|
||||||
|
|
||||||
//...register event handlers
|
|
||||||
if (plugin.handlers) {
|
|
||||||
for (var eventName in plugin.handlers) {
|
|
||||||
app.jsdoc.parser.on(eventName, plugin.handlers[eventName]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//...define tags
|
|
||||||
if (plugin.defineTags) {
|
|
||||||
plugin.defineTags(dictionary);
|
|
||||||
}
|
|
||||||
|
|
||||||
//...add a node visitor
|
|
||||||
if (plugin.nodeVisitor) {
|
|
||||||
app.jsdoc.parser.addNodeVisitor(plugin.nodeVisitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// any source file named package.json is treated special
|
// any source file named package.json is treated special
|
||||||
@ -231,25 +237,25 @@ function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (env.opts._.length > 0) { // are there any files to scan and parse?
|
if (env.opts._.length > 0) { // are there any files to scan and parse?
|
||||||
|
|
||||||
var includeMatch = (env.conf.source && env.conf.source.includePattern)? new RegExp(env.conf.source.includePattern) : null,
|
var includeMatch = (env.conf.source && env.conf.source.includePattern)? new RegExp(env.conf.source.includePattern) : null,
|
||||||
excludeMatch = (env.conf.source && env.conf.source.excludePattern)? new RegExp(env.conf.source.excludePattern) : null;
|
excludeMatch = (env.conf.source && env.conf.source.excludePattern)? new RegExp(env.conf.source.excludePattern) : null;
|
||||||
|
|
||||||
sourceFiles = app.jsdoc.scanner.scan(env.opts._, (env.opts.recurse? 10 : undefined), includeMatch, excludeMatch);
|
sourceFiles = app.jsdoc.scanner.scan(env.opts._, (env.opts.recurse? 10 : undefined), includeMatch, excludeMatch);
|
||||||
|
|
||||||
require('jsdoc/src/handlers').attachTo(app.jsdoc.parser);
|
require('jsdoc/src/handlers').attachTo(app.jsdoc.parser);
|
||||||
|
|
||||||
docs = app.jsdoc.parser.parse(sourceFiles, env.opts.encoding);
|
docs = app.jsdoc.parser.parse(sourceFiles, env.opts.encoding);
|
||||||
|
|
||||||
//The files are ALWAYS useful for the templates to have
|
//The files are ALWAYS useful for the templates to have
|
||||||
//If there is no package.json, just create an empty package
|
//If there is no package.json, just create an empty package
|
||||||
var packageDocs = new (require('jsdoc/package').Package)(packageJson);
|
var packageDocs = new (require('jsdoc/package').Package)(packageJson);
|
||||||
packageDocs.files = sourceFiles || [];
|
packageDocs.files = sourceFiles || [];
|
||||||
docs.push(packageDocs);
|
docs.push(packageDocs);
|
||||||
|
|
||||||
function indexAll(docs) {
|
function indexAll(docs) {
|
||||||
var lookupTable = {};
|
var lookupTable = {};
|
||||||
|
|
||||||
docs.forEach(function(doc) {
|
docs.forEach(function(doc) {
|
||||||
if ( !lookupTable.hasOwnProperty(doc.longname) ) {
|
if ( !lookupTable.hasOwnProperty(doc.longname) ) {
|
||||||
lookupTable[doc.longname] = [];
|
lookupTable[doc.longname] = [];
|
||||||
@ -258,12 +264,12 @@ function main() {
|
|||||||
});
|
});
|
||||||
docs.index = lookupTable;
|
docs.index = lookupTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
indexAll(docs);
|
indexAll(docs);
|
||||||
|
|
||||||
require('jsdoc/augment').addInherited(docs);
|
require('jsdoc/augment').addInherited(docs);
|
||||||
require('jsdoc/borrow').resolveBorrows(docs);
|
require('jsdoc/borrow').resolveBorrows(docs);
|
||||||
|
|
||||||
if (env.opts.explain) {
|
if (env.opts.explain) {
|
||||||
console.log(docs);
|
console.log(docs);
|
||||||
exit(0);
|
exit(0);
|
||||||
@ -279,7 +285,7 @@ function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
env.opts.template = env.opts.template || 'templates/default';
|
env.opts.template = env.opts.template || 'templates/default';
|
||||||
|
|
||||||
// should define a global "publish" function
|
// should define a global "publish" function
|
||||||
include(env.opts.template + '/publish.js');
|
include(env.opts.template + '/publish.js');
|
||||||
|
|
||||||
|
|||||||
@ -11,13 +11,13 @@ console = {
|
|||||||
log: function(/*...*/) {
|
log: function(/*...*/) {
|
||||||
var args = Array.prototype.slice.call(arguments, 0),
|
var args = Array.prototype.slice.call(arguments, 0),
|
||||||
dumper = dumper || require('jsdoc/util/dumper');
|
dumper = dumper || require('jsdoc/util/dumper');
|
||||||
|
|
||||||
for (var i = 0, len = args.length; i < len; i++) {
|
for (var i = 0, len = args.length; i < len; i++) {
|
||||||
if (typeof args[i] !== 'string') {
|
if (typeof args[i] !== 'string') {
|
||||||
args[i] = dumper.dump(args[i]);
|
args[i] = dumper.dump(args[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print( args.join(' ') );
|
print( args.join(' ') );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -33,4 +33,3 @@ process = {
|
|||||||
},
|
},
|
||||||
argv: [__dirname + '/jsdoc.js'].concat(Array.prototype.slice.call(arguments, 0))
|
argv: [__dirname + '/jsdoc.js'].concat(Array.prototype.slice.call(arguments, 0))
|
||||||
};
|
};
|
||||||
|
|
||||||
107
node_modules/common/args.js
generated
vendored
107
node_modules/common/args.js
generated
vendored
@ -14,22 +14,24 @@
|
|||||||
*/
|
*/
|
||||||
exports.ArgParser = function() {
|
exports.ArgParser = function() {
|
||||||
this._options = [];
|
this._options = [];
|
||||||
}
|
this._shortNameIndex = {};
|
||||||
|
this._longNameIndex = {};
|
||||||
|
};
|
||||||
|
|
||||||
exports.ArgParser.prototype._getOptionByShortName = function(name) {
|
exports.ArgParser.prototype._getOptionByShortName = function(name) {
|
||||||
for (var i = this._options.length; i--;) {
|
if (this._shortNameIndex.hasOwnProperty(name)) {
|
||||||
if (this._options[i].shortName === name) { return this._options[i]; }
|
return this._options[this._shortNameIndex[name]];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
};
|
||||||
|
|
||||||
exports.ArgParser.prototype._getOptionByLongName = function(name) {
|
exports.ArgParser.prototype._getOptionByLongName = function(name) {
|
||||||
for (var i = this._options.length; i--;) {
|
if (this._longNameIndex.hasOwnProperty(name)) {
|
||||||
if (this._options[i].longName === name) { return this._options[i]; }
|
return this._options[this._longNameIndex[name]];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide information about a legal option.
|
* Provide information about a legal option.
|
||||||
* @param {character} shortName The short name of the option, entered like: -T.
|
* @param {character} shortName The short name of the option, entered like: -T.
|
||||||
@ -40,39 +42,47 @@
|
|||||||
* myParser.addOption('t', 'template', true, 'The path to the template.');
|
* myParser.addOption('t', 'template', true, 'The path to the template.');
|
||||||
* myParser.addOption('h', 'help', false, 'Show the help message.');
|
* myParser.addOption('h', 'help', false, 'Show the help message.');
|
||||||
*/
|
*/
|
||||||
exports.ArgParser.prototype.addOption = function(shortName, longName, hasValue, helpText) {
|
exports.ArgParser.prototype.addOption = function(shortName, longName, hasValue, helpText, canHaveMultiple) {
|
||||||
this._options.push({shortName: shortName, longName: longName, hasValue: hasValue, helpText: helpText});
|
this._options.push({shortName: shortName, longName: longName, hasValue: hasValue, helpText: helpText, canHaveMultiple: (canHaveMultiple || false)});
|
||||||
|
if (shortName) {
|
||||||
|
this._shortNameIndex[shortName] = this._options.length - 1;
|
||||||
|
}
|
||||||
|
if (longName) {
|
||||||
|
this._longNameIndex[longName] = this._options.length - 1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Generate a summary of all the options with corresponding help text.
|
Generate a summary of all the options with corresponding help text.
|
||||||
@returns {string}
|
@returns {string}
|
||||||
*/
|
*/
|
||||||
exports.ArgParser.prototype.help = function() {
|
exports.ArgParser.prototype.help = function() {
|
||||||
var help = 'OPTIONS:\n',
|
var helpArr = ['OPTIONS:'],
|
||||||
option;
|
option, optionHelp;
|
||||||
|
|
||||||
for (var i = 0, leni = this._options.length; i < leni; i++) {
|
for (var i = 0, leni = this._options.length; i < leni; i++) {
|
||||||
option = this._options[i];
|
option = this._options[i];
|
||||||
|
optionHelp = '\t';
|
||||||
|
|
||||||
if (option.shortName) {
|
if (option.shortName) {
|
||||||
help += '-' + option.shortName + (option.longName? ' or ' : '');
|
optionHelp += '-' + option.shortName + (option.longName ? ', ' : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option.longName) {
|
if (option.longName) {
|
||||||
help += '--' + option.longName;
|
optionHelp += '--' + option.longName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option.hasValue) {
|
if (option.hasValue) {
|
||||||
help += ' <value>';
|
optionHelp += ' <value>';
|
||||||
}
|
}
|
||||||
|
|
||||||
help += ' ' + option.helpText + '\n';
|
optionHelp += '\t\t' + option.helpText;
|
||||||
|
helpArr.push(optionHelp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return help;
|
return helpArr.join('\n');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the options.
|
Get the options.
|
||||||
@param {Array.<string>} args An array, like ['-x', 'hello']
|
@param {Array.<string>} args An array, like ['-x', 'hello']
|
||||||
@ -82,22 +92,22 @@
|
|||||||
provided, or `true` if the option accepts no value.
|
provided, or `true` if the option accepts no value.
|
||||||
*/
|
*/
|
||||||
exports.ArgParser.prototype.parse = function(args, defaults) {
|
exports.ArgParser.prototype.parse = function(args, defaults) {
|
||||||
var result = defaults || {};
|
var util = require('common/util'),
|
||||||
|
result = defaults && util.mixin({}, defaults) || {};
|
||||||
|
|
||||||
result._ = [];
|
result._ = [];
|
||||||
|
|
||||||
for (var i = 0, leni = args.length; i < leni; i++) {
|
for (var i = 0, leni = args.length; i < leni; i++) {
|
||||||
var arg = '' + args[i],
|
var arg = '' + args[i],
|
||||||
next = (i < leni-1)? '' + args[i+1] : null,
|
next = (i < leni-1)? '' + args[i+1] : null,
|
||||||
option,
|
option,
|
||||||
shortName,
|
shortName = null,
|
||||||
longName,
|
longName,
|
||||||
name,
|
name,
|
||||||
value = null;
|
value = null;
|
||||||
|
|
||||||
// like -t
|
// like -t
|
||||||
if (arg.charAt(0) === '-') {
|
if (arg.charAt(0) === '-') {
|
||||||
|
|
||||||
// like: --template
|
// like: --template
|
||||||
if (arg.charAt(1) === '-') {
|
if (arg.charAt(1) === '-') {
|
||||||
name = longName = arg.slice(2);
|
name = longName = arg.slice(2);
|
||||||
@ -107,15 +117,15 @@
|
|||||||
name = shortName = arg.slice(1);
|
name = shortName = arg.slice(1);
|
||||||
option = this._getOptionByShortName(shortName);
|
option = this._getOptionByShortName(shortName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option === null) {
|
if (option === null) {
|
||||||
throw new Error( 'Unknown command line option found: ' + name );
|
throw new Error( 'Unknown command line option found: ' + name );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option.hasValue) {
|
if (option.hasValue) {
|
||||||
value = next;
|
value = next;
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (value === null || value.charAt(0) === '-') {
|
if (value === null || value.charAt(0) === '-') {
|
||||||
throw new Error( 'Command line option requires a value: ' + name );
|
throw new Error( 'Command line option requires a value: ' + name );
|
||||||
}
|
}
|
||||||
@ -123,18 +133,29 @@
|
|||||||
else {
|
else {
|
||||||
value = true;
|
value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option.longName && shortName) {
|
if (option.longName && shortName) {
|
||||||
name = option.longName;
|
name = option.longName;
|
||||||
}
|
}
|
||||||
|
|
||||||
result[name] = value;
|
// Allow for multiple options of the same type to be present
|
||||||
|
if (option.canHaveMultiple && result.hasOwnProperty(name)) {
|
||||||
|
var val = result[name];
|
||||||
|
if (val instanceof Array) {
|
||||||
|
val.push(value);
|
||||||
|
} else {
|
||||||
|
result[name] = [val, value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result[name] = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result._.push(arg);
|
result._.push(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
@ -341,4 +341,33 @@ doclet to the map (keyed off of the id property) of doclets it knows about.
|
|||||||
Lastly, the visitors are executed in the order the plugins are listed in the
|
Lastly, the visitors are executed in the order the plugins are listed in the
|
||||||
conf.json file. A plugin can stop later plugins from visiting a node by
|
conf.json file. A plugin can stop later plugins from visiting a node by
|
||||||
setting a ```stopPropagation``` property on the event object (e.stopPropagation = true).
|
setting a ```stopPropagation``` property on the event object (e.stopPropagation = true).
|
||||||
A plugin can stop the event from firing setting a ```preventDefault``` property.
|
A plugin can stop the event from firing setting a ```preventDefault``` property.
|
||||||
|
|
||||||
|
Packaging JSDoc 3 Plugins
|
||||||
|
----
|
||||||
|
|
||||||
|
The JSDoc 3 Jakefile has an ```install``` task that can be used to install a plugin
|
||||||
|
into the jsdoc 3 installation. So running the following will install the plugin:
|
||||||
|
|
||||||
|
$>jake install[path/to/YourPluginFolder]
|
||||||
|
|
||||||
|
_note: on some systems (like MacOS X), you may need to quote the target name and parameters_:
|
||||||
|
|
||||||
|
$>jake 'install[path/to/YourPluginFolder]'
|
||||||
|
|
||||||
|
The task is passed a directory that should look something like the following:
|
||||||
|
|
||||||
|
YourPluginFolder
|
||||||
|
|- plugins
|
||||||
|
| |- YourPlugin.js
|
||||||
|
| \- test
|
||||||
|
| |- fixtures
|
||||||
|
| | \- YourFixtures.js
|
||||||
|
| \- specs
|
||||||
|
| \- YourTests.js
|
||||||
|
\- templates
|
||||||
|
\- YourTemplate
|
||||||
|
\- publish.js
|
||||||
|
|
||||||
|
Basically everything is copied over into the jsdoc installation directory, the
|
||||||
|
directory should contain anything you want to put there.
|
||||||
@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
@overview Demonstrate how to modify the source code before the parser sees it.
|
@overview Demonstrate how to modify the source code before the parser sees it.
|
||||||
@module plugins/comentConvert
|
@module plugins/commentConvert
|
||||||
@author Michael Mathews <micmath@gmail.com>
|
@author Michael Mathews <micmath@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
exports.handlers = {
|
exports.handlers = {
|
||||||
///
|
///
|
||||||
/// Convert ///-style comments into jsdoc comments.
|
/// Convert ///-style comments into jsdoc comments.
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
exports.handlers = {
|
exports.handlers = {
|
||||||
/**
|
/**
|
||||||
Translate HTML tags in descriptions into safe entities.
|
Translate HTML tags in descriptions into safe entities.
|
||||||
|
Replaces <, & and newlines
|
||||||
*/
|
*/
|
||||||
newDoclet: function(e) {
|
newDoclet: function(e) {
|
||||||
if (e.doclet.description) {
|
if (e.doclet.description) {
|
||||||
|
|||||||
@ -6,12 +6,12 @@
|
|||||||
|
|
||||||
|
|
||||||
exports.handlers = {
|
exports.handlers = {
|
||||||
///
|
/**
|
||||||
/// Remove rails tags from the source input (e.g. <% foo bar %>)
|
* Remove rails tags from the source input (e.g. <% foo bar %>)
|
||||||
/// @param e
|
* @param e
|
||||||
/// @param e.filename
|
* @param e.filename
|
||||||
/// @param e.source
|
* @param e.source
|
||||||
///
|
*/
|
||||||
beforeParse: function(e) {
|
beforeParse: function(e) {
|
||||||
if (e.filename.match(/\.erb$/)) {
|
if (e.filename.match(/\.erb$/)) {
|
||||||
e.source = e.source.replace(/<%.*%>/g, "");
|
e.source = e.source.replace(/<%.*%>/g, "");
|
||||||
|
|||||||
@ -8,35 +8,36 @@ exports.handlers = {
|
|||||||
Support @source tag. Expected value like:
|
Support @source tag. Expected value like:
|
||||||
{ "filename": "myfile.js", "lineno": 123 }
|
{ "filename": "myfile.js", "lineno": 123 }
|
||||||
Modifies the corresponding meta values on the given doclet.
|
Modifies the corresponding meta values on the given doclet.
|
||||||
|
@source { "filename": "sourcetag.js", "lineno": 13 }
|
||||||
*/
|
*/
|
||||||
newDoclet: function(e) {
|
newDoclet: function(e) {
|
||||||
var tags = e.doclet.tags,
|
var tags = e.doclet.tags,
|
||||||
tag,
|
tag,
|
||||||
value;
|
value;
|
||||||
|
|
||||||
//console.log(e.doclet);
|
//console.log(e.doclet);
|
||||||
// any user-defined tags in this doclet?
|
// any user-defined tags in this doclet?
|
||||||
if (typeof tags !== 'undefined') {
|
if (typeof tags !== 'undefined') {
|
||||||
// only interested in the @source tags
|
// only interested in the @source tags
|
||||||
tags = tags.filter(function($) {
|
tags = tags.filter(function($) {
|
||||||
return $.title === 'source';
|
return $.title === 'source';
|
||||||
});
|
});
|
||||||
|
|
||||||
if (tags.length) {
|
if (tags.length) {
|
||||||
// take the first one
|
// take the first one
|
||||||
tag = tags[0];
|
tag = tags[0];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
value = JSON.parse(tag.value);
|
value = JSON.parse(tag.value);
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
throw new Error('@source tag expects a valid JSON value, like { "filename": "myfile.js", "lineno": 123 }.');
|
throw new Error('@source tag expects a valid JSON value, like { "filename": "myfile.js", "lineno": 123 }.');
|
||||||
}
|
}
|
||||||
|
|
||||||
!e.doclet.meta && (e.doclet.meta = {});
|
!e.doclet.meta && (e.doclet.meta = {});
|
||||||
e.doclet.meta.filename = value.filename || '';
|
e.doclet.meta.filename = value.filename || '';
|
||||||
e.doclet.meta.lineno = value.lineno || '';
|
e.doclet.meta.lineno = value.lineno || '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
20
plugins/test/fixtures/railsTemplate.js.erb
vendored
Normal file
20
plugins/test/fixtures/railsTemplate.js.erb
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
@overview Strips the rails template tags from a js.erb file
|
||||||
|
@module plugins/railsTemplate
|
||||||
|
@author Jannon Frank <jannon@jannon.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
exports.handlers = {
|
||||||
|
/**
|
||||||
|
* Remove rails tags from the source input (e.g. <% foo bar %>)
|
||||||
|
* @param e
|
||||||
|
* @param e.filename
|
||||||
|
* @param e.source
|
||||||
|
*/
|
||||||
|
beforeParse: function(e) {
|
||||||
|
if (e.filename.match(/\.erb$/)) {
|
||||||
|
e.source = e.source.replace(/<%.*%> /g, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
13
plugins/test/specs/commentConvert.js
Normal file
13
plugins/test/specs/commentConvert.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
describe("commentConvert plugin", function() {
|
||||||
|
var parser = new (require("jsdoc/src/parser")).Parser(),
|
||||||
|
plugin = require('plugins/commentConvert'),
|
||||||
|
docSet;
|
||||||
|
|
||||||
|
installPlugins(['plugins/commentConvert'], parser);
|
||||||
|
docSet = jasmine.getDocSetFromFile("plugins/commentConvert.js", parser);
|
||||||
|
|
||||||
|
it("should convert '///-style comments into jsdoc comments", function() {
|
||||||
|
var doclet = docSet.getByLongname("module:plugins/commentConvert.handlers.beforeParse");
|
||||||
|
expect(doclet.length).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
13
plugins/test/specs/escapeHtml.js
Normal file
13
plugins/test/specs/escapeHtml.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
describe("escapeHtml plugin", function() {
|
||||||
|
var parser = new (require("jsdoc/src/parser")).Parser(),
|
||||||
|
plugin = require('plugins/escapeHtml'),
|
||||||
|
docSet;
|
||||||
|
|
||||||
|
installPlugins(['plugins/escapeHtml'], parser);
|
||||||
|
docSet = jasmine.getDocSetFromFile("plugins/escapeHtml.js", parser);
|
||||||
|
|
||||||
|
it("should escape '&', '<' and newlines in doclet descriptions", function() {
|
||||||
|
var doclet = docSet.getByLongname("module:plugins/escapeHtml.handlers.newDoclet");
|
||||||
|
expect(doclet[0].description).toEqual("Translate HTML tags in descriptions into safe entities.<br> Replaces <, & and newlines");
|
||||||
|
});
|
||||||
|
});
|
||||||
22
plugins/test/specs/markdown.js
Normal file
22
plugins/test/specs/markdown.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
@overview Translate doclet descriptions from MarkDown into HTML.
|
||||||
|
@module plugins/markdown
|
||||||
|
@author Michael Mathews <micmath@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
var mdParser = require('evilstreak/markdown');
|
||||||
|
|
||||||
|
exports.handlers = {
|
||||||
|
/**
|
||||||
|
Translate markdown syntax in a new doclet's description into HTML. Is run
|
||||||
|
by JSDoc 3 whenever a "newDoclet" event fires.
|
||||||
|
*/
|
||||||
|
newDoclet: function(e) {
|
||||||
|
if (e.doclet.description) {
|
||||||
|
e.doclet.description = mdParser.toHTML(e.doclet.description)
|
||||||
|
.replace( /&/g, "&" ) // because markdown escapes these
|
||||||
|
.replace( /</g, "<" )
|
||||||
|
.replace( />/g, ">" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
15
plugins/test/specs/railsTemplate.js
Normal file
15
plugins/test/specs/railsTemplate.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
describe("railsTemplate plugin", function() {
|
||||||
|
var parser = new (require("jsdoc/src/parser")).Parser(),
|
||||||
|
plugin = require('plugins/railsTemplate');
|
||||||
|
|
||||||
|
|
||||||
|
installPlugins(['plugins/railsTemplate'], parser);
|
||||||
|
require('jsdoc/src/handlers').attachTo(parser);
|
||||||
|
|
||||||
|
it("should remove <% %> rails template tags from the source of *.erb files", function() {
|
||||||
|
var path = require("path"),
|
||||||
|
docSet = parser.parse([path.join(__dirname, "plugins/test/fixtures/railsTemplate.js.erb")]);
|
||||||
|
|
||||||
|
expect(docSet[2].description).toEqual("Remove rails tags from the source input (e.g. )");
|
||||||
|
});
|
||||||
|
});
|
||||||
13
plugins/test/specs/shout.js
Normal file
13
plugins/test/specs/shout.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
describe("shout plugin", function() {
|
||||||
|
var parser = new (require("jsdoc/src/parser")).Parser(),
|
||||||
|
plugin = require('plugins/shout'),
|
||||||
|
docSet;
|
||||||
|
|
||||||
|
installPlugins(['plugins/shout'], parser);
|
||||||
|
docSet = jasmine.getDocSetFromFile("plugins/shout.js", parser);
|
||||||
|
|
||||||
|
it("should make the description uppercase", function() {
|
||||||
|
var doclet = docSet.getByLongname("module:plugins/shout.handlers.newDoclet");
|
||||||
|
expect(doclet[0].description).toEqual("MAKE YOUR DESCRIPTIONS MORE SHOUTIER.");
|
||||||
|
});
|
||||||
|
});
|
||||||
15
plugins/test/specs/sourcetag.js
Normal file
15
plugins/test/specs/sourcetag.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
describe("sourcetag plugin", function() {
|
||||||
|
var parser = new (require("jsdoc/src/parser")).Parser(),
|
||||||
|
plugin = require('plugins/sourcetag'),
|
||||||
|
docSet;
|
||||||
|
|
||||||
|
installPlugins(['plugins/sourcetag'], parser);
|
||||||
|
docSet = jasmine.getDocSetFromFile("plugins/sourcetag.js", parser);
|
||||||
|
|
||||||
|
it("should set the lineno and filename of the doclet's meta property", function() {
|
||||||
|
var doclet = docSet.getByLongname("module:plugins/sourcetag.handlers.newDoclet");
|
||||||
|
expect(doclet[0].meta).toBeDefined();
|
||||||
|
expect(doclet[0].meta.filename).toEqual("sourcetag.js");
|
||||||
|
expect(doclet[0].meta.lineno).toEqual(13);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -7,12 +7,17 @@ exports.readFileSync = function(filename, encoding) {
|
|||||||
var readdirSync = exports.readdirSync = function(path) {
|
var readdirSync = exports.readdirSync = function(path) {
|
||||||
var dir,
|
var dir,
|
||||||
files;
|
files;
|
||||||
|
|
||||||
dir = new java.io.File(path);
|
dir = new java.io.File(path);
|
||||||
if (!dir.directory) { return [String(dir)]; }
|
if (!dir.directory) { return [String(dir)]; }
|
||||||
|
|
||||||
files = dir.list();
|
files = dir.list();
|
||||||
|
|
||||||
|
//Convert files to Javascript strings so they play nice with node modules
|
||||||
|
files = files.map(function(fileName) {
|
||||||
|
return String(fileName);
|
||||||
|
});
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -24,20 +29,20 @@ var ls = exports.ls = function(dir, recurse, _allFiles, _path) {
|
|||||||
_allFiles = [];
|
_allFiles = [];
|
||||||
_path = [dir];
|
_path = [dir];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_path.length === 0) { return _allFiles; }
|
if (_path.length === 0) { return _allFiles; }
|
||||||
if (typeof recurse === 'undefined') { recurse = 1; }
|
if (typeof recurse === 'undefined') { recurse = 1; }
|
||||||
|
|
||||||
if ( stat(dir).isFile(dir) ) {
|
if ( stat(dir).isFile(dir) ) {
|
||||||
files = [dir];
|
files = [dir];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
files = readdirSync(dir);
|
files = readdirSync(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var f = 0, lenf = files.length; f < lenf; f++) {
|
for (var f = 0, lenf = files.length; f < lenf; f++) {
|
||||||
file = String(files[f]);
|
file = String(files[f]);
|
||||||
|
|
||||||
if (file.match(/^\.[^\.\/\\]/)) { continue; } // skip dot files
|
if (file.match(/^\.[^\.\/\\]/)) { continue; } // skip dot files
|
||||||
|
|
||||||
if ((new java.io.File(_path.join('/') + '/' + file)).list()) { // it's a directory
|
if ((new java.io.File(_path.join('/') + '/' + file)).list()) { // it's a directory
|
||||||
@ -48,7 +53,7 @@ var ls = exports.ls = function(dir, recurse, _allFiles, _path) {
|
|||||||
}
|
}
|
||||||
_path.pop();
|
_path.pop();
|
||||||
}
|
}
|
||||||
else { // it's a file
|
else { // it's a file
|
||||||
_allFiles.push(
|
_allFiles.push(
|
||||||
(_path.join('/') + '/' + file).replace(/[\/\\]+/g, '/')
|
(_path.join('/') + '/' + file).replace(/[\/\\]+/g, '/')
|
||||||
);
|
);
|
||||||
@ -58,21 +63,21 @@ var ls = exports.ls = function(dir, recurse, _allFiles, _path) {
|
|||||||
return _allFiles;
|
return _allFiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
var stat = exports.stat = function(path, encoding) {
|
var stat = exports.stat = exports.statSync = function(path, encoding) {
|
||||||
var f = new java.io.File(path)
|
var f = new java.io.File(path);
|
||||||
return {
|
return {
|
||||||
isFile: function() {
|
isFile: function() {
|
||||||
return f.isFile();
|
return f.isFile();
|
||||||
},
|
},
|
||||||
isDir: function() {
|
isDirectory: function() {
|
||||||
return f.isDirectory();
|
return f.isDirectory();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.mkPath = function(/**Array*/ path) {
|
exports.mkPath = function(/**Array*/ path) {
|
||||||
if (path.constructor != Array) path = path.split(/[\\\/]/);
|
if (path.constructor != Array){path = path.split(/[\\\/]/);}
|
||||||
var make = "";
|
var make = "";
|
||||||
for (var i = 0, l = path.length; i < l; i++) {
|
for (var i = 0, l = path.length; i < l; i++) {
|
||||||
make += path[i] + '/';
|
make += path[i] + '/';
|
||||||
@ -104,25 +109,25 @@ function exists(path) {
|
|||||||
|
|
||||||
var toDir = exports.toDir = function(path) {
|
var toDir = exports.toDir = function(path) {
|
||||||
var f = new java.io.File(path);
|
var f = new java.io.File(path);
|
||||||
|
|
||||||
if (f.isDirectory()){
|
if (f.isDirectory()){
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
var parts = path.split(/[\\\/]/);
|
var parts = path.split(/[\\\/]/);
|
||||||
parts.pop();
|
parts.pop();
|
||||||
|
|
||||||
return parts.join('/');
|
return parts.join('/');
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.copyFile = function(inFile, outDir, fileName) {
|
exports.copyFile = function(inFile, outDir, fileName) {
|
||||||
if (fileName == null) fileName = toFile(inFile);
|
if (fileName == null){fileName = toFile(inFile);}
|
||||||
|
|
||||||
outDir = toDir(outDir);
|
outDir = toDir(outDir);
|
||||||
|
|
||||||
var inFile = new java.io.File(inFile);
|
var inFile = new java.io.File(inFile);
|
||||||
var outFile = new java.io.File(outDir+'/'+fileName);
|
var outFile = new java.io.File(outDir+'/'+fileName);
|
||||||
|
|
||||||
var bis = new Packages.java.io.BufferedInputStream(new Packages.java.io.FileInputStream(inFile), 4096);
|
var bis = new Packages.java.io.BufferedInputStream(new Packages.java.io.FileInputStream(inFile), 4096);
|
||||||
var bos = new Packages.java.io.BufferedOutputStream(new Packages.java.io.FileOutputStream(outFile), 4096);
|
var bos = new Packages.java.io.BufferedOutputStream(new Packages.java.io.FileOutputStream(outFile), 4096);
|
||||||
var theChar;
|
var theChar;
|
||||||
@ -136,7 +141,7 @@ exports.copyFile = function(inFile, outDir, fileName) {
|
|||||||
var toFile = exports.toFile = function(path) {
|
var toFile = exports.toFile = function(path) {
|
||||||
var parts = path.split(/[\\\/]/);
|
var parts = path.split(/[\\\/]/);
|
||||||
return parts.pop();
|
return parts.pop();
|
||||||
}
|
};
|
||||||
|
|
||||||
exports.writeFileSync = function(filename, data, encoding) {
|
exports.writeFileSync = function(filename, data, encoding) {
|
||||||
encoding = encoding || 'utf-8';
|
encoding = encoding || 'utf-8';
|
||||||
@ -147,7 +152,7 @@ exports.writeFileSync = function(filename, data, encoding) {
|
|||||||
encoding
|
encoding
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
out.write(data);
|
out.write(data);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,9 +27,13 @@ argParser.addOption('X', 'explain', false, 'Dump all found doclet internals
|
|||||||
argParser.addOption('q', 'query', true, 'Provide a querystring to define custom variable names/values to add to the options hash.');
|
argParser.addOption('q', 'query', true, 'Provide a querystring to define custom variable names/values to add to the options hash.');
|
||||||
argParser.addOption('u', 'tutorials', true, 'Directory in which JSDoc should search for tutorials.');
|
argParser.addOption('u', 'tutorials', true, 'Directory in which JSDoc should search for tutorials.');
|
||||||
|
|
||||||
|
//TODO [-R, recurseonly] = a number representing the depth to recurse
|
||||||
|
//TODO [-f, filter] = a regex to filter on <-- this can be better defined in the configs?
|
||||||
|
|
||||||
// TODO [-R, recurseonly] = a number representing the depth to recurse
|
//Here are options specific to tests
|
||||||
// TODO [-f, filter] = a regex to filter on <-- this can be better defined in the configs?
|
argParser.addOption(null, 'verbose', false, 'Display verbose output for tests');
|
||||||
|
argParser.addOption(null, 'match', true, 'only run tests containing <value>', true);
|
||||||
|
argParser.addOption(null, 'coffee', false, 'load coffee-script which allows execution .coffee files');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set the options for this app.
|
Set the options for this app.
|
||||||
@ -38,13 +42,13 @@ argParser.addOption('u', 'tutorials', true, 'Directory in which JSDoc should
|
|||||||
*/
|
*/
|
||||||
exports.parse = function(args) {
|
exports.parse = function(args) {
|
||||||
args = args || [];
|
args = args || [];
|
||||||
|
|
||||||
if (typeof args === 'string' || args.constructor === String) {
|
if (typeof args === 'string' || args.constructor === String) {
|
||||||
args = (''+args).split(/\s+/g);
|
args = (''+args).split(/\s+/g);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourOptions = argParser.parse(args, defaults);
|
ourOptions = argParser.parse(args, defaults);
|
||||||
|
|
||||||
return ourOptions;
|
return ourOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -183,5 +183,5 @@ exports.attachTo = function(parser) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ exports.Parser = function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
this._visitors = [];
|
this._visitors = [];
|
||||||
}
|
};
|
||||||
require('common/util').mixin(exports.Parser.prototype, require('common/events'));
|
require('common/util').mixin(exports.Parser.prototype, require('common/events'));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,7 +72,7 @@ exports.Parser.prototype.parse = function(sourceFiles, encoding) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this._resultBuffer;
|
return this._resultBuffer;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {Array<Doclet>} The accumulated results of any calls to parse.
|
* @returns {Array<Doclet>} The accumulated results of any calls to parse.
|
||||||
|
|||||||
@ -1,17 +1,146 @@
|
|||||||
|
|
||||||
|
var isWindows = java.lang.System.getProperty("os.name").toLowerCase().contains("windows");
|
||||||
|
var fileSeparator = java.lang.System.getProperty("file.separator");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns everything on a path except for the last item
|
||||||
|
* e.g. if the path was 'path/to/something', the return value would be 'path/to'
|
||||||
|
*/
|
||||||
exports.basename = function(path) {
|
exports.basename = function(path) {
|
||||||
var parts = path.split('/');
|
var parts = path.split(fileSeparator);
|
||||||
parts.pop();
|
parts.pop();
|
||||||
path = parts.join('/');
|
path = parts.join(fileSeparator);
|
||||||
return path;
|
return path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last item on a path
|
||||||
|
*/
|
||||||
|
exports.filename = function(path) {
|
||||||
|
var parts = path.split(fileSeparator);
|
||||||
|
if (parts.length > 0) {
|
||||||
|
return parts.pop();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
exports.existsSync = function(path) {
|
exports.existsSync = function(path) {
|
||||||
var file = new java.io.File(path);
|
var file = new java.io.File(path);
|
||||||
|
|
||||||
if (file.isFile()) {
|
if (file.isFile()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Code below taken from node
|
||||||
|
|
||||||
|
//resolves . and .. elements in a path array with directory names there
|
||||||
|
//must be no slashes, empty elements, or device names (c:\) in the array
|
||||||
|
//(so also no leading and trailing slashes - it does not distinguish
|
||||||
|
//relative and absolute paths)
|
||||||
|
function normalizeArray(parts, allowAboveRoot) {
|
||||||
|
// if the path tries to go above the root, `up` ends up > 0
|
||||||
|
var up = 0;
|
||||||
|
for ( var i = parts.length - 1; i >= 0; i--) {
|
||||||
|
var last = parts[i];
|
||||||
|
if (last == '.') {
|
||||||
|
parts.splice(i, 1);
|
||||||
|
} else if (last === '..') {
|
||||||
|
parts.splice(i, 1);
|
||||||
|
up++;
|
||||||
|
} else if (up) {
|
||||||
|
parts.splice(i, 1);
|
||||||
|
up--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the path is allowed to go above the root, restore leading ..s
|
||||||
|
if (allowAboveRoot) {
|
||||||
|
for (; up--; up) {
|
||||||
|
parts.unshift('..');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isWindows) {
|
||||||
|
// Regex to split a windows path into three parts: [*, device, slash,
|
||||||
|
// tail] windows-only
|
||||||
|
var splitDeviceRe =
|
||||||
|
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/;
|
||||||
|
|
||||||
|
// windows version
|
||||||
|
exports.normalize = function(path) {
|
||||||
|
var result = splitDeviceRe.exec(path),
|
||||||
|
device = result[1] || '',
|
||||||
|
isUnc = device && device.charAt(1) !== ':',
|
||||||
|
isAbsolute = !!result[2] || isUnc, // UNC paths are always absolute
|
||||||
|
tail = result[3],
|
||||||
|
trailingSlash = /[\\\/]$/.test(tail);
|
||||||
|
|
||||||
|
// Normalize the tail path
|
||||||
|
tail = normalizeArray(tail.split(/[\\\/]+/).filter(function(p) {
|
||||||
|
return !!p;
|
||||||
|
}), !isAbsolute).join('\\');
|
||||||
|
|
||||||
|
if (!tail && !isAbsolute) {
|
||||||
|
tail = '.';
|
||||||
|
}
|
||||||
|
if (tail && trailingSlash) {
|
||||||
|
tail += '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
return device + (isAbsolute ? '\\' : '') + tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
//windows version
|
||||||
|
exports.join = function() {
|
||||||
|
function f(p) {
|
||||||
|
return p && typeof p === 'string';
|
||||||
|
}
|
||||||
|
|
||||||
|
var paths = Array.prototype.slice.call(arguments, 0).filter(f);
|
||||||
|
var joined = paths.join('\\');
|
||||||
|
|
||||||
|
// Make sure that the joined path doesn't start with two slashes
|
||||||
|
// - it will be mistaken for an unc path by normalize() -
|
||||||
|
// unless the paths[0] also starts with two slashes
|
||||||
|
if (/^[\\\/]{2}/.test(joined) && !/^[\\\/]{2}/.test(paths[0])) {
|
||||||
|
joined = joined.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return exports.normalize(joined);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// path.normalize(path)
|
||||||
|
// posix version
|
||||||
|
exports.normalize = function(path) {
|
||||||
|
var isAbsolute = path.charAt(0) === '/',
|
||||||
|
trailingSlash = path.slice(-1) === '/';
|
||||||
|
|
||||||
|
// Normalize the path
|
||||||
|
path = normalizeArray(path.split('/').filter(function(p) {
|
||||||
|
return !!p;
|
||||||
|
}), !isAbsolute).join('/');
|
||||||
|
|
||||||
|
if (!path && !isAbsolute) {
|
||||||
|
path = '.';
|
||||||
|
}
|
||||||
|
if (path && trailingSlash) {
|
||||||
|
path += '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (isAbsolute ? '/' : '') + path;
|
||||||
|
};
|
||||||
|
|
||||||
|
// posix version
|
||||||
|
exports.join = function() {
|
||||||
|
var paths = Array.prototype.slice.call(arguments, 0);
|
||||||
|
return exports.normalize(paths.filter(function(p, index) {
|
||||||
|
return p && typeof p === 'string';
|
||||||
|
}).join('/'));
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1,7 +1,45 @@
|
|||||||
From the project root, run the following command in the terminal:
|
Testing JSDoc 3
|
||||||
|
===============
|
||||||
|
|
||||||
java -jar lib/js.jar -modules rhino_modules -modules node_modules jsdoc.js -T
|
Running Tests
|
||||||
|
-------------
|
||||||
|
|
||||||
TODO:
|
Running tests is easy. Just change your working directory to the jsdoc folder
|
||||||
|
and run the following command on Windows:
|
||||||
|
|
||||||
More info for contributors about how tests work and about plugin/template tests
|
jsdoc -T
|
||||||
|
|
||||||
|
... or on a Max OSX or *nix platform:
|
||||||
|
|
||||||
|
./jsdoc -T
|
||||||
|
|
||||||
|
If you can't get the short-form commands to work, try invoking Java directly:
|
||||||
|
|
||||||
|
java -cp lib/js.jar org.mozilla.javascript.tools.shell.Main -opt -1 \
|
||||||
|
-modules node_modules -modules rhino_modules -modules . \
|
||||||
|
jsdoc.js -T
|
||||||
|
|
||||||
|
Writing Tests
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Adding tests is pretty easy, too. You can write tests for jsdoc itself (to
|
||||||
|
make sure tags and the parser, etc. are working properly), tests for plugins, and/or
|
||||||
|
tests for templates.
|
||||||
|
|
||||||
|
JSDoc 3 uses Jasmine (https://github.com/pivotal/jasmine) as its testing framework.
|
||||||
|
Take a look at that project's wiki for documentation on writing tests in general.
|
||||||
|
|
||||||
|
### Tests for JSDoc
|
||||||
|
|
||||||
|
Take a look at the files in the ```test``` directory for many examples of
|
||||||
|
writing tests for JSDoc itself. the ```test\fixtures``` directory hold fixtures
|
||||||
|
for use in the tests and the ```test\specs``` directory holds the tests themselves.
|
||||||
|
|
||||||
|
### Tests for plugins
|
||||||
|
|
||||||
|
Tests for plugins are found in ```plugins\test``` directory. Plugins containing
|
||||||
|
tests that were installed with the Jakefile install task will be run automatically.
|
||||||
|
|
||||||
|
### Tests for templates
|
||||||
|
|
||||||
|
TODO
|
||||||
56
test/async-callback.js
Normal file
56
test/async-callback.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
(function() {
|
||||||
|
var withoutAsync = {};
|
||||||
|
|
||||||
|
["it", "beforeEach", "afterEach"].forEach(function(jasmineFunction) {
|
||||||
|
withoutAsync[jasmineFunction] = jasmine.Env.prototype[jasmineFunction];
|
||||||
|
return jasmine.Env.prototype[jasmineFunction] = function() {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 0);
|
||||||
|
var timeout = null;
|
||||||
|
if (isLastArgumentATimeout(args)) {
|
||||||
|
timeout = args.pop();
|
||||||
|
}
|
||||||
|
if (isLastArgumentAnAsyncSpecFunction(args))
|
||||||
|
{
|
||||||
|
var specFunction = args.pop();
|
||||||
|
args.push(function() {
|
||||||
|
return asyncSpec(specFunction, this, timeout);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return withoutAsync[jasmineFunction].apply(this, args);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
function isLastArgumentATimeout(args)
|
||||||
|
{
|
||||||
|
return args.length > 0 && (typeof args[args.length-1]) === "number";
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLastArgumentAnAsyncSpecFunction(args)
|
||||||
|
{
|
||||||
|
return args.length > 0 && (typeof args[args.length-1]) === "function" && args[args.length-1].length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function asyncSpec(specFunction, spec, timeout) {
|
||||||
|
if (timeout == null){timeout = jasmine.DEFAULT_TIMEOUT_INTERVAL || 1000;}
|
||||||
|
var done = false;
|
||||||
|
spec.runs(function() {
|
||||||
|
try {
|
||||||
|
return specFunction(function(error) {
|
||||||
|
done = true;
|
||||||
|
if (error != null) {
|
||||||
|
return spec.fail(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
done = true;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return spec.waitsFor(function() {
|
||||||
|
if (done === true) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}, "spec to complete", timeout);
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
@ -1,4 +0,0 @@
|
|||||||
// Simple inheritance model with correct constructor
|
|
||||||
function Test() {}
|
|
||||||
function Test2() { Test.call(this); }
|
|
||||||
Test2.prototype = Object.create(Test.prototype, {constructor: {value: Test2}});
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
Call(
|
|
||||||
{
|
|
||||||
methodA: function()
|
|
||||||
{
|
|
||||||
this.id = this.createUUID();
|
|
||||||
},
|
|
||||||
|
|
||||||
valueOf: function()
|
|
||||||
{
|
|
||||||
return this.id;
|
|
||||||
},
|
|
||||||
|
|
||||||
toString: function()
|
|
||||||
{
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
22
test/fixtures/objectpropertykeys.js
vendored
Normal file
22
test/fixtures/objectpropertykeys.js
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Call(
|
||||||
|
{
|
||||||
|
methodA: function()
|
||||||
|
{
|
||||||
|
this.id = this.createUUID();
|
||||||
|
},
|
||||||
|
|
||||||
|
valueOf: function()
|
||||||
|
{
|
||||||
|
return this.id;
|
||||||
|
},
|
||||||
|
|
||||||
|
toString: function()
|
||||||
|
{
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Simple inheritance model with correct constructor
|
||||||
|
function Test() {}
|
||||||
|
function Test2() { Test.call(this); }
|
||||||
|
Test2.prototype = Object.create(Test.prototype, {constructor: {value: Test2}});
|
||||||
10
test/fixtures/plugins.js
vendored
Normal file
10
test/fixtures/plugins.js
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* @name virtual
|
||||||
|
*/
|
||||||
|
|
||||||
|
var foo = "bar";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @foo bar
|
||||||
|
*/
|
||||||
|
var test = "tada";
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user