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
|
||||
following command:
|
||||
|
||||
jsdoc --debug
|
||||
|
||||
or the long form version:
|
||||
|
||||
$ java -classpath lib/js.jar \
|
||||
org.mozilla.javascript.tools.debugger.Main -debug \
|
||||
-modules node_modules -modules rhino_modules -modules . \
|
||||
jsdoc.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"
|
||||
menu, then press the "Run" button. If there is an error, you should see exactly
|
||||
where it is in the source code.
|
||||
|
||||
21
jsdoc
21
jsdoc
@ -4,6 +4,23 @@
|
||||
SOURCE="$0"
|
||||
while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done
|
||||
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} $@
|
||||
58
jsdoc.js
58
jsdoc.js
@ -82,8 +82,9 @@ try { main(); }
|
||||
catch(e) {
|
||||
if (e.rhinoException != null) {
|
||||
e.rhinoException.printStackTrace();
|
||||
}
|
||||
else throw e;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
finally { env.run.finish = new Date(); }
|
||||
|
||||
@ -128,6 +129,33 @@ function 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,7 +172,6 @@ function main() {
|
||||
}
|
||||
},
|
||||
resolver,
|
||||
dictionary = require('jsdoc/tag/dictionary'),
|
||||
fs = require('fs');
|
||||
|
||||
env.opts = jsdoc.opts.parser.parse(env.args);
|
||||
@ -192,34 +219,13 @@ function main() {
|
||||
if (env.opts.help) {
|
||||
console.log( jsdoc.opts.parser.help() );
|
||||
exit(0);
|
||||
}
|
||||
else if (env.opts.test) {
|
||||
} else if (env.opts.test) {
|
||||
include('test/runner.js');
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// allow user-defined plugins to...
|
||||
if (env.conf.plugins) {
|
||||
for (var i = 0, leni = env.conf.plugins.length; i < leni; i++) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
installPlugins(env.conf.plugins);
|
||||
}
|
||||
|
||||
// any source file named package.json is treated special
|
||||
|
||||
@ -33,4 +33,3 @@ process = {
|
||||
},
|
||||
argv: [__dirname + '/jsdoc.js'].concat(Array.prototype.slice.call(arguments, 0))
|
||||
};
|
||||
|
||||
67
node_modules/common/args.js
generated
vendored
67
node_modules/common/args.js
generated
vendored
@ -14,21 +14,23 @@
|
||||
*/
|
||||
exports.ArgParser = function() {
|
||||
this._options = [];
|
||||
}
|
||||
this._shortNameIndex = {};
|
||||
this._longNameIndex = {};
|
||||
};
|
||||
|
||||
exports.ArgParser.prototype._getOptionByShortName = function(name) {
|
||||
for (var i = this._options.length; i--;) {
|
||||
if (this._options[i].shortName === name) { return this._options[i]; }
|
||||
if (this._shortNameIndex.hasOwnProperty(name)) {
|
||||
return this._options[this._shortNameIndex[name]];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
exports.ArgParser.prototype._getOptionByLongName = function(name) {
|
||||
for (var i = this._options.length; i--;) {
|
||||
if (this._options[i].longName === name) { return this._options[i]; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (this._longNameIndex.hasOwnProperty(name)) {
|
||||
return this._options[this._longNameIndex[name]];
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provide information about a legal option.
|
||||
@ -40,8 +42,14 @@
|
||||
* myParser.addOption('t', 'template', true, 'The path to the template.');
|
||||
* myParser.addOption('h', 'help', false, 'Show the help message.');
|
||||
*/
|
||||
exports.ArgParser.prototype.addOption = function(shortName, longName, hasValue, helpText) {
|
||||
this._options.push({shortName: shortName, longName: longName, hasValue: hasValue, helpText: helpText});
|
||||
exports.ArgParser.prototype.addOption = function(shortName, longName, hasValue, helpText, canHaveMultiple) {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -49,28 +57,30 @@
|
||||
@returns {string}
|
||||
*/
|
||||
exports.ArgParser.prototype.help = function() {
|
||||
var help = 'OPTIONS:\n',
|
||||
option;
|
||||
var helpArr = ['OPTIONS:'],
|
||||
option, optionHelp;
|
||||
|
||||
for (var i = 0, leni = this._options.length; i < leni; i++) {
|
||||
option = this._options[i];
|
||||
optionHelp = '\t';
|
||||
|
||||
if (option.shortName) {
|
||||
help += '-' + option.shortName + (option.longName? ' or ' : '');
|
||||
optionHelp += '-' + option.shortName + (option.longName ? ', ' : '');
|
||||
}
|
||||
|
||||
if (option.longName) {
|
||||
help += '--' + option.longName;
|
||||
optionHelp += '--' + option.longName;
|
||||
}
|
||||
|
||||
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');
|
||||
};
|
||||
|
||||
/**
|
||||
@ -82,15 +92,15 @@
|
||||
provided, or `true` if the option accepts no value.
|
||||
*/
|
||||
exports.ArgParser.prototype.parse = function(args, defaults) {
|
||||
var result = defaults || {};
|
||||
var util = require('common/util'),
|
||||
result = defaults && util.mixin({}, defaults) || {};
|
||||
|
||||
result._ = [];
|
||||
|
||||
for (var i = 0, leni = args.length; i < leni; i++) {
|
||||
var arg = '' + args[i],
|
||||
next = (i < leni-1)? '' + args[i+1] : null,
|
||||
option,
|
||||
shortName,
|
||||
shortName = null,
|
||||
longName,
|
||||
name,
|
||||
value = null;
|
||||
@ -128,7 +138,18 @@
|
||||
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 {
|
||||
result._.push(arg);
|
||||
@ -136,5 +157,5 @@
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
})();
|
||||
@ -342,3 +342,32 @@ 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
|
||||
setting a ```stopPropagation``` property on the event object (e.stopPropagation = true).
|
||||
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,6 +1,6 @@
|
||||
/**
|
||||
@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>
|
||||
*/
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
exports.handlers = {
|
||||
/**
|
||||
Translate HTML tags in descriptions into safe entities.
|
||||
Replaces <, & and newlines
|
||||
*/
|
||||
newDoclet: function(e) {
|
||||
if (e.doclet.description) {
|
||||
|
||||
@ -6,12 +6,12 @@
|
||||
|
||||
|
||||
exports.handlers = {
|
||||
///
|
||||
/// Remove rails tags from the source input (e.g. <% foo bar %>)
|
||||
/// @param e
|
||||
/// @param e.filename
|
||||
/// @param e.source
|
||||
///
|
||||
/**
|
||||
* 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, "");
|
||||
|
||||
@ -8,6 +8,7 @@ exports.handlers = {
|
||||
Support @source tag. Expected value like:
|
||||
{ "filename": "myfile.js", "lineno": 123 }
|
||||
Modifies the corresponding meta values on the given doclet.
|
||||
@source { "filename": "sourcetag.js", "lineno": 13 }
|
||||
*/
|
||||
newDoclet: function(e) {
|
||||
var tags = e.doclet.tags,
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
@ -13,6 +13,11 @@ var readdirSync = exports.readdirSync = function(path) {
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
@ -58,21 +63,21 @@ var ls = exports.ls = function(dir, recurse, _allFiles, _path) {
|
||||
return _allFiles;
|
||||
};
|
||||
|
||||
var stat = exports.stat = function(path, encoding) {
|
||||
var f = new java.io.File(path)
|
||||
var stat = exports.stat = exports.statSync = function(path, encoding) {
|
||||
var f = new java.io.File(path);
|
||||
return {
|
||||
isFile: function() {
|
||||
return f.isFile();
|
||||
},
|
||||
isDir: function() {
|
||||
isDirectory: function() {
|
||||
return f.isDirectory();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
exports.mkPath = function(/**Array*/ path) {
|
||||
if (path.constructor != Array) path = path.split(/[\\\/]/);
|
||||
if (path.constructor != Array){path = path.split(/[\\\/]/);}
|
||||
var make = "";
|
||||
for (var i = 0, l = path.length; i < l; i++) {
|
||||
make += path[i] + '/';
|
||||
@ -116,7 +121,7 @@ var toDir = exports.toDir = function(path) {
|
||||
};
|
||||
|
||||
exports.copyFile = function(inFile, outDir, fileName) {
|
||||
if (fileName == null) fileName = toFile(inFile);
|
||||
if (fileName == null){fileName = toFile(inFile);}
|
||||
|
||||
outDir = toDir(outDir);
|
||||
|
||||
@ -136,7 +141,7 @@ exports.copyFile = function(inFile, outDir, fileName) {
|
||||
var toFile = exports.toFile = function(path) {
|
||||
var parts = path.split(/[\\\/]/);
|
||||
return parts.pop();
|
||||
}
|
||||
};
|
||||
|
||||
exports.writeFileSync = function(filename, data, encoding) {
|
||||
encoding = encoding || 'utf-8';
|
||||
|
||||
@ -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('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
|
||||
// TODO [-f, filter] = a regex to filter on <-- this can be better defined in the configs?
|
||||
//Here are options specific to tests
|
||||
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.
|
||||
|
||||
@ -183,5 +183,5 @@ exports.attachTo = function(parser) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ exports.Parser = function() {
|
||||
}
|
||||
};
|
||||
this._visitors = [];
|
||||
}
|
||||
};
|
||||
require('common/util').mixin(exports.Parser.prototype, require('common/events'));
|
||||
|
||||
/**
|
||||
@ -72,7 +72,7 @@ exports.Parser.prototype.parse = function(sourceFiles, encoding) {
|
||||
}
|
||||
|
||||
return this._resultBuffer;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {Array<Doclet>} The accumulated results of any calls to parse.
|
||||
|
||||
@ -1,11 +1,29 @@
|
||||
|
||||
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) {
|
||||
var parts = path.split('/');
|
||||
var parts = path.split(fileSeparator);
|
||||
parts.pop();
|
||||
path = parts.join('/');
|
||||
path = parts.join(fileSeparator);
|
||||
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) {
|
||||
var file = new java.io.File(path);
|
||||
|
||||
@ -15,3 +33,114 @@ exports.existsSync = function(path) {
|
||||
|
||||
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