fixes for Node.js compatibility (see details)

- new Rhino .jar to help find module paths
(https://github.com/hegemonic/rhino/commit/31b70105)
- make __dirname and process.cwd() provide the current module path; use
only env.dirname for JSDoc's home dir; fix callers
- get rid of jsdoc/util/include (and update test framework accordingly)
- avoid running Rhino/Node.js tests on the wrong runtime
- remove support for global 'publish' function, which relied upon
jsdoc/util/include
- update jsdoc/util/dumper for consistency with Node.js'
JSON.stringify()
- fix jsdoc/util/runtime to detect Node.js correctly
- add Node.js versions of jsdoc/fs and jsdoc/path
- other minor cleanup
This commit is contained in:
Jeff Williams 2013-10-25 23:30:56 -07:00
parent 9745685dde
commit 751bea1b0a
41 changed files with 414 additions and 370 deletions

View File

@ -15,7 +15,7 @@
* @namespace
* @name env
*/
require('lib/jsdoc/util/global').env = {
require('jsdoc/util/global').env = {
/**
* Running start and finish times.
*
@ -46,14 +46,13 @@ require('lib/jsdoc/util/global').env = {
* The absolute path to the base directory of the JSDoc application.
*
* @private
* @deprecated Use `__dirname` instead.
* @type string
* @memberof env
*/
dirname: '.',
/**
* The command-line arguments, parsed into a key/value hash.
* The command-line options, parsed into a key/value hash.
*
* @type Object
* @memberof env
@ -78,12 +77,7 @@ require('lib/jsdoc/util/global').env = {
};
// initialize the environment for the current JavaScript VM
(function(args) {
var runtime = require('jsdoc/util/runtime').getRuntime();
// TODO: may need to move this file to support Node.js
require('initialize')[runtime](args);
})( Array.prototype.slice.call(arguments, 0) );
require('jsdoc/util/runtime').initialize( Array.prototype.slice.call(arguments, 0) );
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
/**
@ -91,7 +85,7 @@ require('lib/jsdoc/util/global').env = {
* @namespace
* @name app
*/
require('lib/jsdoc/util/global').app = {
require('jsdoc/util/global').app = {
jsdoc: {
scanner: new (require('jsdoc/src/scanner').Scanner)(),
parser: null,
@ -144,9 +138,6 @@ function main() {
},
tutorial: {
resolver: require('jsdoc/tutorial/resolver')
},
util: {
include: require('jsdoc/util/include')
}
};
@ -157,9 +148,11 @@ function main() {
var i;
var info;
var isFile;
var failCount;
var l;
var packageDocs;
var packageJson;
var runner;
var sourceFiles;
var template;
@ -170,7 +163,7 @@ function main() {
};
// get JSDoc version number
info = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
info = JSON.parse(fs.readFileSync(path.join(env.dirname, 'package.json'), 'utf8'));
env.version = {
number: info.version,
revision: new Date(parseInt(info.revision, 10)).toUTCString()
@ -178,7 +171,7 @@ function main() {
env.opts = jsdoc.opts.args.parse(env.args);
confPath = env.opts.configure || path.join(__dirname, 'conf.json');
confPath = env.opts.configure || path.join(env.dirname, 'conf.json');
try {
isFile = fs.statSync(confPath).isFile();
}
@ -187,7 +180,7 @@ function main() {
}
if ( !isFile && !env.opts.configure ) {
confPath = path.join(__dirname, 'conf.json.EXAMPLE');
confPath = path.join(env.dirname, 'conf.json.EXAMPLE');
}
try {
@ -205,8 +198,10 @@ function main() {
console.log( jsdoc.opts.args.help() );
process.exit(0);
} else if (env.opts.test) {
jsdoc.util.include('test/runner.js');
process.exit(0);
runner = require( path.join(env.dirname, 'test/runner') );
runner(function(failCount) {
process.exit(failCount);
});
} else if (env.opts.version) {
console.log('JSDoc ' + env.version.number + ' (' + env.version.revision + ')');
process.exit(0);
@ -229,7 +224,7 @@ function main() {
}
}
if (env.conf.source && env.opts._.length > 0) { // are there any files to scan and parse?
if (env.conf.source && env.opts._.length) { // are there any files to scan and parse?
filter = new jsdoc.src.filter.Filter(env.conf.source);
env.sourceFiles = sourceFiles = app.jsdoc.scanner.scan(env.opts._,
@ -290,31 +285,17 @@ function main() {
);
}
else {
// old templates define a global "publish" function, which is deprecated
jsdoc.util.include(env.opts.template + '/publish.js');
if (publish && typeof publish === 'function') {
console.log( env.opts.template + ' uses a global "publish" function, which is ' +
'deprecated and may not be supported in future versions. ' +
'Please update the template to use "exports.publish" instead.' );
// convert this from a URI back to a path if necessary
env.opts.template = path._uriToPath(env.opts.template);
publish(
taffy(docs),
env.opts,
jsdoc.tutorial.resolver.root
);
}
else {
throw new Error( env.opts.template + ' does not export a "publish" function.' );
}
throw new Error(env.opts.template + ' does not export a "publish" function. Global ' +
'"publish" functions are no longer supported.');
}
process.exit(0);
}
}
try {
main();
env.run.finish = new Date();
process.exit(0);
}
catch(e) {
env.run.finish = new Date();

View File

@ -1,40 +0,0 @@
/*global env: true */
exports.rhino = function(args) {
var myGlobal = require('jsdoc/util/global');
// note: mutates args
function getDirname() {
var dirname;
// Rhino has no native way to get the base dirname of the current script,
// so this information must be manually passed in from the command line.
for (var i = 0; i < args.length; i++) {
if ( /^--dirname(?:=(.+?)(\/|\/\.)?)?$/i.test(args[i]) ) {
if (RegExp.$1) {
dirname = RegExp.$1; // last wins
args.splice(i--, 1); // remove --dirname opt from arguments
}
else {
dirname = args[i + 1];
args.splice(i--, 2);
}
}
}
return dirname;
}
myGlobal.__dirname = env.dirname = getDirname();
env.args = args;
require('jsdoc/util/include')(__dirname + '/rhino/rhino-shim.js');
};
exports.nodejs = function(args) {
throw new Error('Node.js is not currently supported!');
/*
env.dirname = __dirname;
env.args = args;
// TODO: add lib/ to the library paths
*/
};

View File

@ -1,3 +1,4 @@
/*global env: true */
/**
* Extended version of the standard `path` module.
* @module jsdoc/path
@ -16,6 +17,7 @@ function prefixReducer(previousPath, current) {
return currentPath;
}
// TODO: should probably replace process.cwd() with the CWD before launching JSDoc
currentPath = path.resolve( process.cwd(), path.dirname(current) ).split(path.sep) || [];
if (previousPath && currentPath.length) {
@ -65,7 +67,7 @@ exports.commonPrefix = function(paths) {
return common.join(path.sep);
};
// TODO: do we need this?
// TODO: can we get rid of this?
/**
* If required by the current VM, convert a path to a URI that meets the operating system's
* requirements. Otherwise, return the original path.
@ -74,9 +76,9 @@ exports.commonPrefix = function(paths) {
* @param {string} path The path to convert.
* @return {string} A URI that meets the operating system's requirements, or the original path.
*/
var pathToUri = require( runtime.getModulePath('jsdoc') ).pathToUri;
var pathToUri = require( runtime.getModulePath('path') ).pathToUri;
// TODO: do we need this? if so, any way to stop exporting it?
// TODO: can we get rid of this, or at least stop exporting it?
/**
* If required by the current VM, convert a URI to a path that meets the operating system's
* requirements. Otherwise, assume the "URI" is really a path, and return the original path.
@ -85,7 +87,7 @@ var pathToUri = require( runtime.getModulePath('jsdoc') ).pathToUri;
* @param {string} uri The URI to convert.
* @return {string} A path that meets the operating system's requirements.
*/
exports._uriToPath = require( runtime.getModulePath('jsdoc') ).uriToPath;
exports._uriToPath = require( runtime.getModulePath('path') ).uriToPath;
/**
* Retrieve the fully qualified path to the requested resource.
@ -120,7 +122,7 @@ exports.getResourcePath = function(filepath, filename) {
result = path.resolve(filepath);
if ( !pathExists(result) ) {
// next, try resolving it relative to the JSDoc directory
result = path.resolve(__dirname, filepath);
result = path.resolve(env.dirname, filepath);
if ( !pathExists(result) ) {
result = null;
}

View File

@ -1,3 +1,4 @@
/*global env: true */
/**
@module jsdoc/src/filter
@ -15,11 +16,10 @@ var path = require('jsdoc/path');
@param {string|RegExp} opts.excludePattern
*/
exports.Filter = function(opts) {
var cwd = process.cwd();
this.exclude = opts.exclude && Array.isArray(opts.exclude) ?
opts.exclude.map(function($) {
return path.resolve(cwd, $);
// TODO: should we replace env.dirname with the CWD before launching JSDoc?
return path.resolve(env.dirname, $);
}) :
null;
this.includePattern = opts.includePattern?
@ -35,7 +35,8 @@ exports.Filter = function(opts) {
@returns {boolean} Should the given file be included?
*/
exports.Filter.prototype.isIncluded = function(filepath) {
filepath = path.resolve(process.cwd(), filepath);
// TODO: should we replace env.dirname with the CWD before launching JSDoc?
filepath = path.resolve(env.dirname, filepath);
if ( this.includePattern && !this.includePattern.test(filepath) ) {
return false;

View File

@ -1,3 +1,4 @@
/*global env: true */
/**
@module jsdoc/src/scanner
@requires module:fs
@ -26,7 +27,6 @@ exports.Scanner.prototype = Object.create( require('events').EventEmitter.protot
exports.Scanner.prototype.scan = function(searchPaths, depth, filter) {
var isFile;
var cwd = process.cwd();
var filePaths = [];
var self = this;
@ -44,11 +44,13 @@ exports.Scanner.prototype.scan = function(searchPaths, depth, filter) {
}
if (isFile) {
filePaths.push( path.resolve(cwd, filepath) );
// TODO: should we replace env.dirname with the CWD before launching JSDoc?
filePaths.push( path.resolve(env.dirname, filepath) );
}
else {
filePaths = filePaths.concat( fs.ls(filepath, depth).map(function(item) {
return path.resolve(cwd, item);
// TODO: should we replace env.dirname with the CWD before launching JSDoc?
return path.resolve(env.dirname, item);
}) );
}
});

View File

@ -65,6 +65,9 @@ function walk(o) {
else if ( util.isDate(o) ) {
result = '<Date ' + o.toUTCString() + '>';
}
else if ( util.isError(o) ) {
result = { message: o.message };
}
else if ( isFunction(o) ) {
result = '<Function' + (o.name ? ' ' + o.name : '') + '>';
}

View File

@ -1,19 +0,0 @@
var path = require('path');
var runtime = require('jsdoc/util/runtime');
/**
* Read and execute a JavaScript file in global scope.
* @private
* @param {string} filepath The path to the JavaScript file. May contain an absolute path or a
* path relative to env.dirname.
*/
module.exports = function(filepath) {
filepath = path.resolve(__dirname, filepath);
try {
require( runtime.getModulePath('jsdoc/util/include') )(filepath);
}
catch (e) {
console.log('Cannot include ' + filepath + ': ' + e);
}
};

View File

@ -1,4 +1,4 @@
/*global Packages: true */
/*global env: true */
/**
* Helper functions to enable JSDoc to run on multiple JavaScript runtimes.
*
@ -6,7 +6,8 @@
* @private
*/
var os = require('os');
var myGlobal = require('jsdoc/util/global');
var os = require('os');
// These strings represent directory names; do not modify them!
/** @private */
@ -43,10 +44,10 @@ function pathToUri(filepath) {
* @private
*/
var runtime = (function() {
if (Packages && typeof Packages === 'object' &&
Object.prototype.toString.call(Packages) === '[object JavaPackage]') {
if (myGlobal.Packages && typeof myGlobal.Packages === 'object' &&
Object.prototype.toString.call(myGlobal.Packages) === '[object JavaPackage]') {
return RHINO;
} else if ( require && require.main && module && (require.main === module) ) {
} else if (require && require.main && module) {
return NODE;
} else {
// unknown runtime
@ -54,32 +55,6 @@ var runtime = (function() {
}
})();
/**
* Get the require path for the runtime-specific implementation of a module.
*
* @param {string} partialPath - The partial path to the module. Use the same format as when calling
* `require()`.
* @return {object} The require path for the runtime-specific implementation of the module.
*/
exports.getModulePath = function(partialPath) {
var modulePath = [__dirname, runtime, partialPath].join('/').replace(/ /g, '%20');
if (os.platform() === 'win32') {
modulePath = pathToUri(modulePath);
}
return modulePath;
};
/**
* Retrieve the identifier for the current JavaScript runtime.
*
* @private
* @return {string} The runtime identifier.
*/
exports.getRuntime = function() {
return runtime;
};
/**
* Check whether Mozilla Rhino is running JSDoc.
* @return {boolean} Set to `true` if the current runtime is Mozilla Rhino.
@ -95,3 +70,76 @@ exports.isRhino = function() {
exports.isNode = function() {
return runtime === NODE;
};
function initializeRhino(args) {
// note: mutates args
function getDirname() {
var dirname;
// Rhino has no native way to get the base dirname of the current script,
// so this information must be manually passed in from the command line.
for (var i = 0, l = args.length; i < l; i++) {
if ( /^--dirname(?:=(.+?)(\/|\/\.)?)?$/i.test(args[i]) ) {
if (RegExp.$1) {
dirname = RegExp.$1; // last wins
args.splice(i--, 1); // remove --dirname opt from arguments
}
else {
dirname = args[i + 1];
args.splice(i--, 2);
}
}
}
return dirname;
}
env.dirname = getDirname();
env.args = args;
require(env.dirname + '/rhino/rhino-shim.js');
}
function initializeNode(args) {
env.dirname = require('path').dirname(process.argv[1]);
env.args = process.argv.slice(2);
}
exports.initialize = function(args) {
switch(runtime) {
case RHINO:
initializeRhino(args);
break;
case NODE:
initializeNode();
break;
default:
throw new Error('Unable to initialize the JavaScript runtime!');
}
};
/**
* Retrieve the identifier for the current JavaScript runtime.
*
* @private
* @return {string} The runtime identifier.
*/
exports.getRuntime = function() {
return runtime;
};
/**
* Get the require path for the runtime-specific implementation of a module.
*
* @param {string} partialPath - The partial path to the module. Use the same format as when calling
* `require()`.
* @return {object} The require path for the runtime-specific implementation of the module.
*/
exports.getModulePath = function(partialPath) {
var modulePath = [env.dirname, runtime, partialPath].join('/').replace(/ /g, '%20');
if (os.platform() === 'win32') {
modulePath = pathToUri(modulePath);
}
return modulePath;
};

59
node/fs.js Normal file
View File

@ -0,0 +1,59 @@
var fs = require('fs');
var path = require('path');
var stream = require('stream');
var wrench = require('wrench');
var toDir = exports.toDir = function(_path) {
var isDirectory;
try {
isDirectory = fs.statSync(_path).isDirectory();
}
catch(e) {
isDirectory = false;
}
if (isDirectory){
return _path;
} else {
return path.dirname(_path);
}
};
exports.mkPath = function(/**Array*/ _path) {
if ( Array.isArray(_path) ) {
_path = _path.join('');
}
wrench.mkdirSyncRecursive(_path);
};
// adapted from http://procbits.com/2011/11/15/synchronous-file-copy-in-node-js
exports.copyFileSync = function(inFile, outDir, fileName) {
var BUF_LENGTH = 64 * 1024;
var read;
var write;
var buffer = new Buffer(BUF_LENGTH);
var bytesRead = 1;
var outFile = path.join( outDir, fileName || path.basename(inFile) );
var pos = 0;
wrench.mkdirSyncRecursive(outDir);
read = fs.openSync(inFile, 'r');
write = fs.openSync(outFile, 'w');
while (bytesRead > 0) {
bytesRead = fs.readSync(read, buffer, 0, BUF_LENGTH, pos);
fs.writeSync(write, buffer, 0, bytesRead);
pos += bytesRead;
}
fs.closeSync(read);
return fs.closeSync(write);
};
Object.keys(fs).forEach(function(key) {
exports[key] = fs[key];
});

View File

@ -1,17 +0,0 @@
var e = ' is not implemented for Node.js!';
exports.ls = function() {
throw new Error('fs.ls' + e);
};
exports.toDir = function() {
throw new Error('fs.toDir' + e);
};
exports.mkPath = function() {
throw new Error('fs.mkpath' + e);
};
exports.copyFileSync = function() {
throw new Error('fs.copyFileSync' + e);
};

View File

@ -1,8 +0,0 @@
// TODO: not tested
module.exports = function(filepath) {
var fs = require('jsdoc/fs');
var vm = require('vm');
var script = fs.readFileSync(filepath, 'utf8');
vm.runInNewContext(script, global, filepath);
};

7
node/path.js Normal file
View File

@ -0,0 +1,7 @@
exports.pathToUri = function(_path) {
return _path;
};
exports.uriToPath = function(uri) {
return uri;
};

View File

@ -1,11 +1,16 @@
/*global describe: true, expect: true, it: true, jasmine: true */
/*global describe: true, env: true, expect: true, it: true, jasmine: true */
describe("commentConvert plugin", function() {
var parser = new (require("jsdoc/src/parser")).Parser(),
plugin = require('plugins/commentConvert'),
docSet;
var parser = new (require("jsdoc/src/parser")).Parser();
var path = require('jsdoc/path');
require('jsdoc/plugins').installPlugins(['plugins/commentConvert'], parser);
docSet = jasmine.getDocSetFromFile("plugins/commentConvert.js", parser);
var docSet;
var pluginPath = 'plugins/commentConvert';
var pluginPathResolved = path.join(env.dirname, pluginPath);
var plugin = require(pluginPathResolved);
require('jsdoc/plugins').installPlugins([pluginPathResolved], parser);
docSet = jasmine.getDocSetFromFile(pluginPath + '.js', parser);
it("should convert '///-style comments into jsdoc comments", function() {
var doclet = docSet.getByLongname("module:plugins/commentConvert.handlers.beforeParse");

View File

@ -1,11 +1,16 @@
/*global describe: true, expect: true, it: true, jasmine: true */
/*global describe: true, env: true, expect: true, it: true, jasmine: true */
describe("escapeHtml plugin", function() {
var parser = new (require("jsdoc/src/parser")).Parser(),
plugin = require('plugins/escapeHtml'),
docSet;
var parser = new (require('jsdoc/src/parser')).Parser();
var path = require('jsdoc/path');
require('jsdoc/plugins').installPlugins(['plugins/escapeHtml'], parser);
docSet = jasmine.getDocSetFromFile("plugins/escapeHtml.js", parser);
var docSet;
var pluginPath = 'plugins/escapeHtml';
var pluginPathResolved = path.join(env.dirname,pluginPath);
var plugin = require(pluginPathResolved);
require('jsdoc/plugins').installPlugins([pluginPathResolved], parser);
docSet = jasmine.getDocSetFromFile(pluginPath + '.js', parser);
it("should escape '&', '<' and newlines in doclet descriptions", function() {
var doclet = docSet.getByLongname("module:plugins/escapeHtml.handlers.newDoclet");

View File

@ -1,22 +1,29 @@
/*global describe: true, env: true, expect: true, it: true, jasmine: true */
var path = require('jsdoc/path');
describe("markdown plugin", function() {
//TODO
});
describe("markdown see tag support", function() {
var plugin = require('plugins/markdown'),
docSet = jasmine.getDocSetFromFile('plugins/test/fixtures/seetag-markdown.js'),
foo = docSet.getByLongname('foo')[0],
bar = docSet.getByLongname('bar')[0];
var pluginPath = 'plugins/markdown';
var pluginPathResolved = path.join(env.dirname, pluginPath);
var plugin = require(pluginPathResolved);
var docSet = jasmine.getDocSetFromFile('plugins/test/fixtures/seetag-markdown.js');
var foo = docSet.getByLongname('foo')[0];
var bar = docSet.getByLongname('bar')[0];
it ('should parse @see tags containing links', function() {
plugin.handlers.newDoclet({doclet:foo});
expect(typeof foo).toEqual('object');
expect(foo.see[0]).toEqual('<p><a href="http://nowhere.com">Nowhere</a></p>');
})
});
it ('should not parse @see tags that do not contain links', function() {
plugin.handlers.newDoclet({doclet:bar});
expect(typeof bar).toEqual('object');
expect(bar.see[0]).toEqual('AnObject#myProperty');
})
});
});
});

View File

@ -1,10 +1,15 @@
/*global describe: true, expect: true, it: true, jasmine: true, xit: true */
/*global describe: true, env: true, expect: true, it: true, jasmine: true, xit: true */
describe('plugins/overloadHelper', function() {
var parser = new (require('jsdoc/src/parser')).Parser();
var plugin = require('plugins/overloadHelper');
var path = require('jsdoc/path');
var docSet;
require('jsdoc/plugins').installPlugins(['plugins/overloadHelper'], parser);
var pluginPath = 'plugins/overloadHelper';
var pluginPathResolved = path.resolve(env.dirname, pluginPath);
var plugin = require(pluginPathResolved);
require('jsdoc/plugins').installPlugins([pluginPathResolved], parser);
docSet = jasmine.getDocSetFromFile('plugins/test/fixtures/overloadHelper.js', parser);
it('should exist', function() {

View File

@ -1,15 +1,17 @@
/*global describe: true, expect: true, it: true */
/*global describe: true, env: true, expect: true, it: true */
describe("railsTemplate plugin", function() {
var parser = new (require("jsdoc/src/parser")).Parser(),
plugin = require('plugins/railsTemplate');
var parser = new (require("jsdoc/src/parser")).Parser();
var path = require('jsdoc/path');
var pluginPath = path.join(env.dirname, 'plugins/railsTemplate');
var plugin = require(pluginPath);
require('jsdoc/plugins').installPlugins(['plugins/railsTemplate'], parser);
require('jsdoc/plugins').installPlugins([pluginPath], 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")]);
var docSet = parser.parse([path.join(env.dirname, "plugins/test/fixtures/railsTemplate.js.erb")]);
expect(docSet[2].description).toEqual("Remove rails tags from the source input (e.g. )");
});

View File

@ -1,11 +1,16 @@
/*global describe: true, expect: true, it: true, jasmine: true */
/*global describe: true, env: true, expect: true, it: true, jasmine: true */
describe("shout plugin", function() {
var parser = new (require("jsdoc/src/parser")).Parser(),
plugin = require('plugins/shout'),
docSet;
var parser = new (require('jsdoc/src/parser')).Parser();
var path = require('jsdoc/path');
require('jsdoc/plugins').installPlugins(['plugins/shout'], parser);
docSet = jasmine.getDocSetFromFile("plugins/shout.js", parser);
var docSet;
var pluginPath = 'plugins/shout';
var pluginPathResolved = path.join(env.dirname, pluginPath);
var plugin = require(pluginPathResolved);
require('jsdoc/plugins').installPlugins([pluginPathResolved], parser);
docSet = jasmine.getDocSetFromFile(pluginPath + '.js', parser);
it("should make the description uppercase", function() {
var doclet = docSet.getByLongname("module:plugins/shout.handlers.newDoclet");

View File

@ -1,11 +1,16 @@
/*global describe: true, expect: true, it: true, jasmine: true */
/*global describe: true, env: true, expect: true, it: true, jasmine: true */
describe("sourcetag plugin", function() {
var parser = new (require("jsdoc/src/parser")).Parser(),
plugin = require('plugins/sourcetag'),
docSet;
var parser = new (require('jsdoc/src/parser')).Parser();
var path = require('jsdoc/path');
require('jsdoc/plugins').installPlugins(['plugins/sourcetag'], parser);
docSet = jasmine.getDocSetFromFile("plugins/sourcetag.js", parser);
var docSet;
var pluginPath = 'plugins/sourcetag';
var pluginPathResolved = path.join(env.dirname, pluginPath);
var plugin = require(pluginPathResolved);
require('jsdoc/plugins').installPlugins([pluginPathResolved], parser);
docSet = jasmine.getDocSetFromFile(pluginPath + '.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");

View File

@ -1,15 +1,20 @@
/*global describe: true, expect: true, it: true, jasmine: true, xit: true */
/*global describe: true, env: true, expect: true, it: true, jasmine: true, xit: true */
/**
* @author Rob Taylor [manix84@gmail.com]
*/
var path = require('jsdoc/path');
describe("verbose output plugin", function () {
var parser = new (require("jsdoc/src/parser")).Parser(),
plugin = require('plugins/verboseOutput'),
docSet;
var parser = new (require('jsdoc/src/parser')).Parser();
var path = require('jsdoc/path');
var docSet;
var pluginPath = 'plugins/verboseOutput';
var plugin = require( path.resolve(env.dirname, pluginPath) );
//require('jsdoc/plugins').installPlugins(['plugins/verboseOutput'], parser);
docSet = jasmine.getDocSetFromFile("plugins/verboseOutput.js", parser);
docSet = jasmine.getDocSetFromFile(pluginPath + '.js', parser);
xit("should log file names to console", function() {
// TODO: this doesn't actually test the plugin...

View File

@ -96,8 +96,10 @@ var mkdirSync = exports.mkdirSync = function(_path) {
exports.mkdir = asyncify(mkdirSync);
// JSDoc extension to `fs` module
exports.mkPath = function(/**Array*/ _path) {
if (_path.constructor == Array) { _path = _path.join(''); }
exports.mkPath = function(_path) {
if ( Array.isArray(_path) ) {
_path = _path.join('');
}
(new java.io.File(_path)).mkdirs();
};

Binary file not shown.

View File

@ -26,6 +26,16 @@ var asyncify = exports._asyncify = function(func) {
};
};
// JSDoc extension to `path` module
exports.pathToUri = function(_path) {
return String( new java.io.File(_path).toURI() );
};
// JSDoc extension to `path` module
exports.uriToPath = function(uri) {
return String( new java.io.File(new java.net.URI(uri)) );
};
/**
* 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'

View File

@ -4,6 +4,8 @@
* to get JSDoc to run.
*/
var myGlobal = require('jsdoc/util/global');
// Set the JS version that the Rhino interpreter will use.
version(180);
@ -12,10 +14,10 @@ version(180);
* @see https://developer.mozilla.org/en-US/docs/DOM/window#Methods
*/
setTimeout = null,
clearTimeout = null,
setInterval = null,
clearInterval = null;
myGlobal.setTimeout = null;
myGlobal.clearTimeout = null;
myGlobal.setInterval = null;
myGlobal.clearInterval = null;
(function() {
// TODO: tune number of threads if necessary
@ -30,35 +32,35 @@ clearInterval = null;
});
}
setTimeout = function(fn, delay) {
myGlobal.setTimeout = function(fn, delay) {
var timerId = timerCount++;
var callback = getCallback(fn);
timers[timerId] = timerPool.schedule(callback, delay, timerUnits);
return timerId;
};
clearTimeout = function(timerId) {
myGlobal.clearTimeout = function(timerId) {
if (timers[timerId]) {
timerPool.remove(timers[timerId]);
delete timers[timerId];
}
};
setInterval = function(fn, delay) {
myGlobal.setInterval = function(fn, delay) {
var timerId = timerCount++;
var callback = getCallback(fn);
timers[timerId] = timerPool.scheduleAtFixedRate(callback, delay, delay, timerUnits);
return timerId;
};
clearInterval = clearTimeout;
myGlobal.clearInterval = clearTimeout;
})();
/**
* Emulate Node.js console functions.
* @see http://nodejs.org/api/stdio.html
*/
console = (function() {
myGlobal.console = (function() {
function println(stream, args) {
java.lang.System[stream].println( require('util').format.apply(this, args) );
}
@ -88,10 +90,14 @@ console = (function() {
* Emulate Node.js process functions.
* @see http://nodejs.org/api/process.html
*/
process = {
argv: [__dirname + '/jsdoc.js'].concat(Array.prototype.slice.call(arguments, 0)),
myGlobal.process = {
// not quite right, but close enough
argv: ['java', env.dirname + '/jsdoc.js']
.concat( Array.prototype.slice.call(arguments, 0) ),
// this depends on a hack in our version of Rhino
cwd: function() {
return new Packages.java.io.File('.').getCanonicalPath() + '';
var f = new java.io.File( java.lang.System.getProperty('user.dir') );
return String( f.getAbsolutePath() );
},
env: (function() {
var result = {};
@ -124,3 +130,16 @@ process = {
}
}
};
/**
* Emulate other Node.js globals.
* @see http://nodejs.org/docs/latest/api/globals.html
*/
Object.defineProperties(myGlobal, {
'__dirname': {
get: function() {
return process.cwd();
},
enumerable: true
}
});

View File

@ -99,7 +99,7 @@ function shortenPaths(files, commonPrefix) {
}
function resolveSourcePath(filepath) {
return path.resolve(process.cwd(), filepath);
return path.resolve(env.dirname, filepath);
}
function getPathFromDoclet(doclet) {

View File

@ -1,3 +0,0 @@
// Used to test jsdoc/util/include
var myGlobal = require('jsdoc/util/global');
myGlobal.__globalForIncludeTest__++;

View File

@ -1,26 +1,16 @@
/*global env: true, expect: true, runs: true, waits: true */
/*jshint evil: true */
var fs = require('jsdoc/fs');
var path = require('path');
var path = require('jsdoc/path');
var util = require('util');
var hasOwnProp = Object.prototype.hasOwnProperty;
var myGlobal = require('jsdoc/util/global');
var jasmineAll = myGlobal.jasmineAll = require('test/lib/jasmine');
var jasmine = myGlobal.jasmine = jasmineAll.jasmine;
var jasmineAll = require('./lib/jasmine');
var jasmine = jasmineAll.jasmine;
// due to scoping issues, requiring this file doesn't work
eval( fs.readFileSync(__dirname + '/test/async-callback.js', 'utf8') );
var jasmineNode = require('test/reporter').jasmineNode;
// set up jasmine's global functions
['spyOn', 'it', 'xit', 'expect', 'runs', 'waitsFor', 'beforeEach', 'afterEach', 'describe',
'xdescribe'].forEach(function(item) {
myGlobal[item] = jasmineAll[item];
});
var jasmineNode = ( require('./reporter') )(jasmine);
var reporter = null;
jasmine.initialize = function(done, verbose) {
@ -75,8 +65,8 @@ jasmine.executeSpecsInFolder = function(folder, done, opts) {
for (var i = 0, len = specsList.length; i < len; ++i) {
filename = specsList[i];
require(filename.path().replace(/\\/g, '/').
replace(new RegExp('^' + __dirname + '/'), "").
replace(/\.\w+$/, ""));
replace(new RegExp('^' + env.dirname + '/test'), './').
replace(/\.\w+$/, ''));
}
// Run Jasmine
@ -110,11 +100,11 @@ jasmine.asyncSpecDone = function() {
};
jasmine.getDocSetFromFile = function(filename, parser) {
var sourceCode = fs.readFileSync(__dirname + '/' + filename, 'utf8');
var sourceCode = fs.readFileSync( path.join(env.dirname, filename), 'utf8' );
var runtime = require('jsdoc/util/runtime');
// TODO: change to runtime-appropriate parser (and/or get a config setting?)
//var testParser = parser || require('jsdoc/src/parser').createParser('esprima');
var testParser = parser || require('jsdoc/src/parser').createParser('rhino');
var testParser = parser || require('jsdoc/src/parser').createParser('esprima');
//var testParser = parser || require('jsdoc/src/parser').createParser('rhino');
var indexAll = require('jsdoc/borrow').indexAll;
var doclets;
@ -138,8 +128,13 @@ jasmine.getDocSetFromFile = function(filename, parser) {
};
};
for (var key in jasmine) {
if ( hasOwnProp.call(jasmine, key) ) {
exports[key] = jasmine[key];
}
}
// set up jasmine's global functions
Object.keys(jasmine).forEach(function(key) {
exports[key] = myGlobal[key] = jasmine[key];
});
myGlobal.jasmine = jasmine;
require('./async-callback');
['spyOn', 'it', 'xit', 'expect', 'runs', 'waitsFor', 'beforeEach', 'afterEach', 'describe',
'xdescribe'].forEach(function(item) {
myGlobal[item] = jasmineAll[item];
});

View File

@ -1,11 +1,5 @@
(function() {
//
// Imports
//
if (!jasmineNode) {
var jasmineNode = {};
}
module.exports = function(jasmine) {
var jasmineNode = {};
//
// Helpers
@ -106,9 +100,9 @@
var specs = runner.specs();
var specCount = specs.length;
var message = "\n\nFinished in "
+ ((new Date().getTime() - this.startedAt.getTime()) / 1000)
+ " seconds";
var message = "\n\nFinished in " +
((new Date().getTime() - this.startedAt.getTime()) / 1000) +
" seconds";
this.printLine_(message);
// This is what jasmine-html.js has
@ -127,7 +121,7 @@
return;
}
var indent = ' ', failure;
var indent = ' ', failure, failures;
this.printLine_('\n');
this.print_('Failures:');
@ -292,8 +286,5 @@
// Inherit from TerminalReporter
jasmineNode.TerminalVerboseReporter.prototype.__proto__ = jasmineNode.TerminalReporter.prototype;
//
// Exports
//
exports.jasmineNode = jasmineNode;
})();
return jasmineNode;
};

View File

@ -1,4 +1,4 @@
/*global env: true */
/*global env: true, jasmine: true */
/*
* Test Steps:
* 1. Get Jasmine
@ -7,19 +7,13 @@
* 4. Run Jasmine on each directory
*/
var fs = require('jsdoc/fs');
var jasmine = require('test/jasmine-jsdoc');
var myGlobal = require('jsdoc/util/global');
var path = require('path');
fs.existsSync = fs.existsSync || path.existsSync;
var hasOwnProp = Object.prototype.hasOwnProperty;
for (var key in jasmine) {
if (hasOwnProp.call(jasmine, key)) {
this[key] = jasmine[key];
}
}
var opts = {
verbose: env.opts.verbose || false,
showColors: env.opts.nocolor === true ? false : true
@ -32,18 +26,30 @@ if (match instanceof Array) {
}
opts.matcher = new RegExp("(" + match + ")\\.(" + extensions + ")$", 'i');
var specFolders = ['test/specs', 'plugins/test/specs'];
var specFolders = [
path.join(env.dirname, 'test/specs'),
path.join(env.dirname, 'plugins/test/specs')
];
var failedCount = 0;
var index = 0;
var testsCompleteCallback;
var onComplete;
function runNextFolder() {
var runNextFolder = module.exports = function(callback) {
require( path.join(env.dirname, 'test/jasmine-jsdoc') );
testsCompleteCallback = testsCompleteCallback || callback;
if (index < specFolders.length) {
jasmine.executeSpecsInFolder(specFolders[index], onComplete, opts);
}
}
else {
process.nextTick(function() {
testsCompleteCallback(failedCount);
});
}
};
onComplete = function(runner, log) {
if (runner.results().failedCount !== 0) {
@ -52,6 +58,3 @@ onComplete = function(runner, log) {
index++;
runNextFolder();
};
runNextFolder();
process.exit(failedCount);

View File

@ -1,7 +1,9 @@
/*global env: true */
var wrench = require('wrench');
var path = require('path');
var fs = require('jsdoc/fs');
var path = require('jsdoc/path');
var runtime = require('jsdoc/util/runtime');
var wrench = require('wrench');
var specs = [];
var createSpecObj = function(_path, root) {
@ -30,6 +32,17 @@ var clearSpecs = exports.clearSpecs = function() {
specs.splice(0, specs.length);
};
function shouldLoad(file, matcher) {
var skipPath = runtime.isRhino() ? runtime.NODE : runtime.RHINO;
try {
return fs.statSync(file).isFile() && matcher.test( path.basename(file) ) &&
file.indexOf(skipPath) === -1;
}
catch(e) {
return false;
}
}
exports.load = function(loadpath, matcher, clear) {
if (clear === true) {
clearSpecs();
@ -37,15 +50,9 @@ exports.load = function(loadpath, matcher, clear) {
var wannaBeSpecs = wrench.readdirSyncRecursive(loadpath);
for (var i = 0; i < wannaBeSpecs.length; i++) {
var file = path.join(__dirname, loadpath, wannaBeSpecs[i]);
try {
if (fs.statSync(file).isFile()) {
if (matcher.test(path.basename(file))) {
specs.push(createSpecObj(file));
}
}
} catch(e) {
// nothing to do here
var file = path.join(loadpath, wannaBeSpecs[i]);
if ( shouldLoad(file, matcher) ) {
specs.push( createSpecObj(file) );
}
}
};

View File

@ -4,12 +4,12 @@ describe("module names", function() {
var doclets;
var parser = require( runtime.getModulePath('jsdoc/src/parser') );
var parser = require('jsdoc/src/parser');
var srcParser = null;
var sourcePaths = env.opts._.slice(0);
beforeEach(function() {
env.opts._ = [__dirname + '/test/fixtures/modules/data/'];
env.opts._ = [env.dirname + '/test/fixtures/modules/data/'];
srcParser = new parser.Parser();
require('jsdoc/src/handlers').attachTo(srcParser);
});
@ -19,13 +19,13 @@ describe("module names", function() {
});
it("should create a name from the file path when no documented module name exists", function() {
doclets = srcParser.parse(__dirname + '/test/fixtures/modules/data/mod-1.js');
doclets = srcParser.parse(env.dirname + '/test/fixtures/modules/data/mod-1.js');
expect(doclets.length).toBeGreaterThan(1);
expect(doclets[0].longname).toEqual('module:data/mod-1');
});
it("should use the documented module name if available", function() {
doclets = srcParser.parse(__dirname + '/test/fixtures/modules/data/mod-2.js');
doclets = srcParser.parse(env.dirname + '/test/fixtures/modules/data/mod-2.js');
expect(doclets.length).toBeGreaterThan(1);
expect(doclets[0].longname).toEqual('module:my/module/name');
});

View File

@ -1,4 +1,4 @@
/*global describe: true, expect: true, it: true */
/*global describe: true, env: true, expect: true, it: true */
describe("jsdoc/src/filter", function() {
var filter = new (require('jsdoc/src/filter').Filter)({
includePattern: new RegExp(".+\\.js(doc)?$"),
@ -6,7 +6,7 @@ describe("jsdoc/src/filter", function() {
exclude: ['.ignore', 'scratch/conf.js']
});
var files = ['yes.js', '/yes.jsdoc', '/_nope.js', '.ignore', process.cwd() + '/scratch/conf.js'];
var files = ['yes.js', '/yes.jsdoc', '/_nope.js', '.ignore', env.dirname + '/scratch/conf.js'];
files = files.filter(function($) {
return filter.isIncluded($);

View File

@ -1,7 +1,7 @@
/*global describe: true, expect: true, it: true */
describe("jsdoc/src/handlers", function() {
var runtime = require('jsdoc/util/runtime');
var parser = require( runtime.getModulePath('jsdoc/src/parser') );
var parser = require('jsdoc/src/parser');
var testParser = new parser.Parser();
var handlers = require('jsdoc/src/handlers');

View File

@ -1,5 +1,5 @@
/*global beforeEach: true, describe: true, expect: true, it: true, jasmine: true, spyOn: true,
xit: true */
/*global beforeEach: true, describe: true, env: true, expect: true, it: true, jasmine: true,
spyOn: true, xit: true */
describe("jsdoc/src/parser", function() {
var jsdoc = { src: { parser: require('jsdoc/src/parser') } };
@ -225,8 +225,8 @@ describe("jsdoc/src/parser", function() {
it("should be able to parse its own source file", function() {
var fs = require('jsdoc/fs'),
path = require('path'),
parserSrc = 'javascript:' + fs.readFileSync( path.join(__dirname,
'lib', 'jsdoc', 'src', 'parser.js'), 'utf8' ),
parserSrc = 'javascript:' + fs.readFileSync( path.join(env.dirname,
'lib/jsdoc/src/parser.js'), 'utf8' ),
parse = function() {
parser.parse(parserSrc);
};

View File

@ -6,10 +6,10 @@ describe("jsdoc/src/scanner", function() {
excludePattern: new RegExp("(^|\\/|\\\\)_")
}),
path = require('path'),
sourceFiles = scanner.scan([path.join(__dirname, 'test', 'fixtures', 'src')], 3, filter);
sourceFiles = scanner.scan([path.join(env.dirname, 'test', 'fixtures', 'src')], 3, filter);
sourceFiles = sourceFiles.map(function($) {
return path.relative(__dirname, $);
return path.relative(env.dirname, $);
});
it("should return the correct source files", function() {

View File

@ -1,11 +1,10 @@
/*global afterEach: true, describe: true, env: true, expect: true, it: true */
/*global afterEach: true, beforeEach: true, describe: true, env: true, expect: true, it: true,
spyOn: true */
describe("jsdoc/tutorial/resolver", function() {
var resolver = require('jsdoc/tutorial/resolver'),
tutorial = require('jsdoc/tutorial'),
lenient = !!env.opts.lenient,
log = eval(console.log);
var resolver = require('jsdoc/tutorial/resolver');
var tutorial = require('jsdoc/tutorial');
var lenient = !!env.opts.lenient;
/*jshint evil: true */
it("should exist", function() {
expect(resolver).toBeDefined();
expect(typeof resolver).toBe('object');
@ -69,7 +68,7 @@ describe("jsdoc/tutorial/resolver", function() {
});
// load
resolver.load(__dirname + "/test/tutorials/tutorials");
resolver.load(env.dirname + "/test/tutorials/tutorials");
var childNames = resolver.root.children.map(function (t) { return t.name; }),
test = resolver.root.getByName('test'),
test2 = resolver.root.getByName('test2'),
@ -174,7 +173,7 @@ describe("jsdoc/tutorial/resolver", function() {
describe("Error reporting", function() {
// Tests for error reporting.
function missingTutorial() {
resolver.load(__dirname + "/test/tutorials/incomplete");
resolver.load(env.dirname + "/test/tutorials/incomplete");
resolver.resolve();
}
function duplicateNamedTutorials() {
@ -183,13 +182,16 @@ describe("jsdoc/tutorial/resolver", function() {
}
function duplicateDefinedTutorials() {
// can't have a tutorial's metadata defined twice in .json files
resolver.load(__dirname + "/test/tutorials/duplicateDefined");
resolver.load(env.dirname + "/test/tutorials/duplicateDefined");
resolver.resolve();
}
beforeEach(function() {
spyOn(console, 'log');
});
afterEach(function() {
env.opts.lenient = lenient;
console.log = log;
});
it("throws an exception for missing tutorials if the lenient option is not enabled", function() {
@ -199,7 +201,6 @@ describe("jsdoc/tutorial/resolver", function() {
});
it("doesn't throw an exception for missing tutorials if the lenient option is enabled", function() {
console.log = function() {};
env.opts.lenient = true;
expect(missingTutorial).not.toThrow();
@ -211,7 +212,6 @@ describe("jsdoc/tutorial/resolver", function() {
});
it("doesn't throw an exception for duplicate-named tutorials (e.g. test.md, test.html) if the lenient option is not enabled", function() {
console.log = function() {};
env.opts.lenient = true;
expect(duplicateNamedTutorials).not.toThrow();
});
@ -222,7 +222,6 @@ describe("jsdoc/tutorial/resolver", function() {
});
it("doesn't throw an exception for tutorials defined twice in .jsons if the lenient option is not enabled", function() {
console.log = function() {};
env.opts.lenient = true;
expect(duplicateDefinedTutorials).not.toThrow();
});

View File

@ -1,5 +1,5 @@
/*global describe: true, expect: true, it: true */
describe("common/dumper", function() {
describe("jsdoc/util/dumper", function() {
var common = {dumper: require('jsdoc/util/dumper')};
it("should exist", function() {

View File

@ -1,36 +0,0 @@
/*global afterEach: true, beforeEach: true, describe: true, env: true, expect: true, it: true,
__globalForIncludeTest__: true */
describe("jsdoc/util/include", function() {
var include = require('jsdoc/util/include');
var myGlobal = require('jsdoc/util/global');
var path = require('path');
var fixturePath = 'test/fixtures/include.js';
beforeEach(function() {
myGlobal.__globalForIncludeTest__ = 0;
});
afterEach(function() {
myGlobal.__globalForIncludeTest__ = undefined;
});
it("should exist", function() {
expect(include).toBeDefined();
expect(typeof include).toEqual('function');
});
it("should work with a path relative to __dirname", function() {
include(fixturePath);
expect(__globalForIncludeTest__).toEqual(1);
});
// Note: This test also verifies that include() executes the file each time it's passed in,
// rather than executing it once and caching the result, as with require().
it("should work with an absolute path", function() {
var _path = path.resolve(__dirname, fixturePath);
include(_path);
expect(__globalForIncludeTest__).toEqual(1);
});
});

View File

@ -136,7 +136,7 @@ describe("jsdoc/util/templateHelper", function() {
// bit of a dodgy test but the best I can manage. setTutorials doesn't do much.
helper.setTutorials(null);
// should throw error: no 'getByName' in tutorials.
expect(function () { return helper.tutorialToUrl('asdf'); }).toThrow('Cannot call method "getByName" of null');
expect(function () { return helper.tutorialToUrl('asdf'); }).toThrow();
});
it("setting tutorials to the root tutorial object lets lookups work", function() {
@ -955,7 +955,7 @@ describe("jsdoc/util/templateHelper", function() {
env.opts.lenient = true;
// load the tutorials we already have for the tutorials tests
resolver.load(__dirname + "/test/tutorials/tutorials");
resolver.load(env.dirname + "/test/tutorials/tutorials");
resolver.resolve();
var url = helper.tutorialToUrl('test');
@ -1043,7 +1043,7 @@ describe("jsdoc/util/templateHelper", function() {
spyOn(console, 'log');
// load the tutorials we already have for the tutorials tests
resolver.load(__dirname + "/test/tutorials/tutorials");
resolver.load(env.dirname + "/test/tutorials/tutorials");
resolver.resolve();

View File

@ -1,9 +1,9 @@
/*global app: true, beforeEach: true, describe: true, env: true, expect: true, it: true */
var async = require('async'),
fs = require('jsdoc/fs'),
path = require('path');
var async = require('async');
var fs = require('jsdoc/fs');
var path = require('jsdoc/path');
var config = JSON.parse( fs.readFileSync( path.join(__dirname, '.jshintrc'), 'utf8' ) );
var config = JSON.parse( fs.readFileSync( path.join(env.dirname, '.jshintrc'), 'utf8' ) );
function jsHintCheck(filename, callback) {
var JSHINT = require('jshint').JSHINT;
@ -25,7 +25,7 @@ function jsHintCheck(filename, callback) {
describe('jshint-clean', function() {
it('should generate JSHint errors for bad code', function(done) {
var file = path.join(__dirname, 'test', 'fixtures', 'jshint', 'badfile.js');
var file = path.join(env.dirname, 'test', 'fixtures', 'jshint', 'badfile.js');
jsHintCheck(file, function(err, jsHintErrors) {
expect(err).toBeFalsy();
@ -35,7 +35,7 @@ describe('jshint-clean', function() {
});
it('should not generate JSHint errors for good code', function(done) {
var file = path.join(__dirname, 'test', 'fixtures', 'jshint', 'goodfile.js');
var file = path.join(env.dirname, 'test', 'fixtures', 'jshint', 'goodfile.js');
jsHintCheck(file, function(err, jsHintErrors) {
expect(err).toBeFalsy();
@ -57,7 +57,7 @@ describe('jshint-clean', function() {
};
filter = new (require('jsdoc/src/filter').Filter)(source);
files = app.jsdoc.scanner.scan([__dirname], 10, filter);
files = app.jsdoc.scanner.scan([env.dirname], 10, filter);
async.forEach(files, function(file, cb) {
jsHintCheck(file, function(err, jsHintErrors) {

View File

@ -6,12 +6,11 @@ describe("@overview tag", function() {
var doclets;
var parser = require( runtime.getModulePath('jsdoc/src/parser') );
var srcParser = null;
var sourcePaths = env.opts._.slice(0);
beforeEach(function() {
env.opts._ = [__dirname + '/test/fixtures/'];
env.opts._ = [env.dirname + '/test/fixtures/'];
srcParser = new parser.Parser();
require('jsdoc/src/handlers').attachTo(srcParser);
});
@ -21,12 +20,12 @@ describe("@overview tag", function() {
});
it('When a file overview tag appears in a doclet, the name of the doclet should contain the path to the file.', function() {
doclets = srcParser.parse(__dirname + '/test/fixtures/file.js');
doclets = srcParser.parse(env.dirname + '/test/fixtures/file.js');
expect(doclets[0].name).toMatch(/^(fixtures[\/\\]file\.js)$/);
});
it("The name and longname should be equal", function() {
doclets = srcParser.parse(__dirname + '/test/fixtures/file.js');
doclets = srcParser.parse(env.dirname + '/test/fixtures/file.js');
expect(doclets[0].name).toBe(doclets[0].longname);
});
});