mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
Start of deep refactor.
This commit is contained in:
parent
bc6f1a9fa3
commit
7b55f59263
83
LICENSE.md
83
LICENSE.md
@ -1,7 +1,7 @@
|
||||
License
|
||||
=======
|
||||
|
||||
JSDoc 3 is free software.
|
||||
JSDoc is free software.
|
||||
|
||||
Copyright (c) 2010 Michael Mathews <micmath@gmail.com>
|
||||
|
||||
@ -35,16 +35,7 @@ https://developer.mozilla.org/en/Rhino_License
|
||||
You can obtain the source code for Rhino from the Mozilla web site at
|
||||
http://www.mozilla.org/rhino/download.html
|
||||
|
||||
|
||||
jsDump
|
||||
------
|
||||
|
||||
jsDump is copyright (c) 2008 Ariel Flesler, aflesler(at)gmail(dot)com
|
||||
|
||||
Licensed under the BSD license
|
||||
http://www.opensource.org/licenses/bsd-license.php
|
||||
|
||||
json2xml
|
||||
json2xml (modules/goessner/json2xml)
|
||||
--------
|
||||
|
||||
json2xml is copyright (c) Stefan Goessner 2006
|
||||
@ -55,35 +46,31 @@ http://creativecommons.org/licenses/LGPL/2.1/
|
||||
http://goessner.net/
|
||||
http://goessner.net/download/prj/jsonxml/
|
||||
|
||||
JSpec
|
||||
Node (modules/common/assert, modules/common/util)
|
||||
-------
|
||||
|
||||
JSpec is copyright (c) 2008 - 2010 TJ Holowaychuk tj@vision-media.ca
|
||||
Node is Copyright 2009, 2010 Ryan Lienhart Dahl. All rights reserved.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
http://github.com/visionmedia/jspec
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
Licensed under the MIT license.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
https://github.com/ry/node
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
JSONSchema Validator
|
||||
JSONSchema Validator (modules/sitepen/jsonschema)
|
||||
--------------------
|
||||
|
||||
JSONSchema is copyright (c) 2007 Kris Zyp SitePen (www.sitepen.com)
|
||||
@ -93,12 +80,30 @@ http://www.sitepen.com/blog/2010/03/02/commonjs-utilities/
|
||||
|
||||
Licensed under the MIT license.
|
||||
|
||||
Simple JavaScript Templating
|
||||
Mustache (templates/lib/janl/mustache.js)
|
||||
-------------------
|
||||
|
||||
Simple JavaScript Templating is
|
||||
Copyright (c) John Resig - http://ejohn.org/
|
||||
Mustache is
|
||||
Copyright (c) 2009 Chris Wanstrath (Ruby)
|
||||
Copyright (c) 2010 Jan Lehnardt (JavaScript)
|
||||
|
||||
Licensed under the MIT license.
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
http://ejohn.org/blog/javascript-micro-templating/
|
||||
https://github.com/janl/mustache.js
|
||||
185
main.js
185
main.js
@ -1,97 +1,156 @@
|
||||
/**
|
||||
* @overview JSDoc 3
|
||||
* @project JSDoc
|
||||
* @copyright 2010 (c) Michael Mathews <micmath@gmail.com>
|
||||
* @license See LICENSE.md file included in this distribution.
|
||||
*/
|
||||
|
||||
//// bootstrap
|
||||
|
||||
/** @global */
|
||||
const BASEDIR = arguments[0].replace(/([\/\\])main\.js$/, '$1'); // jsdoc.jar sets argument[0] to the abspath to main.js
|
||||
var args = arguments.slice(1);
|
||||
|
||||
/** Follow the commonjs modules convention. */
|
||||
function require(id) {
|
||||
/** @global */
|
||||
function require(id) { // like commonjs
|
||||
var path = require.base + id + '.js',
|
||||
source = '';
|
||||
fileContent = '';
|
||||
|
||||
try {
|
||||
var file = new java.io.File(path),
|
||||
scanner = new java.util.Scanner(file).useDelimiter("\\Z"),
|
||||
source = String( scanner.next() );
|
||||
fileContent = String( scanner.next() );
|
||||
}
|
||||
catch(e) {
|
||||
print(e);
|
||||
}
|
||||
catch(e) { print(e); }
|
||||
|
||||
try {
|
||||
var f = new Function('require', 'exports', 'module', source),
|
||||
var f = new Function('require', 'exports', 'module', fileContent),
|
||||
exports = require.cache[path] || {},
|
||||
module = { id: id, uri: path };
|
||||
|
||||
require.cache[path] = exports;
|
||||
require.cache[id] = exports;
|
||||
f.call({}, require, exports, module);
|
||||
}
|
||||
catch(e) {
|
||||
print('Unable to require source code from '+source+': '+e);
|
||||
print('Unable to require source code from "' + path + '": ' + e);
|
||||
}
|
||||
return exports;
|
||||
}
|
||||
require.base = BASEDIR + '/modules/';
|
||||
require.cache = {};
|
||||
require.base = BASEDIR + '/modules/'; // assume all module paths are relative to here
|
||||
require.cache = {}; // cache module exports. Like: {id: exported}
|
||||
|
||||
function print(msg) {
|
||||
java.lang.System.out.println(msg);
|
||||
}
|
||||
////
|
||||
|
||||
//// main
|
||||
var app = { }; // global settings for this app
|
||||
(function() {
|
||||
var jsdoc = {
|
||||
parser: require('jsdoc/parser'),
|
||||
opts: require('jsdoc/opts'),
|
||||
src: require('jsdoc/src')
|
||||
},
|
||||
opts,
|
||||
sourceFiles;
|
||||
|
||||
app.opts = opts = jsdoc.opts.set(args);
|
||||
|
||||
if (opts.help) {
|
||||
print( jsdoc.opts.help() );
|
||||
java.lang.System.exit(0);
|
||||
}
|
||||
else if (opts.test) {
|
||||
load(BASEDIR+'/test/lib/jspec.js');
|
||||
load(BASEDIR + '/test/runall.js');
|
||||
java.lang.System.exit(0);
|
||||
}
|
||||
|
||||
if (opts._.length > 0) {
|
||||
sourceFiles = jsdoc.src.getFilePaths(opts._, (opts.recurse? 10 : undefined));
|
||||
|
||||
/** @global */
|
||||
env = {
|
||||
run: {
|
||||
start: new Date(),
|
||||
finish: null
|
||||
},
|
||||
args: arguments.slice(1), // jsdoc.jar sets argument[0] to the abspath to main.js, user args follow
|
||||
conf: {}, // TODO: populate from file BASEDIR+'/conf.json'
|
||||
opts: {}
|
||||
};
|
||||
|
||||
jsdoc.parser.parseFiles(sourceFiles, opts.encoding);
|
||||
|
||||
if (opts.validate) {
|
||||
var jsonSchema = require('sitepen/jsonSchema');
|
||||
var jsdocSchema = require('jsdoc/schema').jsdocSchema;
|
||||
var validation = jsonSchema.validate(jsdoc.parser.result.toObject(), jsdocSchema);
|
||||
print('Validation: ' + validation.toSource());
|
||||
}
|
||||
|
||||
if (!opts.destination || opts.destination.indexOf('stdout') === 0) {
|
||||
print( jsdoc.parser.result.toString(opts.destination) );
|
||||
}
|
||||
else if (opts.template) {
|
||||
try {
|
||||
load(BASEDIR+'/templates/'+opts.template+'/publish.js');
|
||||
}
|
||||
catch (e) {
|
||||
print('Cannot load the specified template: templates/'+opts.template+'/publish.js: '+e);
|
||||
}
|
||||
|
||||
publish(jsdoc.parser.result.toObject(), {});
|
||||
}
|
||||
try { main(); }
|
||||
finally { env.run.finish = new Date(); }
|
||||
|
||||
/** @global */
|
||||
function print(/*...*/) {
|
||||
for (var i = 0, leni = arguments.length; i < leni; i++) {
|
||||
java.lang.System.out.println('' + arguments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** @global */
|
||||
function dump(/*...*/) {
|
||||
for (var i = 0, leni = arguments.length; i < leni; i++) {
|
||||
print( require('common/dumper').dump(arguments[i]) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** @global */
|
||||
function include(filepath) {
|
||||
try {
|
||||
load(BASEDIR + filepath);
|
||||
}
|
||||
catch (e) {
|
||||
print('Cannot include "' + BASEDIR + filepath + '": '+e);
|
||||
}
|
||||
}
|
||||
|
||||
/** @global */
|
||||
function exit(v) {
|
||||
java.lang.System.exit(v);
|
||||
}
|
||||
|
||||
function main() {
|
||||
var sourceFiles,
|
||||
docs,
|
||||
jsdoc = {
|
||||
opts: {
|
||||
parser: require('jsdoc/opts/parser')
|
||||
},
|
||||
src: {
|
||||
scanner: require('jsdoc/src/scanner'),
|
||||
parser: require('jsdoc/src/parser')
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
env.conf = JSON.parse( require('common/fs').read(BASEDIR+'conf.json') );
|
||||
}
|
||||
catch (e) {
|
||||
throw('Configuration file cannot be evaluated. '+e);
|
||||
}
|
||||
|
||||
env.opts = jsdoc.opts.parser.parse(env.args);
|
||||
|
||||
|
||||
})();
|
||||
if (env.opts.help) {
|
||||
print( jsdoc.optParser.help() );
|
||||
exit(0);
|
||||
}
|
||||
else if (env.opts.test) {
|
||||
include('test/runall.js');
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (env.opts._.length > 0) { // are there any source files to scan?
|
||||
sourceFiles = jsdoc.src.scanner.scan(env.opts._, (env.opts.recurse? 10 : undefined));
|
||||
//dump('sourceFiles...', sourceFiles);
|
||||
docs = jsdoc.src.parser.parse(sourceFiles, env.opts.encoding);
|
||||
//dump('jsdoc.docs...', docs);
|
||||
if (env.opts.template) {
|
||||
include('templates/'+env.opts.template+'/publish.js');
|
||||
if (typeof publish === 'function') {
|
||||
publish(docs, {});
|
||||
}
|
||||
}
|
||||
//
|
||||
// if (env.opts.validate) {
|
||||
// var jsonSchema = require('sitepen/jsonSchema');
|
||||
// var jsdocSchema = require('jsdoc/schema').jsdocSchema;
|
||||
// var validation = jsonSchema.validate(jsdoc.srcParser.result.toObject(), jsdocSchema);
|
||||
// print('Validation: ' + validation.toSource());
|
||||
// }
|
||||
//
|
||||
// if (!env.opts.destination || env.opts.destination.indexOf('stdout') === 0) {
|
||||
// print( jsdoc.srcParser.result.toString(env.opts.destination) );
|
||||
// }
|
||||
// else if (env.opts.template) {
|
||||
// try {
|
||||
// load(BASEDIR+'/templates/'+env.opts.template+'/publish.js');
|
||||
// }
|
||||
// catch (e) {
|
||||
// print('Cannot load the specified template: templates/'+env.opts.template+'/publish.js: '+e);
|
||||
// }
|
||||
//
|
||||
// publish(jsdoc.srcParser.result.toObject(), {});
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
////
|
||||
@ -1,11 +1,7 @@
|
||||
/**
|
||||
@overview Parse command line options.
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
|
||||
/**
|
||||
@module common/args
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
(function() {
|
||||
|
||||
|
||||
302
modules/common/assert.js
Normal file
302
modules/common/assert.js
Normal file
@ -0,0 +1,302 @@
|
||||
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
|
||||
//
|
||||
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
|
||||
//
|
||||
// Originally from narwhal.js (http://narwhaljs.org)
|
||||
// Copyright (c) 2009 Thomas Robinson <280north.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the 'Software'), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// UTILITY
|
||||
var common = { util: require('common/util') };;
|
||||
var pSlice = Array.prototype.slice;
|
||||
|
||||
// 1. The assert module provides functions that throw
|
||||
// AssertionError's when particular conditions are not met. The
|
||||
// assert module must conform to the following interface.
|
||||
|
||||
var assert = exports;
|
||||
|
||||
// 2. The AssertionError is defined in assert.
|
||||
// new assert.AssertionError({ message: message,
|
||||
// actual: actual,
|
||||
// expected: expected })
|
||||
|
||||
assert.AssertionError = function AssertionError(options) {
|
||||
this.name = 'AssertionError';
|
||||
this.message = options.message;
|
||||
this.actual = options.actual;
|
||||
this.expected = options.expected;
|
||||
this.operator = options.operator;
|
||||
var stackStartFunction = options.stackStartFunction || fail;
|
||||
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, stackStartFunction);
|
||||
}
|
||||
};
|
||||
common.util.inherits(assert.AssertionError, Error);
|
||||
|
||||
assert.AssertionError.prototype.toString = function() {
|
||||
if (this.message) {
|
||||
return [this.name + ':', this.message].join(' ');
|
||||
} else {
|
||||
return [this.name + ':',
|
||||
JSON.stringify(this.expected),
|
||||
this.operator,
|
||||
JSON.stringify(this.actual)].join(' ');
|
||||
}
|
||||
};
|
||||
|
||||
// assert.AssertionError instanceof Error
|
||||
|
||||
assert.AssertionError.__proto__ = Error.prototype;
|
||||
|
||||
// At present only the three keys mentioned above are used and
|
||||
// understood by the spec. Implementations or sub modules can pass
|
||||
// other keys to the AssertionError's constructor - they will be
|
||||
// ignored.
|
||||
|
||||
// 3. All of the following functions must throw an AssertionError
|
||||
// when a corresponding condition is not met, with a message that
|
||||
// may be undefined if not provided. All assertion methods provide
|
||||
// both the actual and expected values to the assertion error for
|
||||
// display purposes.
|
||||
|
||||
function fail(actual, expected, message, operator, stackStartFunction) {
|
||||
throw new assert.AssertionError({
|
||||
message: message,
|
||||
actual: actual,
|
||||
expected: expected,
|
||||
operator: operator,
|
||||
stackStartFunction: stackStartFunction
|
||||
});
|
||||
}
|
||||
|
||||
// EXTENSION! allows for well behaved errors defined elsewhere.
|
||||
assert.fail = fail;
|
||||
|
||||
// 4. Pure assertion tests whether a value is truthy, as determined
|
||||
// by !!guard.
|
||||
// assert.ok(guard, message_opt);
|
||||
// This statement is equivalent to assert.equal(true, guard,
|
||||
// message_opt);. To test strictly for the value true, use
|
||||
// assert.strictEqual(true, guard, message_opt);.
|
||||
|
||||
assert.ok = function ok(value, message) {
|
||||
if (!!!value) fail(value, true, message, '==', assert.ok);
|
||||
};
|
||||
|
||||
// 5. The equality assertion tests shallow, coercive equality with
|
||||
// ==.
|
||||
// assert.equal(actual, expected, message_opt);
|
||||
|
||||
assert.equal = function equal(actual, expected, message) {
|
||||
if (actual != expected) fail(actual, expected, message, '==', assert.equal);
|
||||
};
|
||||
|
||||
// 6. The non-equality assertion tests for whether two objects are not equal
|
||||
// with != assert.notEqual(actual, expected, message_opt);
|
||||
|
||||
assert.notEqual = function notEqual(actual, expected, message) {
|
||||
if (actual == expected) {
|
||||
fail(actual, expected, message, '!=', assert.notEqual);
|
||||
}
|
||||
};
|
||||
|
||||
// 7. The equivalence assertion tests a deep equality relation.
|
||||
// assert.deepEqual(actual, expected, message_opt);
|
||||
|
||||
assert.deepEqual = function deepEqual(actual, expected, message) {
|
||||
if (!_deepEqual(actual, expected)) {
|
||||
fail(actual, expected, message, 'deepEqual', assert.deepEqual);
|
||||
}
|
||||
};
|
||||
|
||||
function _deepEqual(actual, expected) {
|
||||
// 7.1. All identical values are equivalent, as determined by ===.
|
||||
if (actual === expected) {
|
||||
return true;
|
||||
|
||||
} else if (this.Buffer && Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
|
||||
if (actual.length != expected.length) return false;
|
||||
|
||||
for (var i = 0; i < actual.length; i++) {
|
||||
if (actual[i] !== expected[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
// 7.2. If the expected value is a Date object, the actual value is
|
||||
// equivalent if it is also a Date object that refers to the same time.
|
||||
} else if (actual instanceof Date && expected instanceof Date) {
|
||||
return actual.getTime() === expected.getTime();
|
||||
|
||||
// 7.3. Other pairs that do not both pass typeof value == 'object',
|
||||
// equivalence is determined by ==.
|
||||
} else if (typeof actual != 'object' && typeof expected != 'object') {
|
||||
return actual == expected;
|
||||
|
||||
// 7.4. For all other Object pairs, including Array objects, equivalence is
|
||||
// determined by having the same number of owned properties (as verified
|
||||
// with Object.prototype.hasOwnProperty.call), the same set of keys
|
||||
// (although not necessarily the same order), equivalent values for every
|
||||
// corresponding key, and an identical 'prototype' property. Note: this
|
||||
// accounts for both named and indexed properties on Arrays.
|
||||
} else {
|
||||
return objEquiv(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
function isUndefinedOrNull(value) {
|
||||
return value === null || value === undefined;
|
||||
}
|
||||
|
||||
function isArguments(object) {
|
||||
return Object.prototype.toString.call(object) == '[object Arguments]';
|
||||
}
|
||||
|
||||
function objEquiv(a, b) {
|
||||
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
|
||||
return false;
|
||||
// an identical 'prototype' property.
|
||||
if (a.prototype !== b.prototype) return false;
|
||||
//~~~I've managed to break Object.keys through screwy arguments passing.
|
||||
// Converting to array solves the problem.
|
||||
if (isArguments(a)) {
|
||||
if (!isArguments(b)) {
|
||||
return false;
|
||||
}
|
||||
a = pSlice.call(a);
|
||||
b = pSlice.call(b);
|
||||
return _deepEqual(a, b);
|
||||
}
|
||||
try {
|
||||
var ka = Object.keys(a),
|
||||
kb = Object.keys(b),
|
||||
key, i;
|
||||
} catch (e) {//happens when one is a string literal and the other isn't
|
||||
return false;
|
||||
}
|
||||
// having the same number of owned properties (keys incorporates
|
||||
// hasOwnProperty)
|
||||
if (ka.length != kb.length)
|
||||
return false;
|
||||
//the same set of keys (although not necessarily the same order),
|
||||
ka.sort();
|
||||
kb.sort();
|
||||
//~~~cheap key test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
if (ka[i] != kb[i])
|
||||
return false;
|
||||
}
|
||||
//equivalent values for every corresponding key, and
|
||||
//~~~possibly expensive deep test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
key = ka[i];
|
||||
if (!_deepEqual(a[key], b[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 8. The non-equivalence assertion tests for any deep inequality.
|
||||
// assert.notDeepEqual(actual, expected, message_opt);
|
||||
|
||||
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
|
||||
if (_deepEqual(actual, expected)) {
|
||||
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
|
||||
}
|
||||
};
|
||||
|
||||
// 9. The strict equality assertion tests strict equality, as determined by ===.
|
||||
// assert.strictEqual(actual, expected, message_opt);
|
||||
|
||||
assert.strictEqual = function strictEqual(actual, expected, message) {
|
||||
if (actual !== expected) {
|
||||
fail(actual, expected, message, '===', assert.strictEqual);
|
||||
}
|
||||
};
|
||||
|
||||
// 10. The strict non-equality assertion tests for strict inequality, as
|
||||
// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
|
||||
|
||||
assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
|
||||
if (actual === expected) {
|
||||
fail(actual, expected, message, '!==', assert.notStrictEqual);
|
||||
}
|
||||
};
|
||||
|
||||
function expectedException(actual, expected) {
|
||||
if (!actual || !expected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (expected instanceof RegExp) {
|
||||
return expected.test(actual);
|
||||
} else if (actual instanceof expected) {
|
||||
return true;
|
||||
} else if ( expected.call({}, actual) === true ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function _throws(shouldThrow, block, expected, message) {
|
||||
var actual;
|
||||
|
||||
if (typeof expected === 'string') {
|
||||
message = expected;
|
||||
expected = null;
|
||||
}
|
||||
|
||||
try {
|
||||
block();
|
||||
} catch (e) {
|
||||
actual = e;
|
||||
}
|
||||
|
||||
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
|
||||
(message ? ' ' + message : '.');
|
||||
|
||||
if (shouldThrow && !actual) {
|
||||
fail('Missing expected exception' + message);
|
||||
}
|
||||
|
||||
if (!shouldThrow && expectedException(actual, expected)) {
|
||||
fail('Got unwanted exception' + message);
|
||||
}
|
||||
|
||||
if ((shouldThrow && actual && expected &&
|
||||
!expectedException(actual, expected)) || (!shouldThrow && actual)) {
|
||||
throw actual;
|
||||
}
|
||||
}
|
||||
|
||||
// 11. Expected to throw an error:
|
||||
// assert.throws(block, Error_opt, message_opt);
|
||||
|
||||
assert['throws'] = function(block, /*optional*/error, /*optional*/message) {
|
||||
_throws.apply(this, [true].concat(pSlice.call(arguments)));
|
||||
};
|
||||
|
||||
// EXTENSION! This is annoying to write outside this module.
|
||||
assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
|
||||
_throws.apply(this, [false].concat(pSlice.call(arguments)));
|
||||
};
|
||||
|
||||
assert.ifError = function(err) { if (err) {throw err;}};
|
||||
120
modules/common/dumper.js
Normal file
120
modules/common/dumper.js
Normal file
@ -0,0 +1,120 @@
|
||||
/**
|
||||
@module common/dumper
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
(function() {
|
||||
exports.dump = function(object) {
|
||||
indentBy = 0;
|
||||
output = '';
|
||||
|
||||
walk(object);
|
||||
outdent(false);
|
||||
return output;
|
||||
}
|
||||
|
||||
const INDENTATION = ' '; // 4 spaces
|
||||
var indentBy,
|
||||
output;
|
||||
|
||||
function pad(depth) {
|
||||
var padding = '';
|
||||
while (depth--) {
|
||||
padding += INDENTATION;
|
||||
}
|
||||
return padding;
|
||||
}
|
||||
|
||||
function indent(openingBrace) {
|
||||
indentBy++;
|
||||
if (openingBrace) output += openingBrace + '\n';
|
||||
}
|
||||
|
||||
/**
|
||||
@param {string|boolean} The closing brace to add, like "}" or if boolean
|
||||
`false` no closing brace nor trailing newline;
|
||||
*/
|
||||
function outdent(closingBrace) {
|
||||
indentBy--;
|
||||
output = output.replace(/,\n$/, '\n'); // trim trailing comma
|
||||
if (closingBrace === false) { output = output.replace(/\n$/, ''); }
|
||||
else if (closingBrace) output += pad(indentBy) + closingBrace + ',\n';
|
||||
}
|
||||
|
||||
function walk(object) {
|
||||
var value;
|
||||
if ( value = getValue(object) ) {
|
||||
output += value + ',\n';
|
||||
}
|
||||
else if ( isUnwalkable(object) ) {
|
||||
output += '<Object>,\n'
|
||||
}
|
||||
else if ( isRegExp(object) ) {
|
||||
output += '<RegExp ' + object + '>,\n'
|
||||
}
|
||||
else if ( isDate(object) ) {
|
||||
output += '<Date ' + object + '>,\n'
|
||||
}
|
||||
else if ( isFunction(object) ) {
|
||||
output += '<Function' + (object.name? ' '+ object.name : '') + '>,\n';
|
||||
}
|
||||
else if ( isArray(object) ) {
|
||||
indent('[');
|
||||
for (var i = 0, leni = object.length; i < leni; i++) {
|
||||
output += pad(indentBy); // + i + ': ';
|
||||
walk( object[i] );
|
||||
}
|
||||
outdent(']');
|
||||
}
|
||||
else if ( isObject(object) ) {
|
||||
indent('{');
|
||||
for (var p in object) {
|
||||
if ( object.hasOwnProperty(p) ) {
|
||||
output += pad(indentBy) + stringify(p) + ': ';
|
||||
walk( object[p] );
|
||||
}
|
||||
}
|
||||
outdent('}');
|
||||
}
|
||||
}
|
||||
|
||||
function getValue(o) { // see: https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/typeof
|
||||
if (o === null) { return 'null'; }
|
||||
if ( /^(string|boolean|number|undefined)$/.test(typeof o) ) {
|
||||
return ''+stringify(o);
|
||||
}
|
||||
}
|
||||
|
||||
function stringify(o) {
|
||||
return JSON.stringify(o);
|
||||
}
|
||||
|
||||
function isUnwalkable(o) { // some objects are unwalkable, like Java native objects
|
||||
return (typeof o === 'object' && typeof o.constructor === 'undefined');
|
||||
}
|
||||
|
||||
function isArray(o) {
|
||||
return o && (o instanceof Array) || o.constructor === Array;
|
||||
}
|
||||
|
||||
function isRegExp(o) {
|
||||
return (o instanceof RegExp) ||
|
||||
(typeof o.constructor !== 'undefined' && o.constructor.name === 'RegExp');
|
||||
}
|
||||
|
||||
function isDate(o) {
|
||||
return o && (o instanceof Date) ||
|
||||
(typeof o.constructor !== 'undefined' && o.constructor.name === 'Date');
|
||||
}
|
||||
|
||||
function isFunction(o) {
|
||||
return o && (typeof o === 'function' || o instanceof Function);// ||
|
||||
//(typeof o.constructor !== 'undefined' && (o.constructor||{}).name === 'Function');
|
||||
}
|
||||
|
||||
function isObject(o) {
|
||||
return o && o instanceof Object ||
|
||||
(typeof o.constructor !== 'undefined' && o.constructor.name === 'Object');
|
||||
}
|
||||
|
||||
})();
|
||||
100
modules/common/util.js
Normal file
100
modules/common/util.js
Normal file
@ -0,0 +1,100 @@
|
||||
exports.print = function() {
|
||||
for (var i = 0, len = arguments.length; i < len; ++i) {
|
||||
java.lang.System.out.print(String(arguments[i]));
|
||||
}
|
||||
};
|
||||
|
||||
exports.puts = function() {
|
||||
for (var i = 0, len = arguments.length; i < len; ++i) {
|
||||
java.lang.System.out.println(arguments[i] + '\n');
|
||||
}
|
||||
};
|
||||
|
||||
exports.debug = function(x) {
|
||||
exports.puts('DEBUG: ' + x + '\n');
|
||||
};
|
||||
|
||||
var error = exports.error = function(x) {
|
||||
for (var i = 0, len = arguments.length; i < len; ++i) {
|
||||
exports.puts(arguments[i] + '\n');
|
||||
}
|
||||
};
|
||||
|
||||
exports.format = {
|
||||
stylize: function(str, styleType) {
|
||||
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
|
||||
var styles =
|
||||
{ 'bold' : [1, 22],
|
||||
'italic' : [3, 23],
|
||||
'underline' : [4, 24],
|
||||
'inverse' : [7, 27],
|
||||
'white' : [37, 39],
|
||||
'grey' : [90, 39],
|
||||
'black' : [30, 39],
|
||||
'blue' : [34, 39],
|
||||
'cyan' : [36, 39],
|
||||
'green' : [32, 39],
|
||||
'magenta' : [35, 39],
|
||||
'red' : [31, 39],
|
||||
'yellow' : [33, 39] };
|
||||
|
||||
var style =
|
||||
{ 'special': 'cyan',
|
||||
'number': 'blue',
|
||||
'boolean': 'yellow',
|
||||
'undefined': 'grey',
|
||||
'null': 'bold',
|
||||
'string': 'green',
|
||||
'date': 'magenta',
|
||||
// "name": intentionally not styling
|
||||
'regexp': 'red' }[styleType];
|
||||
|
||||
if (style) {
|
||||
return '\033[' + styles[style][0] + 'm' + str +
|
||||
'\033[' + styles[style][1] + 'm';
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
},
|
||||
|
||||
pad: function (n) {
|
||||
return n < 10 ? '0' + n.toString(10) : n.toString(10);
|
||||
}
|
||||
}
|
||||
|
||||
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
|
||||
'Oct', 'Nov', 'Dec'];
|
||||
|
||||
// 26 Feb 16:19:34
|
||||
exports.timestamp = function() {
|
||||
var d = new Date();
|
||||
var time = [pad(d.getHours()),
|
||||
pad(d.getMinutes()),
|
||||
pad(d.getSeconds())].join(':');
|
||||
return [d.getDate(), months[d.getMonth()], time].join(' ');
|
||||
}
|
||||
|
||||
|
||||
exports.log = function(msg) {
|
||||
exports.puts(exports.timestamp() + ' - ' + msg.toString());
|
||||
};
|
||||
|
||||
/**
|
||||
* Inherit the prototype methods from one constructor into another.
|
||||
*
|
||||
* The Function.prototype.inherits from lang.js rewritten as a standalone
|
||||
* function (not on Function.prototype). NOTE: If this file is to be loaded
|
||||
* during bootstrapping this function needs to be revritten using some native
|
||||
* functions as prototype setup using normal JavaScript does not work as
|
||||
* expected during bootstrapping (see mirror.js in r114903).
|
||||
*
|
||||
* @param {function} ctor Constructor function which needs to inherit the
|
||||
* prototype.
|
||||
* @param {function} superCtor Constructor function to inherit prototype from.
|
||||
*/
|
||||
exports.inherits = function(ctor, superCtor) {
|
||||
ctor.super_ = superCtor;
|
||||
ctor.prototype = Object.create(superCtor.prototype, {
|
||||
constructor: { value: ctor, enumerable: false }
|
||||
});
|
||||
};
|
||||
@ -1,175 +0,0 @@
|
||||
|
||||
// Ported by Tom Robinson
|
||||
|
||||
/**
|
||||
* jsDump
|
||||
* Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
|
||||
* Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php)
|
||||
* Date: 5/15/2008
|
||||
* @projectDescription Advanced and extensible data dumping for Javascript.
|
||||
* @version 1.0.0
|
||||
* @author Ariel Flesler
|
||||
*/
|
||||
var jsDump;
|
||||
|
||||
(function(){
|
||||
function quote( str ){
|
||||
return '"' + str.toString()
|
||||
.replace(/\\/g, "\\\\")
|
||||
.replace(/"/g, '\\"')
|
||||
.replace(/\f/g, "\\f")
|
||||
.replace(/\n/g, "\\n")
|
||||
.replace(/\r/g, "\\r")
|
||||
.replace(/\t/g, "\\t")
|
||||
+ '"';
|
||||
};
|
||||
function literal( o ){
|
||||
return o + '';
|
||||
};
|
||||
function join( pre, arr, post ){
|
||||
var s = jsDump.separator(),
|
||||
base = jsDump.indent(),
|
||||
inner = jsDump.indent(1);
|
||||
if( arr.join )
|
||||
arr = arr.join( ',' + s + inner );
|
||||
if( !arr )
|
||||
return pre + post;
|
||||
return [ pre, inner + arr, base + post ].join(s);
|
||||
};
|
||||
function array( arr ){
|
||||
var i = arr.length, ret = Array(i);
|
||||
this.up();
|
||||
while( i-- )
|
||||
ret[i] = this.parse( arr[i] );
|
||||
this.down();
|
||||
return join( '[', ret, ']' );
|
||||
};
|
||||
|
||||
var reName = /^function (\w+)/;
|
||||
|
||||
jsDump = {
|
||||
parse:function( obj, type ){//type is used mostly internally, you can fix a (custom)type in advance
|
||||
var parser = this.parsers[ type || this.typeOf(obj) ];
|
||||
type = typeof parser;
|
||||
|
||||
return type == 'function' ? parser.call( this, obj ) :
|
||||
type == 'string' ? parser :
|
||||
this.parsers.error;
|
||||
},
|
||||
typeOf:function( obj ){
|
||||
var type = typeof obj,
|
||||
f = 'function';//we'll use it 3 times, save it
|
||||
return type != 'object' && type != f ? type :
|
||||
!obj ? 'null' :
|
||||
obj.exec ? 'regexp' :// some browsers (FF) consider regexps functions
|
||||
obj.getHours ? 'date' :
|
||||
obj.scrollBy ? 'window' :
|
||||
obj.nodeName == '#document' ? 'document' :
|
||||
obj.nodeName ? 'node' :
|
||||
obj.item ? 'nodelist' : // Safari reports nodelists as functions
|
||||
obj.callee ? 'arguments' :
|
||||
obj.call || obj.constructor != Array && //an array would also fall on this hack
|
||||
(obj+'').indexOf(f) != -1 ? f : //IE reports functions like alert, as objects
|
||||
'length' in obj ? 'array' :
|
||||
type;
|
||||
},
|
||||
separator:function(){
|
||||
return this.multiline ? this.HTML ? '<br />' : '\n' : this.HTML ? ' ' : ' ';
|
||||
},
|
||||
indent:function( extra ){// extra can be a number, shortcut for increasing-calling-decreasing
|
||||
if( !this.multiline )
|
||||
return '';
|
||||
var chr = this.indentChar;
|
||||
if( this.HTML )
|
||||
chr = chr.replace(/\t/g,' ').replace(/ /g,' ');
|
||||
return Array( this._depth_ + (extra||0) ).join(chr);
|
||||
},
|
||||
up:function( a ){
|
||||
this._depth_ += a || 1;
|
||||
},
|
||||
down:function( a ){
|
||||
this._depth_ -= a || 1;
|
||||
},
|
||||
setParser:function( name, parser ){
|
||||
this.parsers[name] = parser;
|
||||
},
|
||||
// The next 3 are exposed so you can use them
|
||||
quote:quote,
|
||||
literal:literal,
|
||||
join:join,
|
||||
//
|
||||
_depth_: 1,
|
||||
// This is the list of parsers, to modify them, use jsDump.setParser
|
||||
parsers:{
|
||||
window: '[Window]',
|
||||
document: '[Document]',
|
||||
error:'[ERROR]', //when no parser is found, shouldn't happen
|
||||
unknown: '[Unknown]',
|
||||
'null':'null',
|
||||
undefined:'undefined',
|
||||
'function':function( fn ){
|
||||
var ret = 'function',
|
||||
name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE
|
||||
if( name )
|
||||
ret += ' ' + name;
|
||||
ret += '(';
|
||||
|
||||
ret = [ ret, this.parse( fn, 'functionArgs' ), '){'].join('');
|
||||
return join( ret, this.parse(fn,'functionCode'), '}' );
|
||||
},
|
||||
array: array,
|
||||
nodelist: array,
|
||||
arguments: array,
|
||||
object:function( map ){
|
||||
var ret = [ ];
|
||||
this.up();
|
||||
for( var key in map )
|
||||
ret.push( this.parse(key,'key') + ': ' + this.parse(map[key]) );
|
||||
this.down();
|
||||
return join( '{', ret, '}' );
|
||||
},
|
||||
node:function( node ){
|
||||
var open = this.HTML ? '<' : '<',
|
||||
close = this.HTML ? '>' : '>';
|
||||
|
||||
var tag = node.nodeName.toLowerCase(),
|
||||
ret = open + tag;
|
||||
|
||||
for( var a in this.DOMAttrs ){
|
||||
var val = node[this.DOMAttrs[a]];
|
||||
if( val )
|
||||
ret += ' ' + a + '=' + this.parse( val, 'attribute' );
|
||||
}
|
||||
return ret + close + open + '/' + tag + close;
|
||||
},
|
||||
functionArgs:function( fn ){//function calls it internally, it's the arguments part of the function
|
||||
var l = fn.length;
|
||||
if( !l ) return '';
|
||||
|
||||
var args = Array(l);
|
||||
while( l-- )
|
||||
args[l] = String.fromCharCode(97+l);//97 is 'a'
|
||||
return ' ' + args.join(', ') + ' ';
|
||||
},
|
||||
key:quote, //object calls it internally, the key part of an item in a map
|
||||
functionCode:'[code]', //function calls it internally, it's the content of the function
|
||||
attribute:quote, //onode calls it internally, it's an html attribute value
|
||||
string:quote,
|
||||
date:quote,
|
||||
regexp:literal, //regex
|
||||
number:literal,
|
||||
'boolean':literal
|
||||
},
|
||||
DOMAttrs:{//attributes to dump from nodes, name=>realName
|
||||
id:'id',
|
||||
name:'name',
|
||||
'class':'className'
|
||||
},
|
||||
HTML:false,//if true, entities are escaped ( <, >, \t, space and \n )
|
||||
indentChar:' ',//indentation unit
|
||||
multiline:true //if true, items in a collection, are separated by a \n, else just a space.
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
exports.jsDump = jsDump;
|
||||
@ -1,417 +1,138 @@
|
||||
/**
|
||||
@overview
|
||||
@module jsdoc/doclet
|
||||
@requires jsdoc/tag
|
||||
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
(function() {
|
||||
var Tag = require('jsdoc/tag').Tag,
|
||||
tagDictionary = require('jsdoc/tag/dictionary');
|
||||
|
||||
/**
|
||||
@constructor
|
||||
*/
|
||||
exports.Doclet = function (docletSrc, meta) {
|
||||
var newTags = [];
|
||||
|
||||
this.src = docletSrc;
|
||||
this.meta = meta;
|
||||
this.tags = [];
|
||||
|
||||
docletSrc = unwrap(docletSrc);
|
||||
docletSrc = fixDescription(docletSrc);
|
||||
|
||||
/**
|
||||
Functionality relating to jsdoc comments and their tags.
|
||||
@module jsdoc/doclet
|
||||
*/
|
||||
(function() {
|
||||
var jsdoc = {
|
||||
name: require('jsdoc/name'),
|
||||
tag: require('jsdoc/tag'),
|
||||
tagDictionary: require('jsdoc/tagdictionary')
|
||||
};
|
||||
|
||||
/**
|
||||
Factory that builds a Doclet object.
|
||||
@param {string} commentSrc
|
||||
@param {ASTNode} node
|
||||
@param {string} fileName
|
||||
@returns {Doclet}
|
||||
*/
|
||||
exports.makeDoclet = function(commentSrc, node, fileName) {
|
||||
var tags = [],
|
||||
meta = {},
|
||||
doclet;
|
||||
|
||||
meta.file = fileName;
|
||||
meta.line = node? node.getLineno() : '';
|
||||
|
||||
commentSrc = unwrapComment(commentSrc);
|
||||
commentSrc = fixDesc(commentSrc);
|
||||
|
||||
tags = jsdoc.tag.parse(commentSrc);
|
||||
newTags = toTags.call(this, docletSrc);
|
||||
|
||||
try {
|
||||
preprocess(tags, meta);
|
||||
}
|
||||
catch(e) {
|
||||
e.message = 'Cannot make doclet from JSDoc comment found at '+ meta.file + ' ' + meta.line
|
||||
+ ': ' + e.message
|
||||
+ '\n "' + commentSrc.replace(/\n\s+/g, '\n ') + '"';
|
||||
throw e;
|
||||
}
|
||||
|
||||
doclet = new Doclet(tags);
|
||||
|
||||
doclet.meta = meta;
|
||||
for (var i = 0, leni = newTags.length; i < leni; i++) {
|
||||
this.addTag(newTags[i].title, newTags[i].text);
|
||||
}
|
||||
|
||||
this.applyTags(this.tags);
|
||||
}
|
||||
|
||||
postprocess(doclet);
|
||||
jsdoc.name.resolve(doclet);
|
||||
exports.Doclet.prototype.addTag = function(title, text) {
|
||||
var tagDef = tagDictionary.lookUp(title),
|
||||
newTag = new Tag(title, text, {});
|
||||
|
||||
if (tagDef.onTagged) {
|
||||
if (tagDef.onTagged(this, newTag) !== false) { // onTagged handler prevents tag being added bt returning false
|
||||
this.tags.push(newTag);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.tags.push(newTag);
|
||||
}
|
||||
}
|
||||
|
||||
exports.Doclet.prototype.applyTags = function(tags) {
|
||||
var tag;
|
||||
|
||||
for (var i = 0, leni = tags.length; i < leni; i++) {
|
||||
tag = tags[i];
|
||||
|
||||
return doclet
|
||||
if (tag.title === 'name') {
|
||||
this.name = tag.value;
|
||||
}
|
||||
|
||||
if (tag.title === 'kind') {
|
||||
this.kind = tag.value;
|
||||
}
|
||||
|
||||
if (tag.title === 'description') {
|
||||
this.description = tag.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@private
|
||||
@constructor Doclet
|
||||
@param {Array.<Object>} tags
|
||||
Convert the raw source of the doclet comment into an array of Tag objects.
|
||||
@private
|
||||
*/
|
||||
function Doclet(tags) {
|
||||
/**
|
||||
An array of Objects representing tags.
|
||||
@type Array.<Tag>
|
||||
@member Doclet#tags
|
||||
*/
|
||||
this.tags = tags;
|
||||
function toTags(docletSrc) {
|
||||
var tagSrcs,
|
||||
tags = [];
|
||||
|
||||
docletSrc = unwrap(docletSrc);
|
||||
tagSrcs = split(docletSrc);
|
||||
//dump('tagSrcs', tagSrcs);
|
||||
|
||||
for each(tagSrc in tagSrcs) {
|
||||
tags.push( {title: tagSrc.title, text: tagSrc.text} );
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
/**
|
||||
Set the name of the Doclet.
|
||||
@method Doclet#setName
|
||||
@param {string} nameToSet
|
||||
*/
|
||||
Doclet.prototype.setName = function(nameToSet) {
|
||||
this.setTag('name', nameToSet);
|
||||
|
||||
nameToSet = jsdoc.name.resolve(this);
|
||||
}
|
||||
|
||||
/**
|
||||
Return the value of the first tag with the given name.
|
||||
@method Doclet#tagValue
|
||||
@param {String} tagName
|
||||
@returns {*} The value of the found tag.
|
||||
*/
|
||||
Doclet.prototype.tagValue = function(tagName) {
|
||||
var tagAbout = jsdoc.tagDictionary.lookUp(tagName);
|
||||
for (var i = 0, leni = this.tags.length; i < leni; i++) {
|
||||
if (this.tags[i].name === tagName) {
|
||||
if (tagAbout.isScalar && this.tags[i].value.push) {
|
||||
return this.tags[i].value[0];
|
||||
}
|
||||
return this.tags[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
Set the value of the first tag with the given name.
|
||||
@method Doclet#setTag
|
||||
@param {String} tagName
|
||||
@returns {*} The value of the found tag.
|
||||
*/
|
||||
Doclet.prototype.setTag = function(tagName, tagValue) {
|
||||
|
||||
for (var i = 0, leni = this.tags.length; i < leni; i++) {
|
||||
if (this.tags[i].name === tagName) {
|
||||
this.tags[i].value = tagValue;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
this.addTag(tagName, tagValue);
|
||||
}
|
||||
|
||||
/**
|
||||
Add a new tag.
|
||||
@method Doclet#addTag
|
||||
@param {String} tagName
|
||||
@param {String} tagValue
|
||||
@returns {Tag} The new tag.
|
||||
*/
|
||||
Doclet.prototype.addTag = function(tagName, tagValue) {
|
||||
return this.tags.addTag(tagName, tagValue);
|
||||
}
|
||||
|
||||
/**
|
||||
Return the first tag with the given name.
|
||||
@method Doclet#getTag
|
||||
@param {String} tagName
|
||||
@returns {Tag} The irst found tag with that name.
|
||||
*/
|
||||
Doclet.prototype.getTag = function(tagName) {
|
||||
for (var i = 0, leni = this.tags.length; i < leni; i++) {
|
||||
if (this.tags[i].name === tagName) {
|
||||
return this.tags[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
Does a tag with the given name exist in this doclet?
|
||||
@method Doclet#hasTag
|
||||
@param {String} tagName
|
||||
@returns {boolean} True if the tag is found, false otherwise.
|
||||
*/
|
||||
Doclet.prototype.hasTag = function(tagName) {
|
||||
return this.tags.hasTag(tagName);
|
||||
}
|
||||
|
||||
/**
|
||||
Get a JSON-compatible object representing this Doclet.
|
||||
@method Doclet#toObject
|
||||
@param {string} [flavor='json'] Either: jason or xml.
|
||||
@returns {Object}
|
||||
*/
|
||||
Doclet.prototype.toObject = function(/*todo*/flavor) {
|
||||
var tag, tagName, tagValue, tagAbout,
|
||||
o = {};
|
||||
|
||||
for (var i = 0, leni = this.tags.length; i < leni; i++) {
|
||||
tag = this.tags[i];
|
||||
tagName = tag.name;
|
||||
tagValue = {};
|
||||
tagAbout = jsdoc.tagDictionary.lookUp(tagName);
|
||||
|
||||
if (!tagAbout.isExported) { continue; }
|
||||
|
||||
// a long tag, like a @param
|
||||
if (tag.pname) {
|
||||
tagValue.name = tag.pname; // the parameter name
|
||||
}
|
||||
if (tag.type && tag.type.length && tag.type[0] !== '') {
|
||||
if (tag.type.length === 1) { tagValue.type = tag.type[0]; }
|
||||
else { tagValue.type = tag.type; }
|
||||
}
|
||||
if (tag.pdesc) { tagValue.description = tag.pdesc; }
|
||||
if (typeof tag.poptional === 'boolean') { tagValue.optional = tag.poptional; }
|
||||
if (typeof tag.pnullable === 'boolean') { tagValue.nullable = tag.pnullable; }
|
||||
if (typeof tag.pdefault !== 'undefined') { tagValue.defaultvalue = tag.pdefault; }
|
||||
|
||||
// tag value is not an object, it's just a simple string
|
||||
if (!tag.pname && !tag.pdesc && !(tag.type && tag.type.length)) { // TODO: should check the list instead?
|
||||
if (flavor === 'xml' && tagName === 'example') {
|
||||
tagValue['#cdata'] = tag.value; // TODO this is only meaningful to XML, move to a tag.format(style) method?
|
||||
}
|
||||
else {
|
||||
tagValue = tag.value;
|
||||
}
|
||||
}
|
||||
|
||||
if (tagAbout.exportName) {
|
||||
tagName = tagAbout.exportName;
|
||||
}
|
||||
|
||||
if (tagValue) {
|
||||
if (typeof o[tagName] === 'undefined') { // not defined
|
||||
o[tagName] = tagAbout.forceArray? [tagValue] : tagValue;
|
||||
}
|
||||
else if (typeof o[tagName].push === 'function') { // is an array
|
||||
o[tagName].push(tagValue);
|
||||
}
|
||||
else { // is a string, but needs to be an array
|
||||
o[tagName] = [ o[tagName] ];
|
||||
o[tagName].push(tagValue);
|
||||
}
|
||||
}
|
||||
|
||||
o.meta = this.meta;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
Remove JsDoc comment slash-stars. Trims white space.
|
||||
@private
|
||||
@function unwrapComment
|
||||
@param {string} commentSrc
|
||||
@return {string} Coment wit stars and slashes removed.
|
||||
*/
|
||||
function unwrapComment(commentSrc) {
|
||||
if (!commentSrc) { return ''; }
|
||||
function unwrap(docletSrc) {
|
||||
if (!docletSrc) { return ''; }
|
||||
|
||||
// note: keep trailing whitespace for @examples
|
||||
// extra opening/closing stars are ignored
|
||||
// left margin is considered a star and a space
|
||||
// use the /m flag on regex to avoid having to guess what this platform's newline is
|
||||
commentSrc =
|
||||
commentSrc.replace(/^\/\*\*+/, '') // remove opening slash+stars
|
||||
.replace(/\**\*\/$/, "\\Z") // replace closing star slash with end-marker
|
||||
.replace(/^\s*(\* ?|\\Z)/gm, '') // remove left margin like: spaces+star or spaces+end-marker
|
||||
.replace(/\s*\\Z$/g, ''); // remove end-marker
|
||||
docletSrc =
|
||||
docletSrc.replace(/^\/\*\*+/, '') // remove opening slash+stars
|
||||
.replace(/\**\*\/$/, "\\Z") // replace closing star slash with end-marker
|
||||
.replace(/^\s*(\* ?|\\Z)/gm, '') // remove left margin like: spaces+star or spaces+end-marker
|
||||
.replace(/\s*\\Z$/g, ''); // remove end-marker
|
||||
|
||||
return commentSrc;
|
||||
return docletSrc;
|
||||
}
|
||||
|
||||
/**
|
||||
Add a @description tag if none exists on untagged text at start of comment.
|
||||
@private
|
||||
@function fixDesc
|
||||
@param {string} commentSrc
|
||||
@return {string} With needed @description tag added.
|
||||
*/
|
||||
function fixDesc(commentSrc) {
|
||||
if (!/^\s*@/.test(commentSrc)) {
|
||||
commentSrc = '@description ' + commentSrc;
|
||||
function fixDescription(docletSrc) {
|
||||
if (!/^\s*@/.test(docletSrc)) {
|
||||
docletSrc = '@description ' + docletSrc;
|
||||
}
|
||||
return commentSrc;
|
||||
return docletSrc;
|
||||
}
|
||||
|
||||
/**
|
||||
Expand some shortcut tags. Modifies the tags argument in-place.
|
||||
@private
|
||||
@method preprocess
|
||||
@param {Array.<Object>} tags
|
||||
@returns undefined
|
||||
*/
|
||||
function preprocess(tags, meta) {
|
||||
var name = '',
|
||||
taggedName = '',
|
||||
kind = '',
|
||||
taggedKind = '',
|
||||
memberof = '',
|
||||
taggedMemberof = '',
|
||||
isFile = false, // TODO this should be handled by an event handler in tag dictionary
|
||||
tagAbout;
|
||||
|
||||
for (var i = 0; i < tags.length; i++) {
|
||||
tagAbout = jsdoc.tagDictionary.lookUp(tags[i].name);
|
||||
|
||||
if (tagAbout.setsDocletAttrib) {
|
||||
tags.addTag('attrib', tags[i].name);
|
||||
}
|
||||
|
||||
if (tagAbout.setsDocletAccess) {
|
||||
tags.addTag('access', tags[i].name);
|
||||
}
|
||||
|
||||
if (tagAbout.setsDocletScope) {
|
||||
tags.addTag('scope', tags[i].name);
|
||||
}
|
||||
|
||||
if (tagAbout.impliesTag) { // TODO allow a template string?
|
||||
tags.addTag(tagAbout.impliesTag);
|
||||
}
|
||||
|
||||
if (tagAbout.setsDocletDesc) {
|
||||
tags.addTag('description', tags[i].value);
|
||||
}
|
||||
|
||||
if (tags[i].name === 'name') {
|
||||
if (name && name !== tags[i].value) {
|
||||
throw new DocTagConflictError('Conflicting names in documentation: "'+name+'", and "'+tags[i].value+'"');
|
||||
}
|
||||
taggedName = name = tags[i].value;
|
||||
}
|
||||
else if (tags[i].name === 'kind') {
|
||||
if (kind && kind !== tags[i].value) {
|
||||
throw new DocTagConflictError('Symbol has too many isas, cannot be both: ' + kind + ' and ' + tags[i].value);
|
||||
}
|
||||
taggedKind = kind = tags[i].value;
|
||||
}
|
||||
else if (tags[i].name === 'memberof') {
|
||||
if (memberof) {
|
||||
throw new DocTagConflictError('doclet has too many tags of type: @memberof.');
|
||||
}
|
||||
taggedMemberof = memberof = tags[i].value;
|
||||
}
|
||||
|
||||
if ( tagAbout.setsDocletName/*nameables.indexOf(tags[i].name) > -1*/ ) {
|
||||
if (tags[i].name === 'property' && (kind === 'constructor')) {
|
||||
// to avoid backwards compatability conflicts we just ignore a @property in a doclet after a @constructor
|
||||
}
|
||||
else if (tags[i].name === 'file') {
|
||||
isFile = true;
|
||||
kind = 'file';
|
||||
}
|
||||
else {
|
||||
if (tags[i].value) {
|
||||
if (name && name !== tags[i].value) {
|
||||
throw new DocTagConflictError('Conflicting names in documentation: "'+name+'", and "'+tags[i].value+'"');
|
||||
}
|
||||
name = tags[i].value;
|
||||
}
|
||||
|
||||
if (tags[i].pdesc) {
|
||||
tags.addTag('description', tags[i].pdesc);
|
||||
}
|
||||
|
||||
if (kind && kind !== tags[i].name) {
|
||||
throw new DocTagConflictError('Symbol has too many isas, cannot be both: ' + kind + ' and ' + tags[i].name);
|
||||
}
|
||||
kind = tags[i].name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( /^\s*(\S+)\s*=>\s*(\S+)/.test(taggedName) ) {
|
||||
taggedName = RegExp.$1;
|
||||
var refersto = RegExp.$2;
|
||||
|
||||
tags.setTag('name', taggedName);
|
||||
|
||||
taggedKind = 'mixin';
|
||||
tags.setTag('kind', taggedKind);
|
||||
|
||||
tags.addTag('refersto', refersto);
|
||||
|
||||
}
|
||||
|
||||
if (name && !taggedName) {
|
||||
tags.addTag('name', name);
|
||||
}
|
||||
|
||||
if ( isFile && !(name || taggedName) ) {
|
||||
tags.addTag('name', 'file:'+meta.file);
|
||||
}
|
||||
|
||||
if (kind && !taggedKind) {
|
||||
tags.addTag('kind', kind);
|
||||
}
|
||||
|
||||
if (memberof && !taggedMemberof) {
|
||||
tags.addTag('memberof', memberof);
|
||||
}
|
||||
}
|
||||
|
||||
// now that we have a doclet object we can do some final adjustments
|
||||
function postprocess(doclet) {
|
||||
var tags = doclet.tags;
|
||||
|
||||
for (var i = 0, leni = tags.length; i < leni; i++) {
|
||||
tagAbout = jsdoc.tagDictionary.lookUp(tags[i].name);
|
||||
|
||||
// class tags imply a constructor tag
|
||||
if (tags[i].name === 'class' && !doclet.hasTag('constructor') ) {
|
||||
tags.addTag('kind', 'constructor');
|
||||
}
|
||||
|
||||
// enums have a defualt type of number
|
||||
if (tags[i].name === 'enum') {
|
||||
if ( !doclet.hasTag('type') ) {
|
||||
tags.addTag('type', 'number');
|
||||
}
|
||||
}
|
||||
|
||||
if ( tagAbout.setsDocletType ) {
|
||||
if ( doclet.hasTag('type') ) {
|
||||
DocTagConflictError('Cannot set the type of a doclet more than once.')
|
||||
}
|
||||
var docletTypes = [];
|
||||
if (tags[i].type) {
|
||||
if (typeof tags[i].type === 'string') docletTypes = [tags[i].type];
|
||||
else docletTypes = tags[i].type;
|
||||
|
||||
for (var i = 0, leni = docletTypes.length; i < leni; i++) {
|
||||
tags.addTag('type', docletTypes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function DocTagConflictError(message) {
|
||||
this.name = 'DocTagConflictError';
|
||||
this.message = (message || '');
|
||||
}
|
||||
DocTagConflictError.prototype = Error.prototype;
|
||||
function split(docletSrc) {
|
||||
var tagSrcs = [];
|
||||
|
||||
// split out the basic tags, keep surrounding whitespace
|
||||
// like: @tagTitle tagBody
|
||||
docletSrc
|
||||
.replace(/^(\s*)@(\S)/gm, '$1\\@$2') // replace splitter ats with an arbitrary sequence
|
||||
.split('\\@') // then split on that arbitrary sequence
|
||||
.forEach(function($) {
|
||||
if ($) {
|
||||
parsedTag = $.match(/^(\S+)(:?\s+(\S[\s\S]*))?/);
|
||||
|
||||
if (parsedTag) {
|
||||
var [, tagTitle, tagText] = parsedTag;
|
||||
|
||||
if (tagTitle) {
|
||||
tagSrcs.push({
|
||||
title: tagTitle,
|
||||
text: tagText
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return tagSrcs;
|
||||
}
|
||||
|
||||
})();
|
||||
@ -1,13 +1,9 @@
|
||||
/**
|
||||
@overview Get or set options for this app.
|
||||
@module jsdoc/opts/parser
|
||||
@requires common/args
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
|
||||
/**
|
||||
@module jsdoc/opts
|
||||
@requires common/args
|
||||
*/
|
||||
(function() {
|
||||
var common = {
|
||||
args: require('common/args')
|
||||
@ -34,11 +30,11 @@
|
||||
|
||||
/**
|
||||
Set the options for this app.
|
||||
@method set
|
||||
@method parse
|
||||
@throws {Error} Illegal arguments will throw errors.
|
||||
@param {string|String[]} args The command line arguments for this app.
|
||||
*/
|
||||
exports.set = function(args) {
|
||||
exports.parse = function(args) {
|
||||
args = args || [];
|
||||
|
||||
if (typeof args === 'string' || args.constructor === String) {
|
||||
@ -54,7 +50,9 @@
|
||||
Display help message for options.
|
||||
@method help
|
||||
*/
|
||||
exports.help = function() { return argsParser.help(); }
|
||||
exports.help = function() {
|
||||
return argsParser.help();
|
||||
}
|
||||
|
||||
/**
|
||||
Get a single option or all the options for this app.
|
||||
@ -1,281 +0,0 @@
|
||||
(function() {
|
||||
var Token = Packages.org.mozilla.javascript.Token;
|
||||
|
||||
var jsdoc = {
|
||||
name: require('jsdoc/name'),
|
||||
doclet: require('jsdoc/doclet'),
|
||||
doclets: require('jsdoc/docset').doclets
|
||||
};
|
||||
|
||||
exports.result = jsdoc.doclets;
|
||||
|
||||
/**
|
||||
*/
|
||||
function visitNode(node) {
|
||||
var commentSrc = '',
|
||||
thisDoclet = null,
|
||||
thisDocletName = '',
|
||||
thisDocletPath = '';
|
||||
|
||||
// look for all comments that have names provided
|
||||
if (node.type === Token.SCRIPT && node.comments) {
|
||||
for each (var comment in node.comments.toArray()) {
|
||||
if (comment.commentType === Token.CommentType.JSDOC) {
|
||||
commentSrc = '' + comment.toSource();
|
||||
if (commentSrc) {
|
||||
thisDoclet = jsdoc.doclet.makeDoclet(commentSrc, comment, currentSourceName);
|
||||
|
||||
if ( thisDoclet.hasTag('name') && thisDoclet.hasTag('kind') ) {
|
||||
jsdoc.doclets.addDoclet(thisDoclet);
|
||||
if (thisDoclet.tagValue('kind') === 'module') {
|
||||
jsdoc.name.setCurrentModule( thisDoclet.tagValue('path') );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// use the nocode option to shortcut all the following blah blah
|
||||
if (app.opts.nocode) { return true; }
|
||||
|
||||
// like function foo() {}
|
||||
if (node.type == Token.FUNCTION && String(node.name) !== '') {
|
||||
commentSrc = (node.jsDoc)? String(node.jsDoc) : '';
|
||||
|
||||
if (commentSrc) {
|
||||
thisDoclet = jsdoc.doclet.makeDoclet(commentSrc, node, currentSourceName);
|
||||
thisDocletName = thisDoclet.tagValue('name');
|
||||
|
||||
if (!thisDoclet.hasTag('kind')) { // guess kind from the source code
|
||||
thisDoclet.addTag('kind', 'method')
|
||||
}
|
||||
|
||||
if (!thisDocletName) { // guess name from the source code
|
||||
nodeName = jsdoc.name.resolveInner(node.name, node, thisDoclet);
|
||||
thisDoclet.setName(nodeName);
|
||||
jsdoc.doclets.addDoclet(thisDoclet);
|
||||
}
|
||||
jsdoc.name.refs.push([node, thisDoclet]);
|
||||
}
|
||||
else { // an uncommented function?
|
||||
// this thing may have commented members, so keep a ref to the thing but don't add it to the doclets list
|
||||
thisDoclet = jsdoc.doclet.makeDoclet('[[undocumented]]', node, currentSourceName);
|
||||
|
||||
nodeName = jsdoc.name.resolvePath(node.name, node, thisDoclet);
|
||||
thisDoclet.setName(nodeName);
|
||||
jsdoc.name.refs.push([
|
||||
node,
|
||||
thisDoclet
|
||||
]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// like foo = function(){} or foo: function(){}
|
||||
if (node.type === Token.ASSIGN || node.type === Token.COLON) {
|
||||
|
||||
var nodeName = nodeToString(node.left),
|
||||
nodeKind = '';
|
||||
commentSrc = node.jsDoc || node.left.jsDoc;
|
||||
|
||||
if (commentSrc) {
|
||||
commentSrc = '' + commentSrc;
|
||||
|
||||
thisDoclet = jsdoc.doclet.makeDoclet(commentSrc, node, currentSourceName);
|
||||
thisDocletName = thisDoclet.tagValue('name');
|
||||
nodeKind = thisDoclet.tagValue('kind');
|
||||
|
||||
if (!thisDoclet.hasTag('kind')) { // guess kind from the source code
|
||||
if (node.right.type == Token.FUNCTION) { // assume it's a method
|
||||
thisDoclet.addTag('kind', 'method');
|
||||
}
|
||||
else {
|
||||
thisDoclet.addTag('kind', 'property');
|
||||
}
|
||||
}
|
||||
|
||||
if (!thisDocletName) { // guess name from the source code
|
||||
nodeName = jsdoc.name.resolvePath(nodeName, node, thisDoclet);
|
||||
|
||||
thisDoclet.setName(nodeName);
|
||||
jsdoc.doclets.addDoclet(thisDoclet);
|
||||
}
|
||||
jsdoc.name.refs.push([node.right, thisDoclet]);
|
||||
}
|
||||
else { // an uncommented objlit or anonymous function?
|
||||
|
||||
// this thing may have commented members, so keep a ref to the thing but don't add it to the doclets list
|
||||
|
||||
thisDoclet = jsdoc.doclet.makeDoclet('[[undocumented]]', node, currentSourceName);
|
||||
nodeName = jsdoc.name.resolvePath(nodeName, node, thisDoclet);
|
||||
|
||||
thisDoclet.setName(nodeName);
|
||||
jsdoc.name.refs.push([
|
||||
node.right,
|
||||
thisDoclet
|
||||
]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// like var foo = function(){} or var bar = {}
|
||||
if (node.type == Token.VAR || node.type == Token.LET || node.type == Token.CONST) {
|
||||
var counter = 0,
|
||||
nodeKind;
|
||||
|
||||
if (node.variables) for each (var n in node.variables.toArray()) {
|
||||
|
||||
if (n.target.type === Token.NAME) {
|
||||
var val = n.initializer;
|
||||
|
||||
commentSrc = (counter++ === 0 && !n.jsDoc)? node.jsDoc : n.jsDoc;
|
||||
if (commentSrc) {
|
||||
thisDoclet = jsdoc.doclet.makeDoclet('' + commentSrc, node, currentSourceName);
|
||||
thisDocletPath = thisDoclet.tagValue('path');
|
||||
thisDocletName = thisDoclet.tagValue('name');
|
||||
|
||||
if (!thisDoclet.hasTag('kind') && val) { // guess kind from the source code
|
||||
if (val.type == Token.FUNCTION) {
|
||||
thisDoclet.addTag('kind', 'method');
|
||||
}
|
||||
else {
|
||||
thisDoclet.addTag('kind', 'property');
|
||||
}
|
||||
}
|
||||
|
||||
if (!thisDocletName) {
|
||||
thisDocletName = n.target.string;
|
||||
if (!thisDocletPath) { // guess path from the source code
|
||||
thisDocletPath = jsdoc.name.resolveInner(thisDocletName, node, thisDoclet);
|
||||
thisDoclet.setName(thisDocletPath);
|
||||
}
|
||||
else {
|
||||
thisDoclet.setName(thisDocletName);
|
||||
}
|
||||
jsdoc.doclets.addDoclet(thisDoclet);
|
||||
}
|
||||
|
||||
if (val) { jsdoc.name.refs.push([val, thisDoclet]); }
|
||||
}
|
||||
else { // an uncommented objlit or anonymous function?
|
||||
var nodeName = nodeToString(n.target);
|
||||
// this thing may have commented members, so keep a ref to the thing but don't add it to the doclets list
|
||||
thisDoclet = jsdoc.doclet.makeDoclet('[[undocumented]]', n.target, currentSourceName);
|
||||
|
||||
nodeName = jsdoc.name.resolveInner(nodeName, n.target, thisDoclet);
|
||||
thisDoclet.setName(nodeName);
|
||||
|
||||
if (val) jsdoc.name.refs.push([val, thisDoclet]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
var currentSourceName = '';
|
||||
|
||||
/**
|
||||
*/
|
||||
exports.parseSource = function(source, sourceName) {
|
||||
currentSourceName = sourceName;
|
||||
var ast = getParser().parse(source, sourceName, 1);
|
||||
|
||||
ast.visit(
|
||||
new Packages.org.mozilla.javascript.ast.NodeVisitor({
|
||||
visit: visitNode
|
||||
})
|
||||
);
|
||||
|
||||
currentSourceName = '';
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
exports.parseFiles = function(sourceFiles, encoding) {
|
||||
var ast = getParser(),
|
||||
fs = require('common/fs'),
|
||||
source = '';
|
||||
|
||||
if (arguments.length === 0) {
|
||||
throw 'module:jsdoc/parser.parseFiles requires argument sourceFiles(none provided).';
|
||||
}
|
||||
|
||||
if (typeof sourceFiles === 'string') { sourceFiles = [sourceFiles]; }
|
||||
|
||||
for (i = 0, leni = sourceFiles.length; i < leni; i++) {
|
||||
try {
|
||||
source = fs.read(sourceFiles[i], encoding);
|
||||
}
|
||||
catch(e) {
|
||||
print('FILE READ ERROR: in module:jsdoc/parser.parseFiles: ' + e);
|
||||
continue;
|
||||
}
|
||||
|
||||
exports.parseSource(source, sourceFiles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@private
|
||||
@function getParser
|
||||
*/
|
||||
function getParser() {
|
||||
var cx = Packages.org.mozilla.javascript.Context.getCurrentContext();
|
||||
|
||||
var ce = new Packages.org.mozilla.javascript.CompilerEnvirons();
|
||||
ce.setRecordingComments(true);
|
||||
ce.setRecordingLocalJsDocComments(true);
|
||||
ce.initFromContext(cx);
|
||||
return new Packages.org.mozilla.javascript.Parser(ce, ce.getErrorReporter());
|
||||
}
|
||||
|
||||
/**
|
||||
@private
|
||||
@function nodeToString
|
||||
@param {org.mozilla.javascript.ast.AstNode} node
|
||||
@returns {string}
|
||||
*/
|
||||
// credit: ringojs ninjas
|
||||
function nodeToString(node) {
|
||||
var str;
|
||||
|
||||
if (node.type === Token.GETPROP) {
|
||||
str = [nodeToString(node.target), node.property.string].join('.');
|
||||
}
|
||||
else if (node.type === Token.NAME) {
|
||||
str = node.string;
|
||||
}
|
||||
else if (node.type === Token.STRING) {
|
||||
str = node.value;
|
||||
}
|
||||
else if (node.type === Token.THIS) {
|
||||
str = 'this';
|
||||
}
|
||||
else if (node.type === Token.GETELEM) {
|
||||
str = node.toSource(); // like: Foo['Bar']
|
||||
}
|
||||
else {
|
||||
str = getTypeName(node);
|
||||
}
|
||||
|
||||
return '' + str;
|
||||
};
|
||||
|
||||
/**
|
||||
@private
|
||||
@function getTypeName
|
||||
@param {org.mozilla.javascript.ast.AstNode} node
|
||||
@returns {string}
|
||||
*/
|
||||
// credit: ringojs ninjas
|
||||
function getTypeName(node) {
|
||||
return node ? ''+Packages.org.mozilla.javascript.Token.typeToName(node.getType()) : '' ;
|
||||
}
|
||||
|
||||
})();
|
||||
307
modules/jsdoc/src/parser.js
Normal file
307
modules/jsdoc/src/parser.js
Normal file
@ -0,0 +1,307 @@
|
||||
/**
|
||||
* @module jsdoc/src/parser
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var Token = Packages.org.mozilla.javascript.Token,
|
||||
Doclet = require('jsdoc/doclet').Doclet,
|
||||
_parseResult = [];
|
||||
|
||||
exports.result = function() {
|
||||
return _parseResult;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function visitNode(node) {
|
||||
var commentSrc = '',
|
||||
thisDoclet = null,
|
||||
thisDocletName = '',
|
||||
thisDocletPath = '';
|
||||
|
||||
// look for all comments that have names provided
|
||||
if (node.type === Token.SCRIPT && node.comments) {
|
||||
for each(var comment in node.comments.toArray()) {
|
||||
if (comment.commentType === Token.CommentType.JSDOC) {
|
||||
commentSrc = '' + comment.toSource();
|
||||
|
||||
if (commentSrc) {
|
||||
thisDoclet = new Doclet(commentSrc, node, currentSourceName);
|
||||
|
||||
if (thisDoclet) {
|
||||
_parseResult.push(thisDoclet);
|
||||
}
|
||||
|
||||
// if ( thisDoclet.hasTag('name') && thisDoclet.hasTag('kind') ) {
|
||||
// jsdoc.doclets.addDoclet(thisDoclet);
|
||||
// if (thisDoclet.tagValue('kind') === 'module') {
|
||||
// jsdoc.name.setCurrentModule( thisDoclet.tagValue('path') );
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// use the nocode option to shortcut all the following blah blah
|
||||
if (env.opts.nocode) { return true; }
|
||||
//
|
||||
// // like function foo() {}
|
||||
// if (node.type == Token.FUNCTION && String(node.name) !== '') {
|
||||
// commentSrc = (node.jsDoc)? String(node.jsDoc) : '';
|
||||
//
|
||||
// if (commentSrc) {
|
||||
// thisDoclet = jsdoc.doclet.makeDoclet(commentSrc, node, currentSourceName);
|
||||
// thisDocletName = thisDoclet.tagValue('name');
|
||||
//
|
||||
// if (!thisDoclet.hasTag('kind')) { // guess kind from the source code
|
||||
// thisDoclet.addTag('kind', 'method')
|
||||
// }
|
||||
//
|
||||
// if (!thisDocletName) { // guess name from the source code
|
||||
// nodeName = jsdoc.name.resolveInner(node.name, node, thisDoclet);
|
||||
// thisDoclet.setName(nodeName);
|
||||
// jsdoc.doclets.addDoclet(thisDoclet);
|
||||
// }
|
||||
// jsdoc.name.refs.push([node, thisDoclet]);
|
||||
// }
|
||||
// else { // an uncommented function?
|
||||
// // this thing may have commented members, so keep a ref to the thing but don't add it to the doclets list
|
||||
// thisDoclet = jsdoc.doclet.makeDoclet('[[undocumented]]', node, currentSourceName);
|
||||
//
|
||||
// nodeName = jsdoc.name.resolvePath(node.name, node, thisDoclet);
|
||||
// thisDoclet.setName(nodeName);
|
||||
// jsdoc.name.refs.push([
|
||||
// node,
|
||||
// thisDoclet
|
||||
// ]);
|
||||
// }
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// // like foo = function(){} or foo: function(){}
|
||||
// if (node.type === Token.ASSIGN || node.type === Token.COLON) {
|
||||
//
|
||||
// var nodeName = nodeToString(node.left),
|
||||
// nodeKind = '';
|
||||
// commentSrc = node.jsDoc || node.left.jsDoc;
|
||||
//
|
||||
// if (commentSrc) {
|
||||
// commentSrc = '' + commentSrc;
|
||||
//
|
||||
// thisDoclet = jsdoc.doclet.makeDoclet(commentSrc, node, currentSourceName);
|
||||
// thisDocletName = thisDoclet.tagValue('name');
|
||||
// nodeKind = thisDoclet.tagValue('kind');
|
||||
//
|
||||
// if (!thisDoclet.hasTag('kind')) { // guess kind from the source code
|
||||
// if (node.right.type == Token.FUNCTION) { // assume it's a method
|
||||
// thisDoclet.addTag('kind', 'method');
|
||||
// }
|
||||
// else {
|
||||
// thisDoclet.addTag('kind', 'property');
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (!thisDocletName) { // guess name from the source code
|
||||
// nodeName = jsdoc.name.resolvePath(nodeName, node, thisDoclet);
|
||||
//
|
||||
// thisDoclet.setName(nodeName);
|
||||
// jsdoc.doclets.addDoclet(thisDoclet);
|
||||
// }
|
||||
// jsdoc.name.refs.push([node.right, thisDoclet]);
|
||||
// }
|
||||
// else { // an uncommented objlit or anonymous function?
|
||||
//
|
||||
// // this thing may have commented members, so keep a ref to the thing but don't add it to the doclets list
|
||||
//
|
||||
// thisDoclet = jsdoc.doclet.makeDoclet('[[undocumented]]', node, currentSourceName);
|
||||
// nodeName = jsdoc.name.resolvePath(nodeName, node, thisDoclet);
|
||||
//
|
||||
// thisDoclet.setName(nodeName);
|
||||
// jsdoc.name.refs.push([
|
||||
// node.right,
|
||||
// thisDoclet
|
||||
// ]);
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// // like var foo = function(){} or var bar = {}
|
||||
// if (node.type == Token.VAR || node.type == Token.LET || node.type == Token.CONST) {
|
||||
// var counter = 0,
|
||||
// nodeKind;
|
||||
//
|
||||
// if (node.variables) for each (var n in node.variables.toArray()) {
|
||||
//
|
||||
// if (n.target.type === Token.NAME) {
|
||||
// var val = n.initializer;
|
||||
//
|
||||
// commentSrc = (counter++ === 0 && !n.jsDoc)? node.jsDoc : n.jsDoc;
|
||||
// if (commentSrc) {
|
||||
// thisDoclet = jsdoc.doclet.makeDoclet('' + commentSrc, node, currentSourceName);
|
||||
// thisDocletPath = thisDoclet.tagValue('path');
|
||||
// thisDocletName = thisDoclet.tagValue('name');
|
||||
//
|
||||
// if (!thisDoclet.hasTag('kind') && val) { // guess kind from the source code
|
||||
// if (val.type == Token.FUNCTION) {
|
||||
// thisDoclet.addTag('kind', 'method');
|
||||
// }
|
||||
// else {
|
||||
// thisDoclet.addTag('kind', 'property');
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (!thisDocletName) {
|
||||
// thisDocletName = n.target.string;
|
||||
// if (!thisDocletPath) { // guess path from the source code
|
||||
// thisDocletPath = jsdoc.name.resolveInner(thisDocletName, node, thisDoclet);
|
||||
// thisDoclet.setName(thisDocletPath);
|
||||
// }
|
||||
// else {
|
||||
// thisDoclet.setName(thisDocletName);
|
||||
// }
|
||||
// jsdoc.doclets.addDoclet(thisDoclet);
|
||||
// }
|
||||
//
|
||||
// if (val) { jsdoc.name.refs.push([val, thisDoclet]); }
|
||||
// }
|
||||
// else { // an uncommented objlit or anonymous function?
|
||||
// var nodeName = nodeToString(n.target);
|
||||
// // this thing may have commented members, so keep a ref to the thing but don't add it to the doclets list
|
||||
// thisDoclet = jsdoc.doclet.makeDoclet('[[undocumented]]', n.target, currentSourceName);
|
||||
//
|
||||
// nodeName = jsdoc.name.resolveInner(nodeName, n.target, thisDoclet);
|
||||
// thisDoclet.setName(nodeName);
|
||||
//
|
||||
// if (val) jsdoc.name.refs.push([val, thisDoclet]);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
return true;
|
||||
}
|
||||
|
||||
var currentSourceName = '';
|
||||
|
||||
/**
|
||||
*/
|
||||
exports.parseSource = function(source, sourceName) {
|
||||
currentSourceName = sourceName;
|
||||
var ast = getParser().parse(source, sourceName, 1);
|
||||
|
||||
ast.visit(
|
||||
new Packages.org.mozilla.javascript.ast.NodeVisitor({
|
||||
visit: visitNode
|
||||
})
|
||||
);
|
||||
|
||||
currentSourceName = '';
|
||||
|
||||
return _parseResult;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
exports.clear = function() {
|
||||
_parseResult = [];
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
exports.parse = function(sourceFiles, encoding) {
|
||||
var ast = getParser(),
|
||||
fs = require('common/fs'),
|
||||
sourceCode = '',
|
||||
filename = '',
|
||||
jsUriScheme = 'javascript:';
|
||||
|
||||
if (arguments.length === 0) {
|
||||
throw 'module:jsdoc/parser.parseFiles requires argument sourceFiles(none provided).';
|
||||
}
|
||||
|
||||
if (typeof sourceFiles === 'string') { sourceFiles = [sourceFiles]; }
|
||||
|
||||
for (i = 0, leni = sourceFiles.length; i < leni; i++) {
|
||||
if (sourceFiles[i].indexOf(jsUriScheme) === 0) {
|
||||
sourceCode = sourceFiles[i].substr(jsUriScheme.length);
|
||||
filename = '[[string' + i + ']]';
|
||||
}
|
||||
else {
|
||||
filename = sourceFiles[i];
|
||||
try {
|
||||
sourceCode = fs.read(filename, encoding);
|
||||
}
|
||||
catch(e) {
|
||||
print('FILE READ ERROR: in module:jsdoc/parser.parseFiles: "' + filename + '" ' + e);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
exports.parseSource(sourceCode, filename);
|
||||
}
|
||||
|
||||
return _parseResult;
|
||||
}
|
||||
|
||||
/**
|
||||
@private
|
||||
@function getParser
|
||||
*/
|
||||
function getParser() {
|
||||
var cx = Packages.org.mozilla.javascript.Context.getCurrentContext();
|
||||
|
||||
var ce = new Packages.org.mozilla.javascript.CompilerEnvirons();
|
||||
ce.setRecordingComments(true);
|
||||
ce.setRecordingLocalJsDocComments(true);
|
||||
ce.initFromContext(cx);
|
||||
return new Packages.org.mozilla.javascript.Parser(ce, ce.getErrorReporter());
|
||||
}
|
||||
|
||||
/**
|
||||
@private
|
||||
@function nodeToString
|
||||
@param {org.mozilla.javascript.ast.AstNode} node
|
||||
@returns {string}
|
||||
*/
|
||||
// credit: ringojs ninjas
|
||||
function nodeToString(node) {
|
||||
var str;
|
||||
|
||||
if (node.type === Token.GETPROP) {
|
||||
str = [nodeToString(node.target), node.property.string].join('.');
|
||||
}
|
||||
else if (node.type === Token.NAME) {
|
||||
str = node.string;
|
||||
}
|
||||
else if (node.type === Token.STRING) {
|
||||
str = node.value;
|
||||
}
|
||||
else if (node.type === Token.THIS) {
|
||||
str = 'this';
|
||||
}
|
||||
else if (node.type === Token.GETELEM) {
|
||||
str = node.toSource(); // like: Foo['Bar']
|
||||
}
|
||||
else {
|
||||
str = getTypeName(node);
|
||||
}
|
||||
|
||||
return '' + str;
|
||||
};
|
||||
|
||||
/**
|
||||
@private
|
||||
@function getTypeName
|
||||
@param {org.mozilla.javascript.ast.AstNode} node
|
||||
@returns {string}
|
||||
*/
|
||||
// credit: ringojs ninjas
|
||||
function getTypeName(node) {
|
||||
return node ? ''+Packages.org.mozilla.javascript.Token.typeToName(node.getType()) : '' ;
|
||||
}
|
||||
|
||||
})();
|
||||
@ -1,12 +1,9 @@
|
||||
/**
|
||||
@file Find source files to be parsed for docs.
|
||||
@module jsdoc/src/scanner
|
||||
@requires module:common/fs
|
||||
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
|
||||
/**
|
||||
@module jsdoc/src
|
||||
@requires module:common/fs
|
||||
*/
|
||||
|
||||
(function() {
|
||||
@ -19,7 +16,7 @@
|
||||
@param {Array.<string>} searchPaths
|
||||
@param {number} [depth=1]
|
||||
*/
|
||||
exports.getFilePaths = function(searchPaths, depth) {
|
||||
exports.scan = function(searchPaths, depth) {
|
||||
var filePaths = [];
|
||||
|
||||
searchPaths = searchPaths || [];
|
||||
@ -1,215 +1,108 @@
|
||||
/**
|
||||
@overview
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
|
||||
/**
|
||||
Create tag objects.
|
||||
@module jsdoc/tag
|
||||
*/
|
||||
(function() {
|
||||
var jsdoc = {
|
||||
type: require('jsdoc/type'),
|
||||
tagDictionary: require('jsdoc/tagdictionary')
|
||||
};
|
||||
|
||||
exports.fromText = function(tagText) {
|
||||
var tag = new Tag(tagText);
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
@private
|
||||
@constructor module:jsdoc/tag.Tag
|
||||
@param {string} tagText
|
||||
*/
|
||||
function Tag(tagText) {
|
||||
/** @property {string} - The raw text of this tag, include everything after the @. */
|
||||
this.raw = tagText;
|
||||
|
||||
/** @property {string} - The name of this tag, the word adjacent to the @. */
|
||||
this.name = '';
|
||||
|
||||
/** @property {Array} - Zero or more type specifiers. */
|
||||
this.type = [];
|
||||
|
||||
/** @property {*} - The value of this tag. */
|
||||
this.value = null;
|
||||
|
||||
/** @property {string} - If this is a long tag, then this will be the parameter name. */
|
||||
this.pname = '';
|
||||
|
||||
/** @property {string} - If this is a long tag, then this will be the parameter description. */
|
||||
this.pdesc = '';
|
||||
|
||||
// raw is like: "tagname andsometagtext"
|
||||
var parts = this.raw.match(/^\s*(\S+)(?:\s([\s\S]*))?$/);
|
||||
|
||||
if (parts) {
|
||||
this.name = (parts[1] || '').toLowerCase(); // like @name
|
||||
this.name = jsdoc.tagDictionary.resolveSynonyms(this.name);
|
||||
|
||||
tagText = parts[2] || ''; // all the rest of the tag
|
||||
|
||||
// now that we know who you are, tell us a little about yourself...
|
||||
var tagAbout = jsdoc.tagDictionary.lookUp(this.name);
|
||||
|
||||
if (!tagAbout.keepsWhitespace) {
|
||||
tagText = trim(tagText);
|
||||
}
|
||||
this.value = tagText;
|
||||
|
||||
if (tagAbout.canHaveType) {
|
||||
var [
|
||||
/*Array.<string>*/ type,
|
||||
/*any*/ value,
|
||||
/*?boolean*/ optional,
|
||||
/*?boolean*/ nullable
|
||||
] = jsdoc.type.parse(this.value);
|
||||
|
||||
if (type && type.length) { this.type = type; }
|
||||
|
||||
// @type tags are special: their type *is* their value
|
||||
if (tagAbout.typeIsValue) {
|
||||
value = (this.type[0] === '')? this.value.split(/\s*\|\s*/g) : this.type;
|
||||
if (value.length === 1) value = value[0]; // single values don't need to be arrays
|
||||
this.type = [];
|
||||
}
|
||||
|
||||
if (typeof value !== 'undefined') { this.value = value; }
|
||||
if (optional !== null) { this.poptional = optional; }
|
||||
if (nullable !== null) { this.pnullable = nullable; }
|
||||
}
|
||||
|
||||
if (tagAbout.canHavePname && tagAbout.canHavePdesc) { // both
|
||||
if (typeof this.value === 'string') {
|
||||
var [pname, pdesc, poptional, pdefault] = parsePname(this.value);
|
||||
if (pname && pname !== '-') this.pname = pname;
|
||||
this.pdesc = pdesc;
|
||||
if (typeof poptional !== 'undefined') this.poptional = poptional;
|
||||
this.pdefault = pdefault;
|
||||
}
|
||||
}
|
||||
else if (tagAbout.canHavePname) { // only
|
||||
this.pname = String(this.value);
|
||||
}
|
||||
else if (tagAbout.canHavePdesc) { // only
|
||||
this.pdesc = String(this.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@param {string|Tag} tagOrTagName
|
||||
@param {*} [tagValue]
|
||||
*/
|
||||
function addTag(tagName, tagValue) {
|
||||
var tag;
|
||||
if (tagName.name) {
|
||||
tag = tagName;
|
||||
tagName = tagName.name;
|
||||
}
|
||||
|
||||
var tagAbout = jsdoc.tagDictionary.lookUp(tagName);
|
||||
if (tagAbout.isScalar && this.hasTag(tagName)) {
|
||||
return false;
|
||||
}
|
||||
if (typeof tagValue === 'undefined') {
|
||||
// TODO this could obviously be more efficient
|
||||
this[this.length] = tag || exports.fromText(tagName);
|
||||
}
|
||||
else {
|
||||
this[this.length] = tag || exports.fromText(tagName + ' ' + tagValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function hasTag(tagName, tagValue) {
|
||||
var i = this.length;
|
||||
while(i--) {
|
||||
if (this[i].name === tagName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function setTag(tagName, tagValue) {
|
||||
var i = this.length;
|
||||
while(i--) {
|
||||
if (this[i].name === tagName) {
|
||||
this[i].value = tagValue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
this.addTag(tagName, tagValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
Given the source of a jsdoc comment, finds the tags.
|
||||
@private
|
||||
@function parse
|
||||
@param {string} commentSrc Unwrapped raw source of the doc comment.
|
||||
@returns {Array.<module:jsdoc/tag.Tag>}
|
||||
*/
|
||||
exports.parse = function(commentSrc) {
|
||||
var tags = [];
|
||||
tags.addTag = addTag;
|
||||
tags.hasTag = hasTag;
|
||||
tags.setTag = setTag;
|
||||
|
||||
// split out the basic tags, keep surrounding whitespace
|
||||
commentSrc
|
||||
.replace(/^(\s*)@(\S)/gm, '$1\\@$2') // replace splitter ats with an arbitrary sequence (unicode_recordseperator+@)
|
||||
.split('\\@') // then split on that arbitrary sequence
|
||||
.forEach(function($) {
|
||||
var newTag = exports.fromText($);
|
||||
|
||||
if (newTag.name) { tags.addTag(newTag); }
|
||||
});
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
Tag.prototype.toString = function() {
|
||||
return '@'+this.raw;
|
||||
}
|
||||
|
||||
/**
|
||||
Parse the parameter name and parameter desc from the tag text.
|
||||
@private
|
||||
@method parsePname
|
||||
@param {string} tagText
|
||||
@returns {Array.<string, string, boolean, boolean>} [pname, pdesc, poptional, pdefault].
|
||||
*/
|
||||
function parsePname(tagText) {
|
||||
var pname, pdesc, poptional, pdefault;
|
||||
|
||||
// like: pname, pname pdesc, or name - pdesc
|
||||
tagText.match(/^(\[[^\]]+\]|\S+)((?:\s*\-\s*|\s+)(\S[\s\S]*))?$/);
|
||||
pname = RegExp.$1;
|
||||
pdesc = RegExp.$3;
|
||||
|
||||
if ( /^\[\s*(.+?)\s*\]$/.test(pname) ) {
|
||||
pname = RegExp.$1;
|
||||
poptional = true;
|
||||
|
||||
if ( /^(.+?)\s*=\s*(.+)$/.test(pname) ) {
|
||||
pname = RegExp.$1;
|
||||
pdefault = RegExp.$2;
|
||||
}
|
||||
}
|
||||
return [pname, pdesc, poptional, pdefault];
|
||||
}
|
||||
|
||||
//TODO: move into a shared module?
|
||||
/** @private */
|
||||
function trim(text) {
|
||||
if (!text) { return ''; }
|
||||
return text.replace(/^\s+|\s+$/g, '');
|
||||
}
|
||||
|
||||
/**
|
||||
@module jsdoc/tag
|
||||
@requires jsdoc/tag/dictionary
|
||||
@requires jsdoc/tag/validator
|
||||
@requires jsdoc/tag/type
|
||||
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
(function() {
|
||||
|
||||
var dictionary = require('jsdoc/tag/dictionary'),
|
||||
validator = require('jsdoc/tag/validator'),
|
||||
tagType = require('jsdoc/tag/type');
|
||||
|
||||
/**
|
||||
@constructor Tag
|
||||
*/
|
||||
exports.Tag = function(tagTitle, tagBody, meta) {
|
||||
var tagDef = dictionary.lookUp(tagTitle),
|
||||
meta = meta || {};
|
||||
|
||||
this.title = dictionary.normalise( trim(tagTitle) );
|
||||
this.text = trim(tagBody, tagDef.preservesWhitespace);
|
||||
|
||||
if (this.text) {
|
||||
if (tagDef.canHaveType) {
|
||||
this.value = {};
|
||||
|
||||
var [
|
||||
/*Array.<string>*/ typeNames,
|
||||
/*any*/ remainingText,
|
||||
/*?boolean*/ optional,
|
||||
/*?boolean*/ nullable,
|
||||
/*?boolean*/ variable
|
||||
] = tagType.parse(this.text);
|
||||
|
||||
|
||||
|
||||
if (typeNames.length) {
|
||||
this.value.type = {
|
||||
names: typeNames,
|
||||
optional: optional,
|
||||
nullable: nullable,
|
||||
variable: variable
|
||||
};
|
||||
}
|
||||
if (remainingText) {
|
||||
if (tagDef.canHaveName) {
|
||||
var [tagName, tagDesc, tagOptional, tagDefault] = parseTagText(remainingText);
|
||||
|
||||
if (tagName) { this.value.name = tagName; }
|
||||
if (tagDesc) { this.value.description = tagDesc; }
|
||||
if (tagOptional) { this.value.optional = tagOptional; }
|
||||
if (tagDefault) { this.value.defaultValue = tagDefault; }
|
||||
}
|
||||
else {
|
||||
this.value.description = remainingText;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.value = this.text;
|
||||
}
|
||||
}
|
||||
|
||||
validator.validate(this, meta);
|
||||
}
|
||||
|
||||
function trim(text, newlines) {
|
||||
if (!text) { return ''; }
|
||||
|
||||
if (newlines) {
|
||||
return text.replace(/^[\n\r\f]+|[\n\r\f]+$/g, '');
|
||||
}
|
||||
else {
|
||||
return text.replace(/^\s+|\s+$/g, '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Parse the parameter name and parameter desc from the tag text.
|
||||
@private
|
||||
@method parseTagText
|
||||
@param {string} tagText
|
||||
@returns {Array.<string, string, boolean, boolean>} [pname, pdesc, poptional, pdefault].
|
||||
*/
|
||||
function parseTagText(tagText) {
|
||||
var pname, pdesc, poptional, pdefault;
|
||||
|
||||
// like: pname, pname pdesc, or name - pdesc
|
||||
tagText.match(/^(\[[^\]]+\]|\S+)((?:\s*\-\s*|\s+)(\S[\s\S]*))?$/);
|
||||
pname = RegExp.$1;
|
||||
pdesc = RegExp.$3;
|
||||
|
||||
if ( /^\[\s*(.+?)\s*\]$/.test(pname) ) {
|
||||
pname = RegExp.$1;
|
||||
poptional = true;
|
||||
|
||||
if ( /^(.+?)\s*=\s*(.+)$/.test(pname) ) {
|
||||
pname = RegExp.$1;
|
||||
pdefault = RegExp.$2;
|
||||
}
|
||||
}
|
||||
return [pname, pdesc, poptional, pdefault];
|
||||
}
|
||||
|
||||
})();
|
||||
57
modules/jsdoc/tag/dictionary.js
Normal file
57
modules/jsdoc/tag/dictionary.js
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
@module jsdoc/tag/dictionary
|
||||
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
(function() {
|
||||
var _synonyms = {},
|
||||
_definitions = {};
|
||||
|
||||
/** @constructor */
|
||||
function TagDefinition(title, etc) {
|
||||
etc = etc || {};
|
||||
|
||||
this.title = exports.normalise(title);
|
||||
|
||||
for (var p in etc) {
|
||||
if (etc.hasOwnProperty(p)) {
|
||||
this[p] = etc[p];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.defineTag = function(title, opts) {
|
||||
_definitions[title] = new TagDefinition(title, opts);
|
||||
}
|
||||
|
||||
exports.lookUp = function(title) {
|
||||
title = exports.normalise(title);
|
||||
|
||||
if ( _definitions.hasOwnProperty(title) ) {
|
||||
return _definitions[title];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
exports.defineSynonym = function(canonicalName, synonymName /*...*/) {
|
||||
var canonicalName = canonicalName.toLowerCase()
|
||||
for (var i = 1, leni = arguments.length; i < leni; i++) {
|
||||
_synonyms[arguments[i].toLowerCase()] = canonicalName;
|
||||
}
|
||||
}
|
||||
|
||||
exports.normalise = function(title) {
|
||||
canonicalName = title.toLowerCase();
|
||||
|
||||
if ( _synonyms.hasOwnProperty(canonicalName) ) {
|
||||
return _synonyms[canonicalName];
|
||||
}
|
||||
|
||||
return canonicalName;
|
||||
}
|
||||
|
||||
require('jsdoc/tag/dictionary/definitions').defineTags(exports)
|
||||
|
||||
})();
|
||||
106
modules/jsdoc/tag/dictionary/definitions.js
Normal file
106
modules/jsdoc/tag/dictionary/definitions.js
Normal file
@ -0,0 +1,106 @@
|
||||
/**
|
||||
Define tags that are known in JSDoc.
|
||||
@module jsdoc/tag/dictionary/definitions
|
||||
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
(function() {
|
||||
exports.defineTags = function(dictionary) {
|
||||
|
||||
dictionary.defineTag('class', {
|
||||
onTagged: function(doclet, tag) { // @class implies @constructor
|
||||
doclet.addTag('kind', 'constructor');
|
||||
}
|
||||
});
|
||||
|
||||
dictionary.defineTag('constructor', {
|
||||
onTagged: function(doclet, tag) {
|
||||
setDocletKindToTitle(doclet, tag);
|
||||
setDocletNameToValue(doclet, tag);
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
dictionary.defineSynonym('description', 'desc');
|
||||
dictionary.defineTag('description', {
|
||||
mustHaveValue: true
|
||||
});
|
||||
|
||||
dictionary.defineTag('event', {
|
||||
onTagged: function(doclet, tag) {
|
||||
setDocletKindToTitle(doclet, tag);
|
||||
setDocletNameToValue(doclet, tag);
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
dictionary.defineTag('example', {
|
||||
preservesWhitespace: true,
|
||||
mustHaveValue: true
|
||||
});
|
||||
|
||||
dictionary.defineTag('fires', {
|
||||
mustHaveValue: true
|
||||
});
|
||||
|
||||
dictionary.defineSynonym('function', 'method');
|
||||
dictionary.defineTag('function', {
|
||||
onTagged: function(doclet, tag) {
|
||||
setDocletKindToTitle(doclet, tag);
|
||||
setDocletNameToValue(doclet, tag);
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
dictionary.defineTag('kind', {
|
||||
mustHaveValue: true
|
||||
});
|
||||
|
||||
dictionary.defineTag('name', {
|
||||
mustHaveValue: true
|
||||
});
|
||||
|
||||
dictionary.defineTag('param', {
|
||||
mustHaveValue: true,
|
||||
canHaveType: true,
|
||||
canHaveName: true
|
||||
});
|
||||
|
||||
dictionary.defineTag('private', {
|
||||
mustNotHaveValue: true
|
||||
});
|
||||
|
||||
dictionary.defineSynonym('returns', 'return');
|
||||
dictionary.defineTag('returns', {
|
||||
mustHaveValue: true,
|
||||
canHaveType: true
|
||||
});
|
||||
|
||||
dictionary.defineTag('uri', {
|
||||
mustHaveValue: true
|
||||
});
|
||||
|
||||
dictionary.defineTag('var', {
|
||||
onTagged: function(doclet, tag) {
|
||||
setDocletKindToTitle(doclet, tag);
|
||||
setDocletNameToValue(doclet, tag);
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** @private */
|
||||
function setDocletKindToTitle(doclet, tag) {
|
||||
doclet.addTag( 'kind', tag.title );
|
||||
}
|
||||
|
||||
function setDocletNameToValue(doclet, tag) {
|
||||
doclet.addTag( 'name', tag.text );
|
||||
}
|
||||
|
||||
})();
|
||||
@ -1,13 +1,10 @@
|
||||
/**
|
||||
@overview
|
||||
@module jsdoc/tag/type
|
||||
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
|
||||
/**
|
||||
Parse type expressions.
|
||||
@module jsdoc/type
|
||||
*/
|
||||
(function() {
|
||||
|
||||
/**
|
||||
@ -18,7 +15,10 @@
|
||||
if (typeof tagValue !== 'string') { tagValue = ''; }
|
||||
var type = '',
|
||||
text = '',
|
||||
count = 0;
|
||||
count = 0,
|
||||
optional,
|
||||
nullable,
|
||||
variable;
|
||||
|
||||
// type expressions start with '{'
|
||||
if (tagValue[0] === '{') {
|
||||
@ -26,11 +26,15 @@
|
||||
|
||||
// find matching closer '}'
|
||||
for (var i = 1, leni = tagValue.length; i < leni; i++) {
|
||||
if (tagValue[i] === '\\') { i++; continue; } // backslash escapes the next character
|
||||
|
||||
if (tagValue[i] === '{') { count++; }
|
||||
else if (tagValue[i] === '}') { count--; }
|
||||
|
||||
|
||||
if (count === 0) {
|
||||
type = trim(tagValue.slice(1, i));
|
||||
type = trim(tagValue.slice(1, i))
|
||||
.replace(/\\\{/g, '{') // unescape escaped curly braces
|
||||
.replace(/\\\}/g, '}');
|
||||
text = trim(tagValue.slice(i+1));
|
||||
break;
|
||||
}
|
||||
@ -41,10 +45,11 @@
|
||||
|
||||
[type, optional] = parseOptional(type);
|
||||
[type, nullable] = parseNullable(type);
|
||||
[type, variable] = parseVariable(type);
|
||||
|
||||
type = parseTypes(type); // make it into an array
|
||||
|
||||
return [type, text, optional, nullable];
|
||||
return [type, text, optional, nullable, variable];
|
||||
}
|
||||
|
||||
function parseOptional(type) {
|
||||
@ -71,17 +76,30 @@
|
||||
return [type, nullable];
|
||||
}
|
||||
|
||||
function parseVariable(type) {
|
||||
var variable = null;
|
||||
|
||||
// {...sometype} means variable number of that type
|
||||
if ( /^(\.\.\.)(.+)$/.test(type) ) {
|
||||
type = RegExp.$2;
|
||||
variable = true;
|
||||
}
|
||||
|
||||
return [type, variable];
|
||||
}
|
||||
|
||||
function parseTypes(type) {
|
||||
var types = [];
|
||||
|
||||
if (type.indexOf('|') > -1) {
|
||||
// remove optional parens
|
||||
if ( ~type.indexOf('|') ) {
|
||||
// remove optional parens, like: { ( string | number ) }
|
||||
// see: http://code.google.com/closure/compiler/docs/js-for-compiler.html#types
|
||||
if ( /^\s*\(\s*(.+)\s*\)\s*$/.test(type) ) {
|
||||
type = RegExp.$1;
|
||||
}
|
||||
types = type.split(/\s*\|\s*/g);
|
||||
}
|
||||
else {
|
||||
else if (type) {
|
||||
types = [type];
|
||||
}
|
||||
|
||||
52
modules/jsdoc/tag/validator.js
Normal file
52
modules/jsdoc/tag/validator.js
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
@module jsdoc/tag/validator
|
||||
@requires jsdoc/tag/dictionary
|
||||
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
@license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
(function() {
|
||||
|
||||
var dictionary = require('jsdoc/tag/dictionary');
|
||||
|
||||
/**
|
||||
@constructor
|
||||
*/
|
||||
exports.validate = function(tag, meta) {
|
||||
var tagDef = dictionary.lookUp(tag.title);
|
||||
|
||||
if (!tagDef && !env.conf.permitUnknownTags) {
|
||||
throw new UnknownTagError(tag.title, meta);
|
||||
}
|
||||
|
||||
if (!tag.text) {
|
||||
if (tagDef.mustHaveValue) {
|
||||
throw new TagValueRequiredError(tag.title, tag.text, meta);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tagDef.mustNotHaveValue) {
|
||||
throw new TagValueNotPermittedError(tag.title, tag.text, meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function UnknownTagError(tagName, meta) {
|
||||
this.name = 'UnknownTagError';
|
||||
this.message = '@' + tagName + ' is not a known tag. In file: ' + meta.file;
|
||||
}
|
||||
UnknownTagError.prototype = Error.prototype;
|
||||
|
||||
function TagValueRequiredError(tagName, meta) {
|
||||
this.name = 'TagValueRequiredError';
|
||||
this.message = '@' + tagName + ' requires a value. In file: ' + meta.file;
|
||||
}
|
||||
TagValueRequiredError.prototype = Error.prototype;
|
||||
|
||||
function TagValueNotPermittedError(tagName, message, meta) {
|
||||
this.name = 'TagValueNotPermittedError';
|
||||
this.message = '@' + tagName + ' does not permit a value: "' + message + '". In file: ' + meta.file;
|
||||
}
|
||||
TagValueNotPermittedError.prototype = Error.prototype;
|
||||
|
||||
})();
|
||||
@ -1,107 +1,28 @@
|
||||
(function() {
|
||||
|
||||
//// include your template engine of choice
|
||||
/**
|
||||
Apply template formatting to some data.
|
||||
@function tmpl
|
||||
@param {string} templateFilepath
|
||||
@param {Object} data
|
||||
@return {string}
|
||||
*/
|
||||
load(BASEDIR + '/templates/lib/resig/tmpl.js');
|
||||
include('templates/lib/janl/mustache.js');
|
||||
|
||||
//// define a global publish function, will be called by JSDoc
|
||||
/**
|
||||
Generate the output from the documentation data collected by JSDoc.
|
||||
@function publish
|
||||
@param {module:jsdoc/docset.doclets} docs
|
||||
@param {Object} opts
|
||||
*/
|
||||
publish = function(docs, opts) {
|
||||
/**
|
||||
Turn JSDOC {@link}s into usable HTML links.
|
||||
@ignore For internal use only.
|
||||
@function linkify
|
||||
@param {string} text Containing {@link}s presumably.
|
||||
@return {string} The text with <A HREF> tags instead.
|
||||
*/
|
||||
function linkify(text) {
|
||||
if (typeof text === 'string') {
|
||||
return text.replace(/\{@link\s+(.+?)(:? (.+?))?\}/gi, function(str, p1, p2, offset, s) {
|
||||
return "<a href='?doc=" + docpathToUri(p1) + "'>" + (p2 || p1) + '</a>';
|
||||
});
|
||||
}
|
||||
}
|
||||
publish = function(docs, opts) {
|
||||
var out = '',
|
||||
template = readFile(BASEDIR + 'templates/default/tmpl/index.html');
|
||||
|
||||
var summarize = function () {
|
||||
return function(text, render) {
|
||||
text = render(text);
|
||||
/^(.*?(\.|\n|\r|$))/.test(text);
|
||||
return RegExp.$1;
|
||||
}
|
||||
};
|
||||
|
||||
function getDoc(docpath) {
|
||||
var i = docs.doc.length;
|
||||
while (i--) {
|
||||
if (docs.doc[i].path === docpath) {
|
||||
return docs.doc[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function docpathToUri(docpath) {
|
||||
var page, doc, uri;
|
||||
if (uri = docpathToUri.cache[docpath]) { return uri; }
|
||||
|
||||
doc = getDoc(docpath);
|
||||
if (doc && doc.memberof) {
|
||||
//print('=doc.memberof is '+doc.memberof);
|
||||
uri = 'doc' + makeFileNameSafe(doc.memberof)+'.html#'+doc.name;
|
||||
}
|
||||
else {
|
||||
//print('~doc.path is '+doc.path);
|
||||
uri = 'doc' + makeFileNameSafe(doc.path)+'.html';
|
||||
}
|
||||
|
||||
return uri;
|
||||
}
|
||||
docpathToUri.cache = {};
|
||||
|
||||
function makeFileNameSafe(docpath) {
|
||||
return hash(docpath);
|
||||
}
|
||||
makeFileNameSafe.id = 0;
|
||||
|
||||
function hash(str) {
|
||||
//if ( typeof(hash.crc) === 'undefined' ) {
|
||||
hash.crc = 0;
|
||||
//}
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
|
||||
hash.crc = hash.crc ^ (-1);
|
||||
for( var i = 0, iTop = str.length; i < iTop; i++ ) {
|
||||
y = ( hash.crc ^ str.charCodeAt( i ) ) & 0xFF;
|
||||
x = '0x' + hash.table.substr( y * 9, 8 );
|
||||
hash.crc = ( hash.crc >>> 8 ) ^ x;
|
||||
}
|
||||
|
||||
return hash.crc ^ (-1);
|
||||
}
|
||||
hash.table = "00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D";
|
||||
|
||||
// turn symbol paths into anchors
|
||||
docs.doc.filter(function($) {
|
||||
$.desc = linkify($.desc);
|
||||
});
|
||||
|
||||
var template = BASEDIR + '/templates/default/tmpl/index.html';
|
||||
print( tmpl(template, docs) );
|
||||
}
|
||||
|
||||
//// export some utilities to the template
|
||||
/**
|
||||
Return the first line of the given description text.
|
||||
@method tmpl.summarize
|
||||
@param {string} desc
|
||||
@return {string}
|
||||
*/
|
||||
tmpl.summarize = function(desc) {
|
||||
return /(.*)/.test(desc), RegExp.$1;
|
||||
}
|
||||
out = Mustache.to_html(
|
||||
template,
|
||||
{
|
||||
docs: docs,
|
||||
summarize: summarize
|
||||
}
|
||||
);
|
||||
|
||||
print(out);
|
||||
}
|
||||
|
||||
})();
|
||||
@ -3,39 +3,19 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc Index</title>
|
||||
|
||||
<script type="text/javascript">
|
||||
route = function() {
|
||||
var url, q = location.search.slice(1);
|
||||
if ( /^doc=(.+)/.test(q) ) {
|
||||
q = decodeURIComponent(RegExp.$1);
|
||||
if ( (url = route.resolve(q)) ) { window.location = url; }
|
||||
}
|
||||
}
|
||||
|
||||
route.resolve = function(q) {
|
||||
if ( route.map.hasOwnProperty(q) ) { return route.map[q]; }
|
||||
}
|
||||
|
||||
route.map = {
|
||||
/* docpath => url */
|
||||
}
|
||||
|
||||
route();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>All Symbols</h1>
|
||||
|
||||
<% if (doc.length) { %>
|
||||
<ul>
|
||||
<% for ( var i = 0; i < doc.length; i++ ) { %>
|
||||
<li class="symbol"><i>{<%= doc[i].kind %>}</i> <%= doc[i].path %> - <%= tmpl.summarize(doc[i].desc) %></li>
|
||||
<% } %>
|
||||
{{#docs}}
|
||||
<li class="symbol">
|
||||
<i>{{kind}}</i> {{name}}{{#description}} - {{#summarize}}{{description}}{{/summarize}}{{/description}}
|
||||
</li>
|
||||
{{/docs}}
|
||||
</ul>
|
||||
<% } %>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
324
templates/lib/janl/mustache.js
Normal file
324
templates/lib/janl/mustache.js
Normal file
@ -0,0 +1,324 @@
|
||||
/*
|
||||
mustache.js — Logic-less templates in JavaScript
|
||||
|
||||
See http://mustache.github.com/ for more info.
|
||||
*/
|
||||
|
||||
var Mustache = function() {
|
||||
var Renderer = function() {};
|
||||
|
||||
Renderer.prototype = {
|
||||
otag: "{{",
|
||||
ctag: "}}",
|
||||
pragmas: {},
|
||||
buffer: [],
|
||||
pragmas_implemented: {
|
||||
"IMPLICIT-ITERATOR": true
|
||||
},
|
||||
context: {},
|
||||
|
||||
render: function(template, context, partials, in_recursion) {
|
||||
// reset buffer & set context
|
||||
if(!in_recursion) {
|
||||
this.context = context;
|
||||
this.buffer = []; // TODO: make this non-lazy
|
||||
}
|
||||
|
||||
// fail fast
|
||||
if(!this.includes("", template)) {
|
||||
if(in_recursion) {
|
||||
return template;
|
||||
} else {
|
||||
this.send(template);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
template = this.render_pragmas(template);
|
||||
var html = this.render_section(template, context, partials);
|
||||
if(in_recursion) {
|
||||
return this.render_tags(html, context, partials, in_recursion);
|
||||
}
|
||||
|
||||
this.render_tags(html, context, partials, in_recursion);
|
||||
},
|
||||
|
||||
/*
|
||||
Sends parsed lines
|
||||
*/
|
||||
send: function(line) {
|
||||
if(line != "") {
|
||||
this.buffer.push(line);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
Looks for %PRAGMAS
|
||||
*/
|
||||
render_pragmas: function(template) {
|
||||
// no pragmas
|
||||
if(!this.includes("%", template)) {
|
||||
return template;
|
||||
}
|
||||
|
||||
var that = this;
|
||||
var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
|
||||
this.ctag);
|
||||
return template.replace(regex, function(match, pragma, options) {
|
||||
if(!that.pragmas_implemented[pragma]) {
|
||||
throw({message:
|
||||
"This implementation of mustache doesn't understand the '" +
|
||||
pragma + "' pragma"});
|
||||
}
|
||||
that.pragmas[pragma] = {};
|
||||
if(options) {
|
||||
var opts = options.split("=");
|
||||
that.pragmas[pragma][opts[0]] = opts[1];
|
||||
}
|
||||
return "";
|
||||
// ignore unknown pragmas silently
|
||||
});
|
||||
},
|
||||
|
||||
/*
|
||||
Tries to find a partial in the curent scope and render it
|
||||
*/
|
||||
render_partial: function(name, context, partials) {
|
||||
name = this.trim(name);
|
||||
if(!partials || partials[name] === undefined) {
|
||||
throw({message: "unknown_partial '" + name + "'"});
|
||||
}
|
||||
if(typeof(context[name]) != "object") {
|
||||
return this.render(partials[name], context, partials, true);
|
||||
}
|
||||
return this.render(partials[name], context[name], partials, true);
|
||||
},
|
||||
|
||||
/*
|
||||
Renders inverted (^) and normal (#) sections
|
||||
*/
|
||||
render_section: function(template, context, partials) {
|
||||
if(!this.includes("#", template) && !this.includes("^", template)) {
|
||||
return template;
|
||||
}
|
||||
|
||||
var that = this;
|
||||
// CSW - Added "+?" so it finds the tighest bound, not the widest
|
||||
var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
|
||||
"\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
|
||||
"\\s*", "mg");
|
||||
|
||||
// for each {{#foo}}{{/foo}} section do...
|
||||
return template.replace(regex, function(match, type, name, content) {
|
||||
var value = that.find(name, context);
|
||||
if(type == "^") { // inverted section
|
||||
if(!value || that.is_array(value) && value.length === 0) {
|
||||
// false or empty list, render it
|
||||
return that.render(content, context, partials, true);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
} else if(type == "#") { // normal section
|
||||
if(that.is_array(value)) { // Enumerable, Let's loop!
|
||||
return that.map(value, function(row) {
|
||||
return that.render(content, that.create_context(row),
|
||||
partials, true);
|
||||
}).join("");
|
||||
} else if(that.is_object(value)) { // Object, Use it as subcontext!
|
||||
return that.render(content, that.create_context(value),
|
||||
partials, true);
|
||||
} else if(typeof value === "function") {
|
||||
// higher order section
|
||||
return value.call(context, content, function(text) {
|
||||
return that.render(text, context, partials, true);
|
||||
});
|
||||
} else if(value) { // boolean section
|
||||
return that.render(content, context, partials, true);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/*
|
||||
Replace {{foo}} and friends with values from our view
|
||||
*/
|
||||
render_tags: function(template, context, partials, in_recursion) {
|
||||
// tit for tat
|
||||
var that = this;
|
||||
|
||||
var new_regex = function() {
|
||||
return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
|
||||
that.ctag + "+", "g");
|
||||
};
|
||||
|
||||
var regex = new_regex();
|
||||
var tag_replace_callback = function(match, operator, name) {
|
||||
switch(operator) {
|
||||
case "!": // ignore comments
|
||||
return "";
|
||||
case "=": // set new delimiters, rebuild the replace regexp
|
||||
that.set_delimiters(name);
|
||||
regex = new_regex();
|
||||
return "";
|
||||
case ">": // render partial
|
||||
return that.render_partial(name, context, partials);
|
||||
case "{": // the triple mustache is unescaped
|
||||
return that.find(name, context);
|
||||
default: // escape the value
|
||||
return that.escape(that.find(name, context));
|
||||
}
|
||||
};
|
||||
var lines = template.split("\n");
|
||||
for(var i = 0; i < lines.length; i++) {
|
||||
lines[i] = lines[i].replace(regex, tag_replace_callback, this);
|
||||
if(!in_recursion) {
|
||||
this.send(lines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if(in_recursion) {
|
||||
return lines.join("\n");
|
||||
}
|
||||
},
|
||||
|
||||
set_delimiters: function(delimiters) {
|
||||
var dels = delimiters.split(" ");
|
||||
this.otag = this.escape_regex(dels[0]);
|
||||
this.ctag = this.escape_regex(dels[1]);
|
||||
},
|
||||
|
||||
escape_regex: function(text) {
|
||||
// thank you Simon Willison
|
||||
if(!arguments.callee.sRE) {
|
||||
var specials = [
|
||||
'/', '.', '*', '+', '?', '|',
|
||||
'(', ')', '[', ']', '{', '}', '\\'
|
||||
];
|
||||
arguments.callee.sRE = new RegExp(
|
||||
'(\\' + specials.join('|\\') + ')', 'g'
|
||||
);
|
||||
}
|
||||
return text.replace(arguments.callee.sRE, '\\$1');
|
||||
},
|
||||
|
||||
/*
|
||||
find `name` in current `context`. That is find me a value
|
||||
from the view object
|
||||
*/
|
||||
find: function(name, context) {
|
||||
name = this.trim(name);
|
||||
|
||||
// Checks whether a value is thruthy or false or 0
|
||||
function is_kinda_truthy(bool) {
|
||||
return bool === false || bool === 0 || bool;
|
||||
}
|
||||
|
||||
var value;
|
||||
if(is_kinda_truthy(context[name])) {
|
||||
value = context[name];
|
||||
} else if(is_kinda_truthy(this.context[name])) {
|
||||
value = this.context[name];
|
||||
}
|
||||
|
||||
if(typeof value === "function") {
|
||||
return value.apply(context);
|
||||
}
|
||||
if(value !== undefined) {
|
||||
return value;
|
||||
}
|
||||
// silently ignore unkown variables
|
||||
return "";
|
||||
},
|
||||
|
||||
// Utility methods
|
||||
|
||||
/* includes tag */
|
||||
includes: function(needle, haystack) {
|
||||
return haystack.indexOf(this.otag + needle) != -1;
|
||||
},
|
||||
|
||||
/*
|
||||
Does away with nasty characters
|
||||
*/
|
||||
escape: function(s) {
|
||||
s = String(s === null ? "" : s);
|
||||
return s.replace(/&(?!\w+;)|["<>\\]/g, function(s) {
|
||||
switch(s) {
|
||||
case "&": return "&";
|
||||
case "\\": return "\\\\";
|
||||
case '"': return '\"';
|
||||
case "<": return "<";
|
||||
case ">": return ">";
|
||||
default: return s;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// by @langalex, support for arrays of strings
|
||||
create_context: function(_context) {
|
||||
if(this.is_object(_context)) {
|
||||
return _context;
|
||||
} else {
|
||||
var iterator = ".";
|
||||
if(this.pragmas["IMPLICIT-ITERATOR"]) {
|
||||
iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
|
||||
}
|
||||
var ctx = {};
|
||||
ctx[iterator] = _context;
|
||||
return ctx;
|
||||
}
|
||||
},
|
||||
|
||||
is_object: function(a) {
|
||||
return a && typeof a == "object";
|
||||
},
|
||||
|
||||
is_array: function(a) {
|
||||
return Object.prototype.toString.call(a) === '[object Array]';
|
||||
},
|
||||
|
||||
/*
|
||||
Gets rid of leading and trailing whitespace
|
||||
*/
|
||||
trim: function(s) {
|
||||
return s.replace(/^\s*|\s*$/g, "");
|
||||
},
|
||||
|
||||
/*
|
||||
Why, why, why? Because IE. Cry, cry cry.
|
||||
*/
|
||||
map: function(array, fn) {
|
||||
if (typeof array.map == "function") {
|
||||
return array.map(fn);
|
||||
} else {
|
||||
var r = [];
|
||||
var l = array.length;
|
||||
for(var i = 0; i < l; i++) {
|
||||
r.push(fn(array[i]));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return({
|
||||
name: "mustache.js",
|
||||
version: "0.3.0",
|
||||
|
||||
/*
|
||||
Turns a template and view into HTML
|
||||
*/
|
||||
to_html: function(template, view, partials, send_fun) {
|
||||
var renderer = new Renderer();
|
||||
if(send_fun) {
|
||||
renderer.send = send_fun;
|
||||
}
|
||||
renderer.render(template, view, partials);
|
||||
if(!send_fun) {
|
||||
return renderer.buffer.join("\n");
|
||||
}
|
||||
}
|
||||
});
|
||||
}();
|
||||
@ -1,34 +0,0 @@
|
||||
// Based on Simple JavaScript Templating
|
||||
// By John Resig - http://ejohn.org/ - MIT Licensed
|
||||
// see: http://ejohn.org/blog/javascript-micro-templating/
|
||||
// modified to run on Rhino
|
||||
(function(){
|
||||
var cache = {};
|
||||
|
||||
this.tmpl = function tmpl(/** templatefilename | templatesrc */str, data){ // templatefilename must not contain `<`, templatesrc must contain <
|
||||
var fn = str.indexOf('<') === -1 ?
|
||||
cache[str] = cache[str] || tmpl(readFile(str)) :
|
||||
|
||||
// Generate a reusable function that will serve as a template
|
||||
// generator (and which will be cached).
|
||||
new Function("obj",
|
||||
"var p=[],print=function(){p.push.apply(p,arguments);};" +
|
||||
|
||||
// Introduce the data as local variables using with(){}
|
||||
"with(obj){p.push('" +
|
||||
|
||||
// Convert the template into pure JavaScript
|
||||
str
|
||||
.replace(/[\r\t\n]/g, " ")
|
||||
.split("<%").join("\t")
|
||||
.replace(/((^|%>)[^\t]*)'/g, "$1\r")
|
||||
.replace(/\t=(.*?)%>/g, "',$1,'")
|
||||
.split("\t").join("');")
|
||||
.split("%>").join("p.push('")
|
||||
.split("\r").join("\\'")
|
||||
+ "');}return p.join('');");
|
||||
|
||||
// Provide some basic currying to the user
|
||||
return data ? fn( data ) : fn;
|
||||
};
|
||||
})();
|
||||
@ -1,37 +1,64 @@
|
||||
load(BASEDIR + '/test/tests/01_jsdoc_opts.js');
|
||||
load(BASEDIR + '/test/tests/02_jsdoc_src.js');
|
||||
load(BASEDIR + '/test/tests/03_jsdoc_parser.js');
|
||||
load(BASEDIR + '/test/tests/04_jsdoc_docset.js');
|
||||
load(BASEDIR + '/test/tests/05_jsdoc_doclet.js');
|
||||
load(BASEDIR + '/test/tests/06_jsdoc_tag.js');
|
||||
load(BASEDIR + '/test/tests/07_jsdoc_resolvefunc.js');
|
||||
load(BASEDIR + '/test/tests/07_jsdoc_resolvefunc_2.js');
|
||||
load(BASEDIR + '/test/tests/07_jsdoc_resolvevar.js');
|
||||
load(BASEDIR + '/test/tests/08_tag_name.js');
|
||||
load(BASEDIR + '/test/tests/09_tag_desc.js');
|
||||
load(BASEDIR + '/test/tests/10_tag_constructor.js');
|
||||
load(BASEDIR + '/test/tests/11_tag_namespace.js');
|
||||
load(BASEDIR + '/test/tests/12_tag_property.js');
|
||||
load(BASEDIR + '/test/tests/13_tag_method.js');
|
||||
load(BASEDIR + '/test/tests/14_tag_member.js');
|
||||
load(BASEDIR + '/test/tests/15_tag_type.js');
|
||||
load(BASEDIR + '/test/tests/16_tag_return.js');
|
||||
load(BASEDIR + '/test/tests/17_tag_example.js');
|
||||
load(BASEDIR + '/test/tests/18_tag_class.js');
|
||||
load(BASEDIR + '/test/tests/19_tag_param.js');
|
||||
load(BASEDIR + '/test/tests/20_tag_file.js');
|
||||
load(BASEDIR + '/test/tests/21_tag_const.js');
|
||||
load(BASEDIR + '/test/tests/22_tag_preserve.js');
|
||||
load(BASEDIR + '/test/tests/23_tag_fires.js');
|
||||
load(BASEDIR + '/test/tests/24_tag_exception.js');
|
||||
load(BASEDIR + '/test/tests/25_tag_scope.js');
|
||||
load(BASEDIR + '/test/tests/26_tag_tag.js');
|
||||
load(BASEDIR + '/test/tests/27_tag_module.js');
|
||||
load(BASEDIR + '/test/tests/28_tag_requires.js');
|
||||
// include('test/tests/01_jsdoc_opts.js');
|
||||
// include('test/tests/02_jsdoc_src.js');
|
||||
// include('test/tests/03_jsdoc_parser.js');
|
||||
// include('test/tests/04_jsdoc_docset.js');
|
||||
// include('test/tests/05_jsdoc_doclet.js');
|
||||
// include('test/tests/06_jsdoc_tag.js');
|
||||
// include('test/tests/07_jsdoc_resolvefunc.js');
|
||||
// include('test/tests/07_jsdoc_resolvefunc_2.js');
|
||||
// include('test/tests/07_jsdoc_resolvevar.js');
|
||||
// include('test/tests/08_tag_name.js');
|
||||
// include('test/tests/09_tag_desc.js');
|
||||
// include('test/tests/10_tag_constructor.js');
|
||||
// include('test/tests/11_tag_namespace.js');
|
||||
// include('test/tests/12_tag_property.js');
|
||||
// include('test/tests/13_tag_method.js');
|
||||
// include('test/tests/14_tag_member.js');
|
||||
// include('test/tests/15_tag_type.js');
|
||||
// include('test/tests/16_tag_return.js');
|
||||
// include('test/tests/17_tag_example.js');
|
||||
// include('test/tests/18_tag_class.js');
|
||||
// include('test/tests/19_tag_param.js');
|
||||
// include('test/tests/20_tag_file.js');
|
||||
// include('test/tests/21_tag_const.js');
|
||||
// include('test/tests/22_tag_preserve.js');
|
||||
// include('test/tests/23_tag_fires.js');
|
||||
// include('test/tests/24_tag_exception.js');
|
||||
// include('test/tests/25_tag_scope.js');
|
||||
// include('test/tests/26_tag_tag.js');
|
||||
// include('test/tests/27_tag_module.js');
|
||||
// include('test/tests/28_tag_requires.js');
|
||||
|
||||
// see http://visionmedia.github.com/jspec/
|
||||
JSpec.run({
|
||||
reporter: JSpec.reporters.Terminal,
|
||||
failuresOnly: true
|
||||
})
|
||||
.report();
|
||||
var assert = require('common/assert');
|
||||
|
||||
var passCount = 0,
|
||||
failCount = 0,
|
||||
errorLog = [];
|
||||
|
||||
function test(description, f) {
|
||||
try {
|
||||
f();
|
||||
passCount++;
|
||||
}
|
||||
catch(e) {
|
||||
errorLog.push(description + '\n' + (e.message||'') + '\n - Expected: ' + e.expected + '\n - Actual: ' + e.actual);
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
|
||||
function report() {
|
||||
print('\033[032mPASSED: ' + passCount + ' test' + (passCount == 1? '' : 's') + '.\033[0m');
|
||||
if (failCount) {
|
||||
print('\033[031mFAILED: '+ failCount + ' test' + (passCount == 1? '' : 's') + '.\033[0m');
|
||||
for (var i = 0, leni = errorLog.length; i < leni; i++) {
|
||||
print(' ' + (i+1) + '. ' + (i+1 < 10? ' ' : '') + (errorLog[i]||'') + '\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// test files
|
||||
include('test/t/common/dumper.js');
|
||||
include('test/t/jsdoc/opts/parser.js');
|
||||
include('test/t/jsdoc/src/parser.js');
|
||||
|
||||
report();
|
||||
|
||||
83
test/t/common/dumper.js
Normal file
83
test/t/common/dumper.js
Normal file
@ -0,0 +1,83 @@
|
||||
var common = {dumper: require('common/dumper')};
|
||||
|
||||
test('The common/dumper module is defined.', function() {
|
||||
assert.notEqual(typeof common.dumper, 'undefined', 'The common/dumper module should be defined.');
|
||||
assert.equal(typeof common.dumper, 'object', 'The common/dumper module should be an object.');
|
||||
});
|
||||
|
||||
test('The common/dumper module exports a "dump" function.', function() {
|
||||
assert.notEqual(typeof common.dumper.dump, 'undefined', 'The common/dumper.dump member should be defined.');
|
||||
assert.equal(typeof common.dumper.dump, 'function', 'The common/dumper.dump member should be a function.');
|
||||
});
|
||||
|
||||
test('The common/dumper.dump function dumps string values.', function() {
|
||||
assert.equal(common.dumper.dump('hello'), '"hello"');
|
||||
assert.equal(common.dumper.dump('hello "world"'), '"hello \\"world\\""', 'Double quotes should be escaped.');
|
||||
assert.equal(common.dumper.dump('hello\nworld'), '"hello\\nworld"', 'Newlines should be escaped.');
|
||||
});
|
||||
|
||||
test('The common/dumper.dump function dumps number values.', function() {
|
||||
assert.equal(common.dumper.dump(1), '1');
|
||||
assert.equal(common.dumper.dump(0.1), '0.1', 'Decimal numbers shuld be dumped.');
|
||||
});
|
||||
|
||||
test('The common/dumper.dump function dumps boolean values.', function() {
|
||||
assert.equal(common.dumper.dump(true), 'true');
|
||||
assert.equal(common.dumper.dump(false), 'false');
|
||||
});
|
||||
|
||||
test('The common/dumper.dump function dumps null values.', function() {
|
||||
assert.equal(common.dumper.dump(null), 'null');
|
||||
});
|
||||
|
||||
test('The common/dumper.dump function dumps undefined values.', function() {
|
||||
assert.equal(common.dumper.dump(undefined), 'undefined');
|
||||
});
|
||||
|
||||
test('The common/dumper.dump function dumps regex values.', function() {
|
||||
assert.equal(common.dumper.dump(/^[Ff]oo$/gi), '<RegExp /^[Ff]oo$/gi>');
|
||||
});
|
||||
|
||||
test('The common/dumper.dump function dumps date values.', function() {
|
||||
assert.equal(common.dumper.dump(new Date(1901, 0, 1)), '<Date Tue Jan 01 1901 00:00:00 GMT-0000 (GMT)>');
|
||||
});
|
||||
|
||||
test('The common/dumper.dump function dumps function values.', function() {
|
||||
assert.equal(common.dumper.dump(function myFunc(){}), '<Function myFunc>');
|
||||
assert.equal(common.dumper.dump(function(){}), '<Function>');
|
||||
});
|
||||
|
||||
test('The common/dumper.dump function dumps array values.', function() {
|
||||
var actual = common.dumper.dump(["hello", "world"]),
|
||||
expected = '[\n "hello",\n "world"\n]';
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
test('The common/dumper.dump function dumps simple object values.', function() {
|
||||
var actual = common.dumper.dump({hello: "world"}),
|
||||
expected = '{\n "hello": "world"\n}';
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
|
||||
test('The common/dumper.dump function dumps constructed instance values.', function() {
|
||||
function Foo(name){ this.name = name; }
|
||||
Foo.prototype.sayHello = function(){}
|
||||
|
||||
var actual = common.dumper.dump(new Foo('hello')),
|
||||
expected = '{\n "name": "hello"\n}';
|
||||
|
||||
assert.equal(actual, expected, 'Members of the instance should appear, but not prototype members.');
|
||||
});
|
||||
|
||||
test('The common/dumper.dump function dumps complex mixed values.', function() {
|
||||
function Foo(){}
|
||||
|
||||
var actual = common.dumper.dump(
|
||||
[undefined, null, new Foo(), 1, true, 'hello\n"world', new Error('oops'), /foo/gi, new Date(2010, 11, 26), {f: function myFunc(){}, o: {a:1}}]
|
||||
),
|
||||
expected = '[\n undefined,\n null,\n {\n },\n 1,\n true,\n "hello\\n\\"world",\n {\n "message": "oops"\n },\n <RegExp /foo/gi>,\n <Date Sun Dec 26 2010 00:00:00 GMT-0000 (GMT)>,\n {\n "f": <Function myFunc>,\n "o": {\n "a": 1\n }\n }\n]';
|
||||
|
||||
assert.equal(actual, expected);
|
||||
});
|
||||
37
test/t/jsdoc/opts/parser.js
Normal file
37
test/t/jsdoc/opts/parser.js
Normal file
@ -0,0 +1,37 @@
|
||||
var opts = require('jsdoc/opts/parser');
|
||||
|
||||
test('The opts module is defined.', function() {
|
||||
assert.notEqual(typeof opts, 'undefined', 'The opts module should not be undefined.');
|
||||
assert.equal(typeof opts, 'object', 'The opts module should be an object.');
|
||||
});
|
||||
|
||||
test('The opts module exports a "parse" function.', function() {
|
||||
assert.notEqual(typeof opts.parse, 'undefined', 'The opts.parse method should not be undefined.');
|
||||
assert.equal(typeof opts.parse, 'function', 'The opts.parse method should be a function.');
|
||||
});
|
||||
|
||||
test('The opts module exports a "get" function.', function() {
|
||||
assert.notEqual(typeof opts.get, 'undefined', 'The opts.get method should not be undefined.');
|
||||
assert.equal(typeof opts.get, 'function', 'The opts.get method should be a function.');
|
||||
});
|
||||
|
||||
test('The opts.parse function accepts a -t opt.', function() {
|
||||
opts.parse(['-t', 'mytemplate']);
|
||||
var r = opts.get();
|
||||
|
||||
assert.equal(r.template, 'mytemplate', 'The opts.get method should return an object with a set template property.');
|
||||
});
|
||||
|
||||
test('The opts.parse function accepts a -d opt.', function() {
|
||||
opts.parse(['-d', 'mydestination']);
|
||||
var r = opts.get();
|
||||
|
||||
assert.equal(r.destination, 'mydestination', 'The opts.get method should return an object with a set destination property.');
|
||||
});
|
||||
|
||||
test('The opts.parse function accepts a naked opt.', function() {
|
||||
opts.parse(['myfile1', 'myfile2']);
|
||||
var r = opts.get();
|
||||
|
||||
assert.deepEqual(r._, ['myfile1', 'myfile2'], 'The opts.get method should return an object with a set _ property.');
|
||||
});
|
||||
75
test/t/jsdoc/src/parser.js
Normal file
75
test/t/jsdoc/src/parser.js
Normal file
@ -0,0 +1,75 @@
|
||||
(function() {
|
||||
|
||||
var src = { parser: require('jsdoc/src/parser')};
|
||||
|
||||
test('There is a src/parser module.', function() {
|
||||
assert.notEqual(typeof src, 'undefined', 'The src/parser module should be defined.');
|
||||
assert.equal(typeof src, 'object', 'The src/parser module should be an object.');
|
||||
});
|
||||
|
||||
test('The src/parser module has a "parse" function.', function() {
|
||||
assert.notEqual(typeof src.parser.parse, 'undefined', 'The src.parser.parse method should be defined.');
|
||||
assert.equal(typeof src.parser.parse, 'function', 'The src.parser.parse method should be a function.');
|
||||
});
|
||||
|
||||
test('The src/parser module has a "parseSource" function.', function() {
|
||||
assert.notEqual(typeof src.parser.parseSource, 'undefined', 'The src.parser.parseSource method should be defined.');
|
||||
assert.equal(typeof src.parser.parseSource, 'function', 'The src.parser.parseSource method should be a function.');
|
||||
});
|
||||
|
||||
test('The src/parser module has a "result" function.', function() {
|
||||
assert.notEqual(typeof src.parser.result, 'undefined', 'The src.parser.result method should be defined.');
|
||||
assert.equal(typeof src.parser.result, 'function', 'The src.parser.result method should be a function.');
|
||||
});
|
||||
|
||||
test('The src/parser module has a "clear" function.', function() {
|
||||
assert.notEqual(typeof src.parser.clear, 'undefined', 'The src.parser.clear method should be defined.');
|
||||
assert.equal(typeof src.parser.clear, 'function', 'The src.parser.clear method should be a function.');
|
||||
});
|
||||
|
||||
test('The src/parser.result function can return the result array.', function() {
|
||||
var docs = src.parser.result;
|
||||
|
||||
assert.notEqual(typeof docs, 'undefined', 'The src.parser.result method should return a result.');
|
||||
assert.equal(docs.length, 0, 'The src.parser.result method should return an array of 0 results if there has been nothing parsed yet.');
|
||||
});
|
||||
|
||||
test('The src/parser.parseSource function can parse js source code containing a jsdoc comment.', function() {
|
||||
var sourceCode = '/** @name foo */';
|
||||
|
||||
var docs = src.parser.parseSource(sourceCode, '/bar/foo.js');
|
||||
|
||||
assert.notEqual(typeof docs, 'undefined', 'The src.parser.parseSource method should return a result.');
|
||||
assert.equal(docs.length, 1, 'The src.parser.parseSource method should return an array of 1 result if there is 1 jsdoc comment.');
|
||||
assert.notEqual(typeof docs[0].tags, 'undefined', 'The result array returned by src.parser.parseSource should be a collection of Doclets with Tags.');
|
||||
});
|
||||
|
||||
test('The src/parser.clear function can empty the result array.', function() {
|
||||
src.parser.clear();
|
||||
var docs = src.parser.result;
|
||||
|
||||
assert.equal(docs.length, 0, 'The src.parser.result method should return an array of 0 results if clear was called.');
|
||||
});
|
||||
|
||||
test('The src/parser.parse function can parse js source code containing a doc comment.', function() {
|
||||
var sourceCode = 'javascript:/** @name bar */';
|
||||
|
||||
src.parser.clear();
|
||||
var docs = src.parser.parse([sourceCode]);
|
||||
|
||||
assert.notEqual(typeof docs, 'undefined', 'The src.parser.parse method should return a result.');
|
||||
assert.equal(docs.length, 1, 'The src.parser.parse method should return an array of 1 result if there is 1 jsdoc comment.');
|
||||
assert.notEqual(typeof docs[0].tags, 'undefined', 'The result array returned by src.parser.parse should be a collection of Doclets with Tags.');
|
||||
});
|
||||
|
||||
test('The src/parser.parse function can cope with source code containing no jsdoc comments.', function() {
|
||||
var sourceCode = 'javascript:var blah;';
|
||||
|
||||
src.parser.clear();
|
||||
var docs = src.parser.parse([sourceCode]);
|
||||
|
||||
assert.notEqual(typeof docs, 'undefined', 'The src.parser.parse method should return a result.');
|
||||
assert.equal(docs.length, 0, 'The src.parser.parse method should return an array of 0 Doclets if there are no jsdocc omments.');
|
||||
});
|
||||
|
||||
})();
|
||||
@ -1,106 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc;
|
||||
|
||||
JSpec.describe('jsdoc/opts.js', function() {
|
||||
|
||||
before(function() {
|
||||
jsdoc = { opts: require('jsdoc/opts') };
|
||||
});
|
||||
|
||||
describe('The object exported by the jsdoc/opts module', function() {
|
||||
it('should be an object', function() {
|
||||
expect(jsdoc.opts).to(be_an, Object);
|
||||
});
|
||||
|
||||
it('should have a set method', function() {
|
||||
expect(jsdoc.opts).to(respond_to, 'set');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The jsdoc.opts#set method', function() {
|
||||
it('should return an object', function() {
|
||||
var returnedValue = jsdoc.opts.set('main.js');
|
||||
expect(returnedValue).to(be_an, Object);
|
||||
});
|
||||
});
|
||||
|
||||
describe('The return value of jsdoc.opts#set when called with no arguments', function() {
|
||||
it('should have a property named `destination`', function() {
|
||||
var returnedValue = jsdoc.opts.set();
|
||||
expect(returnedValue).to(have_property, 'destination', 'jsdoc.xml');
|
||||
});
|
||||
|
||||
it('should have a property named `template`', function() {
|
||||
var returnedValue = jsdoc.opts.set();
|
||||
expect(returnedValue).to(have_property, 'template', 'default');
|
||||
});
|
||||
|
||||
it('should have a property named `_`', function() {
|
||||
var returnedValue = jsdoc.opts.set();
|
||||
expect(returnedValue).to(have_property, '_');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The default value for the property named `opts._`', function() {
|
||||
it('should be an empty array', function() {
|
||||
var returnedValue = jsdoc.opts.set();
|
||||
expect(returnedValue._).to(be_a, Array);
|
||||
expect(returnedValue._).to(have_length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
//// setting the destination option
|
||||
describe('The return value of jsdoc.opts#set when called with `["-d", "foo/bar.json"]`', function() {
|
||||
it('should have a property `destination` set to "foo/bar.json"', function() {
|
||||
var returnedValue = jsdoc.opts.set(['-d', 'foo/bar.json']);
|
||||
expect(returnedValue.destination).to(be, 'foo/bar.json');
|
||||
});
|
||||
});
|
||||
|
||||
//// setting the recurse option
|
||||
describe('The return value of jsdoc.opts#recurse when called with `-r`', function() {
|
||||
it('should have a property `recurse` set to true', function() {
|
||||
var returnedValue = jsdoc.opts.set(['-r', true]);
|
||||
expect(returnedValue.recurse).to(be, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('The return value of jsdoc.opts#set when called with `["--destination", "flib/flub.json"]`', function() {
|
||||
it('should have a property `destination` set to "flib/flub.json"', function() {
|
||||
var returnedValue = jsdoc.opts.set(['--destination', 'flib/flub.json']);
|
||||
expect(returnedValue.destination).to(be, 'flib/flub.json');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The return value of jsdoc.opts#set when called with `["-d", ""]`', function() {
|
||||
it('should have a property `destination` set to ""', function() {
|
||||
var returnedValue = jsdoc.opts.set(['-d', '']);
|
||||
expect(returnedValue.destination).to(be, '');
|
||||
});
|
||||
});
|
||||
|
||||
//// setting the template option
|
||||
describe('The return value of jsdoc.opts#set when called with `["-t", "mytemplate"]`', function() {
|
||||
it('should have a property `template` set to "mytemplate"', function() {
|
||||
var returnedValue = jsdoc.opts.set(['-t', 'mytemplate']);
|
||||
expect(returnedValue.template).to(be, 'mytemplate');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The return value of jsdoc.opts#set when called with `["--template", "mytemplate"]`', function() {
|
||||
it('should have a property `template` set to "mytemplate"', function() {
|
||||
var returnedValue = jsdoc.opts.set(['--template', 'mytemplate']);
|
||||
expect(returnedValue.template).to(be, 'mytemplate');
|
||||
});
|
||||
});
|
||||
|
||||
//// setting the _ option
|
||||
describe('The return value of jsdoc.opts#set when called with `["one", "two"]`', function() {
|
||||
it('should have a property `_` set to ["one", "two"]', function() {
|
||||
var returnedValue = jsdoc.opts.set(["one", "two"]);
|
||||
expect(returnedValue._).to(eql, ["one", "two"]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
||||
@ -1,62 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc;
|
||||
|
||||
JSpec.describe('jsdoc/src.js', function() {
|
||||
|
||||
before(function() {
|
||||
jsdoc = { src: require('jsdoc/src') };
|
||||
});
|
||||
|
||||
describe('The object exported by the jsdoc/src module', function() {
|
||||
it('should be an object', function() {
|
||||
expect(jsdoc.src).to(be_an, Object);
|
||||
});
|
||||
|
||||
it('should have a `getFilePaths` method', function() {
|
||||
expect(jsdoc.src).to(respond_to, 'getFilePaths');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The return value of jsdoc.src#getFilePaths when called with no arguments', function() {
|
||||
it('should return an empty array', function() {
|
||||
var returnedValue = jsdoc.src.getFilePaths();
|
||||
expect(returnedValue).to(be_an, Array);
|
||||
expect(returnedValue).to(have_length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('The return value of jsdoc.src#getFilePaths when called with an array with one src dir and no depth', function() {
|
||||
it('should return an array of 2 file paths', function() {
|
||||
var returnedValue = jsdoc.src.getFilePaths(['test/samples/src']);
|
||||
expect(returnedValue).to(be_an, Array);
|
||||
expect(returnedValue).to(have_length, 2);
|
||||
});
|
||||
|
||||
it('should contain both js files and not the txt file', function() {
|
||||
var returnedValue = jsdoc.src.getFilePaths(['test/samples/src']);
|
||||
|
||||
expect( returnedValue.indexOf('test/samples/src/one.js') ).to(be_at_least, 0);
|
||||
expect( returnedValue.indexOf('test/samples/src/two.js') ).to(be_at_least, 0);
|
||||
expect( returnedValue.indexOf('test/samples/src/ignored.txt') ).to(be_less_than, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('The return value of jsdoc.src#getFilePaths when called with an array with one src dir and depth of 2', function() {
|
||||
it('should return an array of 3 file paths', function() {
|
||||
var returnedValue = jsdoc.src.getFilePaths(['test/samples/src'], 2);
|
||||
expect(returnedValue).to(be_an, Array);
|
||||
expect(returnedValue).to(have_length, 3);
|
||||
});
|
||||
|
||||
it('should contain all three js files and not the txt file', function() {
|
||||
var returnedValue = jsdoc.src.getFilePaths(['test/samples/src'], 2);
|
||||
|
||||
expect( returnedValue.indexOf('test/samples/src/one.js') ).to(be_at_least, 0);
|
||||
expect( returnedValue.indexOf('test/samples/src/two.js') ).to(be_at_least, 0);
|
||||
expect( returnedValue.indexOf('test/samples/src/dir1/three.js') ).to(be_at_least, 0);
|
||||
expect( returnedValue.indexOf('test/samples/src/ignored.txt') ).to(be_less_than, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
||||
@ -1,39 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc;
|
||||
|
||||
JSpec.describe('jsdoc/parser.js', function() {
|
||||
|
||||
before(function() {
|
||||
jsdoc = { parser: require('jsdoc/parser') };
|
||||
});
|
||||
|
||||
describe('The object exported by the jsdoc/src module', function() {
|
||||
it('should be an object', function() {
|
||||
expect(jsdoc.parser).to(be_an, Object);
|
||||
});
|
||||
|
||||
it('should have a `parseFiles` method', function() {
|
||||
expect(jsdoc.parser).to(respond_to, 'parseFiles');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The jsdoc.parser.result value', function() {
|
||||
it('should initially be an empty array', function() {
|
||||
expect(jsdoc.parser.result).to(be_an, Array);
|
||||
expect(jsdoc.parser.result).to(have_length, 0);
|
||||
});
|
||||
|
||||
it('should be set by calling jsdoc.parser.parseFiles', function() {
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/tests/03_jsdoc_parser.js');
|
||||
expect(jsdoc.parser.result).to(be_an, Array);
|
||||
expect(jsdoc.parser.result).to(have_length, 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
(function testarea() {
|
||||
|
||||
/** @constructor Foo */
|
||||
|
||||
})();
|
||||
@ -1,40 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc;
|
||||
|
||||
JSpec.describe('jsdoc/docset.js', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = { parser: require('jsdoc/parser') };
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/tests/04_jsdoc_docset.js');
|
||||
});
|
||||
|
||||
describe('The docset object', function() {
|
||||
it('should be an array', function() {
|
||||
expect(jsdoc.parser.result).to(be_an, Array);
|
||||
});
|
||||
|
||||
it('should have a `toObject` method', function() {
|
||||
expect(jsdoc.parser.result).to(respond_to, 'toObject');
|
||||
});
|
||||
|
||||
it('should have a `toString` method', function() {
|
||||
expect(jsdoc.parser.result).to(respond_to, 'toString');
|
||||
});
|
||||
|
||||
it('should have a `toJSON` method', function() {
|
||||
expect(jsdoc.parser.result).to(respond_to, 'toJSON');
|
||||
});
|
||||
|
||||
it('should have a `toXML` method', function() {
|
||||
expect(jsdoc.parser.result).to(respond_to, 'toXML');
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
(function testarea() {
|
||||
|
||||
/** @constructor Foo */
|
||||
|
||||
})();
|
||||
@ -1,87 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclet;
|
||||
|
||||
JSpec.describe('jsdoc/doclet.js', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = { parser: require('jsdoc/parser') };
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/tests/05_jsdoc_doclet.js');
|
||||
doclet = jsdoc.parser.result[0];
|
||||
});
|
||||
|
||||
describe('The doclet object', function() {
|
||||
it('should be a doclet', function() {
|
||||
expect(doclet.constructor.name).to(eql, 'Doclet');
|
||||
});
|
||||
|
||||
it('should have a `tagValue` method', function() {
|
||||
expect(doclet).to(respond_to, 'toObject');
|
||||
});
|
||||
|
||||
it('should have a `hasTag` method', function() {
|
||||
expect(doclet).to(respond_to, 'toObject');
|
||||
});
|
||||
|
||||
it('should have a `tags` property which is an array', function() {
|
||||
expect(doclet).to(have_property, 'tags');
|
||||
expect(doclet.tags).to(be_an, Array);
|
||||
});
|
||||
|
||||
it('should have a `meta` property which is an object', function() {
|
||||
expect(doclet).to(have_property, 'meta');
|
||||
expect(doclet.meta).to(be_an, Object);
|
||||
});
|
||||
});
|
||||
|
||||
describe('The returned value of jsdoc.Doclet#tagValue', function() {
|
||||
it('should be a string', function() {
|
||||
var returnedValue = doclet.tagValue('name');
|
||||
expect(returnedValue).to(be_a, String);
|
||||
});
|
||||
|
||||
it('should be the text of the tag that matches the given tag name', function() {
|
||||
var returnedValue = doclet.tagValue('name');
|
||||
expect(returnedValue).to(eql, 'Foo');
|
||||
});
|
||||
|
||||
it('should be the text of the first tag that matches the given tag name if there are more than 1', function() {
|
||||
var returnedValue = doclet.tagValue('param');
|
||||
expect(returnedValue).to(eql, 'a');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The jsdoc.Doclet#hasTag method', function() {
|
||||
it('should return a boolean', function() {
|
||||
var returnedValue = doclet.hasTag('name');
|
||||
expect(returnedValue).to(be_a, Boolean);
|
||||
});
|
||||
|
||||
it('should return true if the tag exists', function() {
|
||||
var returnedValue = doclet.hasTag('param');
|
||||
expect(returnedValue).to(eql, true);
|
||||
});
|
||||
|
||||
it('should return true even if the tag was generated by JSDoc', function() {
|
||||
var returnedValue = doclet.hasTag('name');
|
||||
expect(returnedValue).to(eql, true);
|
||||
});
|
||||
|
||||
it('should return false if the tag does not exist', function() {
|
||||
var returnedValue = doclet.hasTag('unicorns');
|
||||
expect(returnedValue).to(eql, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
(function testarea() {
|
||||
|
||||
/**
|
||||
@constructor Foo
|
||||
@param a
|
||||
@param b
|
||||
*/
|
||||
|
||||
})();
|
||||
@ -1,93 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
tags;
|
||||
|
||||
JSpec.describe('jsdoc/tag.js', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/tests/06_jsdoc_tag.js');
|
||||
tags = jsdoc.parser.result[0].tags;
|
||||
});
|
||||
|
||||
describe('The object exported by the jsdoc/tag module', function() {
|
||||
it('should be an object', function() {
|
||||
expect(jsdoc.tag).to(be_an, Object);
|
||||
});
|
||||
|
||||
it('should have a `fromText` method', function() {
|
||||
expect(jsdoc.tag).to(respond_to, 'fromText');
|
||||
});
|
||||
|
||||
it('should have a `parse` method', function() {
|
||||
expect(jsdoc.tag).to(respond_to, 'parse');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The tag object', function() {
|
||||
it('should be a Tag', function() {
|
||||
var tag = tags[0];
|
||||
expect(tag.constructor.name).to(eql, 'Tag');
|
||||
});
|
||||
|
||||
it('should have a `raw` property which is an string', function() {
|
||||
var tag = tags[0];
|
||||
expect(tag).to(have_property, 'raw');
|
||||
expect(tag.raw).to(be_an, String);
|
||||
});
|
||||
|
||||
it('should have a `name` property which is an string', function() {
|
||||
var tag = tags[0];
|
||||
expect(tag).to(have_property, 'name');
|
||||
expect(tag.name).to(be_an, String);
|
||||
});
|
||||
|
||||
it('should have a `text` property which is an string', function() {
|
||||
var tag = tags[0];
|
||||
expect(tag).to(have_property, 'value');
|
||||
});
|
||||
|
||||
it('should have a `type` property which is an array', function() {
|
||||
var tag = tags[0];
|
||||
expect(tag).to(have_property, 'type');
|
||||
expect(tag.type).to(be_an, Array);
|
||||
});
|
||||
});
|
||||
|
||||
describe('The tag#raw property', function() {
|
||||
it('should be set to all the characters after the leading @', function() {
|
||||
var tag = tags[0];
|
||||
expect(tag.raw).to(include, 'description Hello world');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The tag#name property', function() {
|
||||
it('should be set to the text after the leading @', function() {
|
||||
var tag = tags[0];
|
||||
expect(tag.name).to(eql, 'description');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The tag#value property', function() {
|
||||
it('should be set to the text after the @name', function() {
|
||||
var tag = tags[0];
|
||||
expect(tag.value).to(eql, 'Hello world');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
|
||||
(function testarea() {
|
||||
|
||||
/**
|
||||
@description Hello world
|
||||
@name Foo
|
||||
@constructor
|
||||
*/
|
||||
|
||||
})();
|
||||
@ -1,113 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('jsdoc/name:resolvefunc', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/jsdoc_resolvefunc.js');
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet that has no @name, that is a property of a nested, undocumented objlit', function() {
|
||||
it('should be given a path that includes membership in the enclosing object', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'createShape');
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'ShapeFactory#util.createShape');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet that has no @name whose name starts with `this.`, that is a property of a nested objlit', function() {
|
||||
it('should correctly resolve `this` to the nearest enclosing object', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'lastShape');
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'ShapeFactory#util.lastShape');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A property doclet that has no @name or @kind whose name starts with `this.`, that is scoped to a non-constructor global function', function() {
|
||||
it('should correctly resolve to a property of the global scope', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'property');
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'g');
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'g');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A method doclet that has no @name or @kind whose name starts with `this.`, that is scoped to a constructor function', function() {
|
||||
it('should correctly resolve to a method of the constructor', function() {
|
||||
var doclet = doclets[4];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'method');
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'bar');
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'Foo#bar');
|
||||
});
|
||||
});
|
||||
|
||||
describe('An inner method doclet that has no @name or @kind, and is scoped to a constructor function', function() {
|
||||
it('should correctly resolve to an inner method of the constructor', function() {
|
||||
var doclet = doclets[5];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'method');
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'inner');
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'Foo~inner');
|
||||
expect(doclet).to(have_property, 'scope');
|
||||
expect(doclet.scope).to(eql, 'inner');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A nested inner method doclet that has no @name or @kind, and is scoped to an inner method', function() {
|
||||
it('should correctly resolve to an inner method of the a inner method', function() {
|
||||
var doclet = doclets[6];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'method');
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'deep');
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'Foo~inner~deep');
|
||||
expect(doclet).to(have_property, 'scope');
|
||||
expect(doclet.scope).to(eql, 'inner');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A property doclet whose name starts with `this.`, that has no @name or @kind, and is scoped to an inner method', function() {
|
||||
it('should correctly resolve to a property of the global scope', function() {
|
||||
var doclet = doclets[7];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'property');
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'globalProp');
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'globalProp');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A global method whose name starts with `this.`, that has no @name or @kind', function() {
|
||||
it('should correctly resolve to a property of the global scope', function() {
|
||||
var doclet = doclets[8];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'method');
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'globalFunc');
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'globalFunc');
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
@ -1,31 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('jsdoc/name:resolvefunc', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/jsdoc_resolvefunc_2.js');
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('An inner doclet that has no @name, but does have @scope and @member tags', function() {
|
||||
it('should be given a path that includes membership in the enclosing object', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'foo');
|
||||
expect(doclet).to(have_property, 'scope');
|
||||
expect(doclet.scope).to(eql, 'inner');
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'ns~foo');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
})();
|
||||
@ -1,87 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('jsdoc/name:resolvevar', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/jsdoc_resolvevar.js');
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A nested, static member of a undocumented global object', function() {
|
||||
it('should be documented as such', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet.name).to(eql, 'child2');
|
||||
expect(doclet.scope).to(eql, 'static');
|
||||
expect(doclet.path).to(eql, 'globalprop.child1.child2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A nested, static member of an inner member of an undocumented anonymous function', function() {
|
||||
it('should be documented as such', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet.name).to(eql, 'ip');
|
||||
expect(doclet.scope).to(eql, 'static');
|
||||
expect(doclet.path).to(eql, '[[anonymous]]~io.ip');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A documented static property', function() {
|
||||
it('should be documented as such', function() {
|
||||
var doclet = doclets[3];
|
||||
expect(doclet.name).to(eql, 'gp');
|
||||
expect(doclet.scope).to(eql, 'static');
|
||||
expect(doclet.path).to(eql, 'go.gp');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A documented var statement with multiple assignments', function() {
|
||||
it('should produce global docs for each documented assigment', function() {
|
||||
var doclet = doclets[4];
|
||||
expect(doclet.name).to(eql, 'foo');
|
||||
expect(doclet.scope).to(eql, 'global');
|
||||
|
||||
doclet = doclets[5];
|
||||
expect(doclet.name).to(eql, 'bar');
|
||||
expect(doclet.scope).to(eql, 'global');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A documented inner doclet of an undocumented enclosing symbol', function() {
|
||||
it('should be given a path that includes inner scope', function() {
|
||||
var doclet = doclets[6];
|
||||
expect(doclet.name).to(eql, 'innerProp');
|
||||
expect(doclet.scope).to(eql, 'inner');
|
||||
expect(doclet.memberof).to(eql, 'globalFunc');
|
||||
expect(doclet.path).to(eql, 'globalFunc~innerProp');
|
||||
});
|
||||
});
|
||||
|
||||
describe('An inner doclet that nested twice', function() {
|
||||
it('should be given a path that includes inner scope twice', function() {
|
||||
var doclet = doclets[7];
|
||||
expect(doclet.name).to(eql, 'nestedProp');
|
||||
expect(doclet.scope).to(eql, 'inner');
|
||||
expect(doclet.memberof).to(eql, 'globalFunc~innerFunc');
|
||||
expect(doclet.path).to(eql, 'globalFunc~innerFunc~nestedProp');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A this-doclet attached to a method of an object literal', function() {
|
||||
it('should set the property on the enclosing objectct literal', function() {
|
||||
var doclet = doclets[8];
|
||||
expect(doclet.name).to(eql, 'prop');
|
||||
expect(doclet.scope).to(eql, 'static');
|
||||
expect(doclet.memberof).to(eql, 'ns');
|
||||
expect(doclet.path).to(eql, 'ns.prop');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
@ -1,49 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@name', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_name.js');
|
||||
doclets = jsdoc.parser.result;
|
||||
});
|
||||
|
||||
describe('A doclet that has a @name tag followed by a simple string', function() {
|
||||
it('should have an `name` property set to that string', function() {
|
||||
var doclet = doclets[0].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'Tipsy');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet that has a @name tag followed by a dotted string', function() {
|
||||
it('should have an `name` property set to the last segment of that string', function() {
|
||||
var doclet = doclets[1].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'LaLa');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet that has a @name tag followed by a dotted string with quotes', function() {
|
||||
it('should have an `name` property set to the last entire quoted segment of that string', function() {
|
||||
var doclet = doclets[2].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, '"and.don\'t.forget#Po!"');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet that has a @name tag followed by a number', function() {
|
||||
it('should have an `name` property set to the number', function() {
|
||||
var doclet = doclets[3].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, '0');
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
@ -1,63 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@description', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/tests/09_tag_desc.js');
|
||||
doclets = jsdoc.parser.result;
|
||||
});
|
||||
|
||||
describe('A doclet that starts with untagged text', function() {
|
||||
it('should have an `description` property set to the text', function() {
|
||||
var doclet = doclets[0].toObject();
|
||||
expect(doclet).to(have_property, 'description');
|
||||
expect(doclet.description).to(eql, 'Here is Edward Bear, coming downstairs now,\nbump,\n bump,\n bump');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet that has a @description tag', function() {
|
||||
it('should have an `description` property set to the text of that tag', function() {
|
||||
var doclet = doclets[1].toObject();
|
||||
expect(doclet).to(have_property, 'description');
|
||||
expect(doclet.description).to(eql, 'Here is Edward Bear, coming downstairs now, bump, bump, bump');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet that has a @description tag', function() {
|
||||
it('should have an `description` property set to the text of that tag', function() {
|
||||
var doclet = doclets[2].toObject();
|
||||
expect(doclet).to(have_property, 'description');
|
||||
expect(doclet.description).to(eql, 'Here is Edward Bear, coming downstairs now, bump, bump, bump');
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
(function testarea() {
|
||||
|
||||
/**
|
||||
* Here is Edward Bear, coming downstairs now,
|
||||
* bump,
|
||||
* bump,
|
||||
* bump
|
||||
* @namespace Poo
|
||||
*/
|
||||
|
||||
/**
|
||||
@namespace Bear
|
||||
@description Here is Edward Bear, coming downstairs now, bump, bump, bump
|
||||
*/
|
||||
|
||||
/**
|
||||
@namespace Winnie
|
||||
@description Here is Edward Bear, coming downstairs now, bump, bump, bump
|
||||
*/
|
||||
|
||||
})();
|
||||
@ -1,90 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@constructor', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_constructor.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet from a constructor tag with a name tag and no code', function() {
|
||||
it('should have an `kind` property set to "constructor"', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'constructor');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'Foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet from a named constructor tag and no code', function() {
|
||||
it('should have an `kind` property set to "constructor"', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'constructor');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'Bar');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet from a constructor tag and named code', function() {
|
||||
it('should have an `kind` property set to "constructor"', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'constructor');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'Pez');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet from a constructor tag and named anonymous function', function() {
|
||||
it('should have an `kind` property set to "constructor"', function() {
|
||||
var doclet = doclets[3];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'constructor');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[3];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'Qux');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet from a constructor tag and named anonymous function part of a var', function() {
|
||||
it('should have an `kind` property set to "constructor"', function() {
|
||||
var doclet = doclets[4];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'constructor');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[4];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'Blap');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
@ -1,93 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@namespace', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/tests/11_tag_namespace.js');
|
||||
doclets = jsdoc.parser.result;
|
||||
});
|
||||
|
||||
describe('A doclet from a namespace tag with a name tag and no code', function() {
|
||||
it('should have an `kind` property set to "namespace"', function() {
|
||||
var doclet = doclets[0].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'namespace');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[0].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet from a named namespace tag and no code', function() {
|
||||
it('should have an `kind` property set to "namespace"', function() {
|
||||
var doclet = doclets[1].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'namespace');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[1].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'bar');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet from a namespace tag and named code', function() {
|
||||
it('should have an `kind` property set to "namespace"', function() {
|
||||
var doclet = doclets[2].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'namespace');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[2].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'pez');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet from a namespace tag and named anonymous function', function() {
|
||||
it('should have an `kind` property set to "namespace"', function() {
|
||||
var doclet = doclets[3].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'namespace');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[3].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'qux');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
|
||||
(function testarea() {
|
||||
|
||||
/**
|
||||
@name foo
|
||||
@namespace
|
||||
*/
|
||||
|
||||
/**
|
||||
@namespace bar
|
||||
*/
|
||||
|
||||
/** @namespace */
|
||||
pez = {
|
||||
}
|
||||
|
||||
/** @namespace */
|
||||
var qux = function() { }
|
||||
})();
|
||||
@ -1,134 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@property', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/tests/12_tag_property.js');
|
||||
doclets = jsdoc.parser.result;
|
||||
});
|
||||
|
||||
describe('A doclet with a named @property attached to a namespace', function() {
|
||||
it('should have an `kind` property set to "property"', function() {
|
||||
var doclet = doclets[2].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'property');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[2].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'fah');
|
||||
});
|
||||
|
||||
it('should have a `memberof` property set to the parent object name', function() {
|
||||
var doclet = doclets[2].toObject();
|
||||
expect(doclet).to(have_property, 'memberof');
|
||||
expect(doclet.memberof).to(eql, 'foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a named @property and a type and a description', function() {
|
||||
it('should have an `kind` property set to "property"', function() {
|
||||
var doclet = doclets[3].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'property');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[3].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'bah');
|
||||
});
|
||||
|
||||
it('should have a `type` property set to the parent given type', function() {
|
||||
var doclet = doclets[3].toObject();
|
||||
expect(doclet).to(have_property, 'type');
|
||||
expect(doclet.type).to(eql, ['string', 'number']);
|
||||
});
|
||||
|
||||
it('should have a `description` property set to the given description', function() {
|
||||
var doclet = doclets[3].toObject();
|
||||
expect(doclet).to(have_property, 'description');
|
||||
expect(doclet.description).to(eql, 'Here is a description.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a named @property after to a constructor tag', function() {
|
||||
it('should be a constructor', function() {
|
||||
var doclet = doclets[4].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
|
||||
expect(doclet.kind).to(eql, 'constructor');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a named @var tag and a description', function() {
|
||||
it('should have an `kind` property set to "property"', function() {
|
||||
var doclet = doclets[5].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'property');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name', function() {
|
||||
var doclet = doclets[5].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'zub');
|
||||
});
|
||||
|
||||
it('should have a `description` property set to the given description', function() {
|
||||
var doclet = doclets[5].toObject();
|
||||
expect(doclet).to(have_property, 'description');
|
||||
expect(doclet.description).to(eql, 'The description here.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with no name and a typed @property tag', function() {
|
||||
it('should have an `kind` property set to "property"', function() {
|
||||
var doclet = doclets[6].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'property');
|
||||
});
|
||||
|
||||
it('should have a `type` property set to the given type', function() {
|
||||
var doclet = doclets[6].toObject();
|
||||
expect(doclet).to(have_property, 'type');
|
||||
expect(doclet.type).to(eql, 'Function');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the name in the code', function() {
|
||||
var doclet = doclets[6].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'onShow');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
|
||||
(function testarea() {
|
||||
|
||||
/** @namespace foo */
|
||||
var foo = {}, onShow, callbacks = [function(){}];
|
||||
/** @constructor bar */
|
||||
|
||||
/** @property foo.fah */
|
||||
|
||||
/** @property {string|number} bar.bah Here is a description. */
|
||||
|
||||
/** @constructor Zub
|
||||
@property {string} zip
|
||||
*/
|
||||
|
||||
/** @var zub - The description here. */
|
||||
|
||||
/** @property {Function} */
|
||||
onShow = callbacks[0];
|
||||
|
||||
})();
|
||||
@ -1,86 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@method', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/tests/13_tag_method.js');
|
||||
doclets = jsdoc.parser.result;
|
||||
});
|
||||
|
||||
describe('A doclet with a named @method attached to a namespace', function() {
|
||||
it('should have an `kind` property set to "method"', function() {
|
||||
var doclet = doclets[2].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'method');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[2].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'fah');
|
||||
});
|
||||
|
||||
it('should have a `memberof` property set to the parent object name', function() {
|
||||
var doclet = doclets[2].toObject();
|
||||
expect(doclet).to(have_property, 'memberof');
|
||||
expect(doclet.memberof).to(eql, 'foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a named @method attached to a constructor', function() {
|
||||
it('should have an `kind` property set to "method"', function() {
|
||||
var doclet = doclets[3].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'method');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[3].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'bah');
|
||||
});
|
||||
|
||||
it('should have a `memberof` property set to the parent object name', function() {
|
||||
var doclet = doclets[3].toObject();
|
||||
expect(doclet).to(have_property, 'memberof');
|
||||
expect(doclet.memberof).to(eql, 'bar');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a named @function tag', function() {
|
||||
it('should have an `kind` property set to "method"', function() {
|
||||
var doclet = doclets[4].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'method');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[4].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'zub');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
|
||||
(function testarea() {
|
||||
|
||||
/** @namespace foo */
|
||||
|
||||
/** @constructor bar */
|
||||
|
||||
/** @method foo.fah */
|
||||
|
||||
/** @method bar.bah */
|
||||
|
||||
/** @function zub */
|
||||
|
||||
})();
|
||||
@ -1,149 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@member', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_member.js');
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
|
||||
});
|
||||
|
||||
describe('A doclet with a method tag and a memberof tag that ends in "prototype"', function() {
|
||||
it('should have an `kind` property set to "method"', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'method');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'fah');
|
||||
});
|
||||
|
||||
it('should have a `memberof` property set to the given member name', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'memberof');
|
||||
expect(doclet.memberof).to(eql, 'foo');
|
||||
});
|
||||
|
||||
it('should have a `scope` property set to "instance"', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'scope');
|
||||
expect(doclet.scope).to(eql, 'instance');
|
||||
});
|
||||
|
||||
it('should have a `path` property set to the parent+member names', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'foo#fah');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a property tag and a member tag', function() {
|
||||
it('should have an `kind` property set to "property"', function() {
|
||||
var doclet = doclets[3];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'property');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[3];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'bah');
|
||||
});
|
||||
|
||||
it('should have a `memberof` property set to the given member name', function() {
|
||||
var doclet = doclets[3];
|
||||
expect(doclet).to(have_property, 'memberof');
|
||||
expect(doclet.memberof).to(eql, 'bar');
|
||||
});
|
||||
|
||||
it('should have a `path` property set to the parent+member names', function() {
|
||||
var doclet = doclets[3];
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'bar.bah');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a property tag and a member tag and an inner tag', function() {
|
||||
it('should have an `kind` property set to "property"', function() {
|
||||
var doclet = doclets[4];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'property');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[4];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'bish');
|
||||
});
|
||||
|
||||
it('should have a `memberof` property set to the given member name', function() {
|
||||
var doclet = doclets[4];
|
||||
expect(doclet).to(have_property, 'memberof');
|
||||
expect(doclet.memberof).to(eql, 'bar');
|
||||
});
|
||||
|
||||
it('should have a `path` property set to the memberof~name', function() {
|
||||
var doclet = doclets[4];
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'bar~bish');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a property tag and a member tag and an instance access tag', function() {
|
||||
it('should have an `kind` property set to "property"', function() {
|
||||
var doclet = doclets[5];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'property');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[5];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'bosh');
|
||||
});
|
||||
|
||||
it('should have a `memberof` property set to the given member name', function() {
|
||||
var doclet = doclets[5];
|
||||
expect(doclet).to(have_property, 'memberof');
|
||||
expect(doclet.memberof).to(eql, 'bar');
|
||||
});
|
||||
|
||||
it('should have a `path` property set to the memberof~name', function() {
|
||||
var doclet = doclets[5];
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'bar#bosh');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a property tag and a member tag and an instance access tag', function() {
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[8];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'innie');
|
||||
});
|
||||
|
||||
it('should have a `memberof` property set to the given member name', function() {
|
||||
var doclet = doclets[8];
|
||||
expect(doclet).to(have_property, 'memberof');
|
||||
expect(doclet.memberof).to(eql, 'foo');
|
||||
});
|
||||
|
||||
it('should have a `path` property set to the memberof~name', function() {
|
||||
var doclet = doclets[8];
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'foo~innie');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
@ -1,52 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@type', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_type.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet with a type tag whose value is a simple string like "number"', function() {
|
||||
it('should have an `type` property set to that string', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'type');
|
||||
expect(doclet.type).to(eql, 'number');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a type tag whose value is a series of piped strings like "number | Array.<number>"', function() {
|
||||
it('should have an `type` property set to an array of those types', function() {
|
||||
var doclet = doclets[3];
|
||||
expect(doclet).to(have_property, 'type');
|
||||
|
||||
expect(doclet.type).to(eql, ['number', 'Array.<number>']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a type tag whose value contains inner braces like "{{myNum: number, myObject}|function(string:a, string:b){}:number}"', function() {
|
||||
it('should have an `type` property set to those types, regardless of the inner braces', function() {
|
||||
var doclet = doclets[4];
|
||||
expect(doclet).to(have_property, 'type');
|
||||
|
||||
expect(doclet.type).to(eql, ['{myNum: number, myObject}', 'function(string:a, string:b){}:number']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a type tag whose value contains a union of two types, surrounded by parens', function() {
|
||||
it('should have an `type` property set to those two types', function() {
|
||||
var doclet = doclets[5];
|
||||
expect(doclet).to(have_property, 'type');
|
||||
expect(doclet.type).to(eql, ['string', 'number']);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
@ -1,91 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@return', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/tests/16_tag_return.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet with a returns tag whose value has a type and description', function() {
|
||||
it('should have an `returns` property', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'returns');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The returns value of that doclet', function() {
|
||||
it('should have a single `type` documented as the given type', function() {
|
||||
var returns = doclets[0].returns;
|
||||
expect(returns).to(have_property, 'type');
|
||||
expect(returns.type).to(eql, 'number');
|
||||
});
|
||||
|
||||
it('should have an `description` property set to the given description', function() {
|
||||
var returns = doclets[0].returns;
|
||||
expect(returns).to(have_property, 'description');
|
||||
expect(returns.description).to(eql, 'The size of the foo.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a (synonym) return tag whose value has a description', function() {
|
||||
it('should have an `returns` property', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet).to(have_property, 'returns');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The returns value of that doclet', function() {
|
||||
it('should have an `description` property set to the given description', function() {
|
||||
var returns = doclets[1].returns;
|
||||
expect(returns).to(have_property, 'description');
|
||||
expect(returns.description).to(eql, 'So a horse walks into a....');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The returns value of a doclet with multiple @returns', function() {
|
||||
it('should only have the first return documented.', function() {
|
||||
var returns = doclets[2].returns;
|
||||
expect(returns).to(have_property, 'description');
|
||||
expect(returns.description).to(eql, 'And so forth.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The return with multiple types', function() {
|
||||
it('should document those types as an array.', function() {
|
||||
var returns = doclets[2].returns;
|
||||
expect(returns).to(have_property, 'type');
|
||||
expect(returns.type).to(eql, ['number', 'string']);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
|
||||
(function testarea() {
|
||||
|
||||
/**
|
||||
@function foo
|
||||
@returns {number} The size of the foo.
|
||||
*/
|
||||
|
||||
/**
|
||||
@function bar
|
||||
@return So a horse walks into a....
|
||||
*/
|
||||
|
||||
/**
|
||||
@function baz
|
||||
@returns {number|string} And so forth.
|
||||
@returns And so on.
|
||||
*/
|
||||
|
||||
})();
|
||||
@ -1,56 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@example', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/tests/17_tag_example.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet with a @example tag', function() {
|
||||
it('should have an `example` property', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'example');
|
||||
});
|
||||
});
|
||||
|
||||
describe('the value of the `example` property', function() {
|
||||
it('should preserve all whitespace', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet.example).to(eql, ' var myresult;\n myresult = foo(a, b);\n');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with 2 @example tags', function() {
|
||||
it('should have an `example` property with length of 2', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet).to(have_property, 'example');
|
||||
expect(doclet.example.length).to(eql, 2);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
(function testarea() {
|
||||
|
||||
/**
|
||||
* @function foo
|
||||
* @example
|
||||
* var myresult;
|
||||
* myresult = foo(a, b);
|
||||
*/
|
||||
|
||||
/**
|
||||
* @function bar
|
||||
* @example one fish
|
||||
* @example two fish
|
||||
*/
|
||||
})();
|
||||
@ -1,35 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@class', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_class.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet from a class tag with a name tag and no code', function() {
|
||||
it('should have an `kind` property set to "constructor"', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'constructor');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'Foo');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
})();
|
||||
@ -1,126 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@param', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_param.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet with two param tags', function() {
|
||||
it('should have an `param` property that is an array of length 2', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'param');
|
||||
expect(doclet.param).to(be_an, Array);
|
||||
expect(doclet.param).to(have_length, 2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a param tag whose value is a simple string like "address"', function() {
|
||||
it('should have an `param` property with a `name` set to "address', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet.param[0]).to(have_property, 'name');
|
||||
expect(doclet.param[0].name).to(eql, 'address');
|
||||
expect(doclet.param[1]).to(have_property, 'name');
|
||||
expect(doclet.param[1].name).to(eql, 'message');
|
||||
});
|
||||
|
||||
it('should not have a `type` or `description` property ', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet.param[0].type).to(be_undefined);
|
||||
expect(doclet.param[0].description).to(be_undefined);
|
||||
expect(doclet.param[1].type).to(be_undefined);
|
||||
expect(doclet.param[1].description).to(be_undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a param tag whose value is a type specifier like {string}', function() {
|
||||
it('should have a `param` property with a `type` set to "string"', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet).to(have_property, 'param');
|
||||
expect(doclet.param).to(have_length, 2);
|
||||
expect(doclet.param[0]).to(have_property, 'type');
|
||||
expect(doclet.param[0].type).to(eql, 'string');
|
||||
expect(doclet.param[1]).to(have_property, 'type');
|
||||
expect(doclet.param[1].type).to(eql, 'string');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with one param tag', function() {
|
||||
it('should have a `param` property that is an array', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'param');
|
||||
expect(doclet.param).to(be_an, Array);
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with one param tag having a type and a name', function() {
|
||||
it('should have a `param` array with a single member with a `type` and `name`', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'param');
|
||||
expect(doclet.param[0].type.push).to(be_undefined); // types are only arrays when there are many
|
||||
expect(doclet.param[0].type).to(eql, 'string');
|
||||
expect(doclet.param[0].name).to(be_an, String);
|
||||
expect(doclet.param[0].name).to(eql, 'str');
|
||||
});
|
||||
|
||||
it('should not have a `description`', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet.param.description).to(be_undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with one param tag having a type, name and a description', function() {
|
||||
it('should have a `param` array with a single member with a `type`, `name` and `description`', function() {
|
||||
var doclet = doclets[3];
|
||||
expect(doclet).to(have_property, 'param');
|
||||
expect(doclet.param[0].type).to(eql, 'string');
|
||||
expect(doclet.param[0].name).to(be_an, String);
|
||||
expect(doclet.param[0].name).to(eql, 'message');
|
||||
expect(doclet.param[0].description).to(be_an, String);
|
||||
expect(doclet.param[0].description).to(eql, 'the message to encrypt.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A param tag using the dash syntax with a `type`, `name` and `description`', function() {
|
||||
it('should have a `type`, `name` and `description`', function() {
|
||||
var param = doclets[4].param[0];
|
||||
expect(param.type).to(eql, 'Panel');
|
||||
expect(param.name).to(be_an, String);
|
||||
expect(param.name).to(eql, 'p');
|
||||
expect(param.description).to(be_an, String);
|
||||
expect(param.description).to(eql, 'The panel to update.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A param tag using the dash syntax with just a `description`', function() {
|
||||
it('should have a `description` but no `type` or `name`', function() {
|
||||
var param = doclets[4].param[1];
|
||||
expect(param.description).to(be_an, String);
|
||||
expect(param.description).to(eql, 'The new content.');
|
||||
expect(param.name).to(be_undefined);
|
||||
expect(param.type).to(be_undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('A param tag using the dash syntax with a `type` and a `description`', function() {
|
||||
it('should have a `description` and `type` but no `name`', function() {
|
||||
var param = doclets[4].param[2];
|
||||
expect(param.type).to(be_an, String);
|
||||
expect(param.type).to(eql, 'boolean');
|
||||
expect(param.description).to(be_an, String);
|
||||
expect(param.description).to(eql, 'Don\'t replace existing content.');
|
||||
expect(param.name).to(be_undefined);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
@ -1,32 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@file', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_file_1.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet with a fileoverview tag and no name tag', function() {
|
||||
it('should have an `kind` property set to "file"', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'file');
|
||||
});
|
||||
|
||||
it('should have an `name` property set to a string equal to the files name', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(match, /test\/samples\/tag_file_1\.js$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
@ -1,51 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@property', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_const.js');
|
||||
doclets = jsdoc.parser.result;
|
||||
});
|
||||
|
||||
describe('A doclet with a @const tag having a type and no given name', function() {
|
||||
it('should have an `kind` property set to "constant"', function() {
|
||||
var doclet = doclets[0].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'constant');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the name in the code', function() {
|
||||
var doclet = doclets[0].toObject();
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'MY_BEER');
|
||||
});
|
||||
|
||||
it('should have a `type` property set to the given type', function() {
|
||||
var doclet = doclets[0].toObject();
|
||||
expect(doclet).to(have_property, 'type');
|
||||
expect(doclet.type).to(eql, 'string');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a @const tag and a type', function() {
|
||||
it('should have an `kind` property set to "constant"', function() {
|
||||
var doclet = doclets[1].toObject();
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'constant');
|
||||
});
|
||||
|
||||
it('should have an `type` property set to the given type', function() {
|
||||
var doclet = doclets[1].toObject();
|
||||
expect(doclet).to(have_property, 'type');
|
||||
expect(doclet.type).to(eql, 'string');
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
@ -1,23 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@preserve', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_preserve.js');
|
||||
doclets = jsdoc.parser.result;
|
||||
});
|
||||
|
||||
describe('A doclet with a only a @preserve tag', function() {
|
||||
it('should not appear in the output', function() {
|
||||
expect(doclets).to(have_length, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
@ -1,40 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@fires', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_fires.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet with a a @fires tag', function() {
|
||||
it('should have a `fires` property', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'fires');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The value of the `fires` property', function() {
|
||||
it('should be equal to the given tag value', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet.fires).to(eql, 'event:disable');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a 2 @fires tags', function() {
|
||||
it('should have a `fires` property set to an array of length 2', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet).to(have_property, 'fires');
|
||||
expect(doclet.fires).to(have_length, 2);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
@ -1,47 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@exception', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_exception.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet with a a @exception tag', function() {
|
||||
it('should have a `exception` property', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'exception');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The type of the `exception` property', function() {
|
||||
it('should be equal to the type of the given tag value', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet.exception.type).to(eql, 'divideByZeroError');
|
||||
});
|
||||
});
|
||||
|
||||
describe('The value of the `exception` property', function() {
|
||||
it('should be equal to the description of the given tag value', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet.exception.description).to(eql, 'Denominator param cannot be zero.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with a 2 @exception tags', function() {
|
||||
it('should have a `exception` property set to an array of length 2', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet).to(have_property, 'exception');
|
||||
expect(doclet.exception).to(have_length, 2);
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
@ -1,98 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@scope', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_scope.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet with global scope', function() {
|
||||
it('should have a `scope` property of type string equalling "global"', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'scope');
|
||||
expect(doclet.scope).to(be_an, String);
|
||||
expect(doclet.scope).to(be, 'global');
|
||||
});
|
||||
|
||||
it('should have a `path` property of type string equalling its namepath', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(be_an, String);
|
||||
expect(doclet.path).to(be, 'outie');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with inner scope', function() {
|
||||
it('should have a `scope` property of type string equalling "inner"', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet).to(have_property, 'scope');
|
||||
expect(doclet.scope).to(be_an, String);
|
||||
expect(doclet.scope).to(be, 'inner');
|
||||
});
|
||||
|
||||
it('should have a `path` property of type string equalling its namepath', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(be_an, String);
|
||||
expect(doclet.path).to(be, 'outie~innie');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with static scope', function() {
|
||||
it('should have a `scope` property of type string equalling "static"', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'scope');
|
||||
expect(doclet.scope).to(be_an, String);
|
||||
expect(doclet.scope).to(be, 'static');
|
||||
});
|
||||
|
||||
it('should have a `path` property of type string equalling its namepath', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(be_an, String);
|
||||
expect(doclet.path).to(be, 'outie.stat');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A var doclet with global scope', function() {
|
||||
it('should have a `scope` property of type string equalling "global"', function() {
|
||||
var doclet = doclets[3];
|
||||
expect(doclet).to(have_property, 'scope');
|
||||
expect(doclet.scope).to(be_an, String);
|
||||
expect(doclet.scope).to(be, 'global');
|
||||
});
|
||||
|
||||
it('should have a `path` property of type string equalling its namepath', function() {
|
||||
var doclet = doclets[3];
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(be_an, String);
|
||||
expect(doclet.path).to(be, 'varoutie');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A var doclet with inner scope', function() {
|
||||
it('should have a `scope` property of type string equalling "inner"', function() {
|
||||
var doclet = doclets[4];
|
||||
expect(doclet).to(have_property, 'scope');
|
||||
expect(doclet.scope).to(be_an, String);
|
||||
expect(doclet.scope).to(be, 'inner');
|
||||
});
|
||||
|
||||
it('should have a `path` property of type string equalling its namepath', function() {
|
||||
var doclet = doclets[4];
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(be_an, String);
|
||||
expect(doclet.path).to(be, 'varoutie~varinnie');
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
@ -1,52 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@tag', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_tag.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet with single @tag <name>', function() {
|
||||
it('should have a `tag` property of type array with a single member', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'tags');
|
||||
expect(doclet.tags).to(be_an, Array);
|
||||
expect(doclet.tags.length).to(be, 1);
|
||||
});
|
||||
|
||||
it('that tag should have a name property set to <name>, and no description property', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet.tags[0]).to(be_an, String);
|
||||
expect(doclet.tags[0]).to(be, 'hilited');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with two @tag <name>', function() {
|
||||
it('should have a tag with a name property set to <name>, and description set to <description>', function() {
|
||||
var doclet = doclets[1];
|
||||
expect(doclet.tags[0]).to(be_an, String);
|
||||
expect(doclet.tags[0]).to(be, 'experimental');
|
||||
|
||||
expect(doclet.tags[1]).to(be_an, String);
|
||||
expect(doclet.tags[1]).to(be, 'lots of words');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet with an empty @tag', function() {
|
||||
it('should have no tag property', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet.tags).to(be_undefined);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
@ -1,47 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@module', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_module.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet that lists a module', function() {
|
||||
it('should have an `kind` property set to "module"', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'kind');
|
||||
expect(doclet.kind).to(eql, 'module');
|
||||
});
|
||||
|
||||
it('should have a `name` property set to the given name"', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, './webui/utils.strings');
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'module:"./webui/utils.strings"');
|
||||
});
|
||||
});
|
||||
|
||||
describe('A function exported by a moduke', function() {
|
||||
it('should a path that includes the name of the module', function() {
|
||||
var doclet = doclets[1];
|
||||
|
||||
expect(doclet).to(have_property, 'name');
|
||||
expect(doclet.name).to(eql, 'twiddle');
|
||||
expect(doclet).to(have_property, 'path');
|
||||
expect(doclet.path).to(eql, 'module:"./webui/utils.strings".twiddle');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
@ -1,43 +0,0 @@
|
||||
(function() {
|
||||
var jsdoc,
|
||||
doclets;
|
||||
|
||||
JSpec.describe('@module', function() {
|
||||
|
||||
before(function() {
|
||||
// docsets can only be created by parsers
|
||||
jsdoc = {
|
||||
tag: require('jsdoc/tag'),
|
||||
parser: require('jsdoc/parser')
|
||||
};
|
||||
|
||||
jsdoc.parser.parseFiles(BASEDIR + 'test/samples/etc_requirejs.js');
|
||||
|
||||
doclets = jsdoc.parser.result.map(function($){ return $.toObject(); });
|
||||
});
|
||||
|
||||
describe('A doclet that lists a module with no requires', function() {
|
||||
it('should have no `requires`', function() {
|
||||
var doclet = doclets[0];
|
||||
expect(doclet.requires).to(be_undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet that requires a module', function() {
|
||||
it('should have the required module listed in its `requires` property', function() {
|
||||
var doclet = doclets[2];
|
||||
expect(doclet).to(have_property, 'requires');
|
||||
expect(doclet.requires).to(be_an, String)
|
||||
});
|
||||
});
|
||||
|
||||
describe('A doclet that requires many modules', function() {
|
||||
it('should have all the required module listed in its `requires` property', function() {
|
||||
var doclet = doclets[4];
|
||||
expect(doclet).to(have_property, 'requires');
|
||||
expect(doclet.requires).to(be_an, Array)
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
Loading…
x
Reference in New Issue
Block a user