mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-11-04 00:08:00 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
@overview Demonstrate how to modify the source code before the parser sees it.
|
||||
@module plugins/commentConvert
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/*eslint spaced-line-comment: 0 */
|
||||
|
||||
exports.handlers = {
|
||||
///
|
||||
/// Convert ///-style comments into jsdoc comments.
|
||||
/// @param e
|
||||
/// @param e.filename
|
||||
/// @param e.source
|
||||
///
|
||||
beforeParse: function(e) {
|
||||
e.source = e.source.replace(/(\n[ \t]*\/\/\/[^\n]*)+/g, function($) {
|
||||
var replacement = '\n/**' + $.replace(/^[ \t]*\/\/\//mg, '').replace(/(\n$|$)/, '*/$1');
|
||||
return replacement;
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @overview Remove everything in a file except JSDoc-style comments. By enabling this plugin, you
|
||||
* can document source files that are not valid JavaScript (including source files for other
|
||||
* languages).
|
||||
* @module plugins/commentsOnly
|
||||
* @author Jeff Williams <jeffrey.l.williams@gmail.com>
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
exports.handlers = {
|
||||
beforeParse: function(e) {
|
||||
// a JSDoc comment looks like: /**[one or more chars]*/
|
||||
var comments = e.source.match(/\/\*\*[\s\S]+?\*\//g);
|
||||
if (comments) {
|
||||
e.source = comments.join('\n\n');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
@overview Escape HTML tags in descriptions.
|
||||
@module plugins/escapeHtml
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
exports.handlers = {
|
||||
/**
|
||||
Translate HTML tags in descriptions into safe entities.
|
||||
Replaces <, & and newlines
|
||||
*/
|
||||
newDoclet: function(e) {
|
||||
if (e.doclet.description) {
|
||||
e.doclet.description = e.doclet.description
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/\r\n|\n|\r/g, '<br>');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,115 @@
|
||||
/*global env: true */
|
||||
/**
|
||||
* @overview Dump information about parser events to the console.
|
||||
* @module plugins/eventDumper
|
||||
* @author Jeff Williams <jeffrey.l.williams@gmail.com>
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var _ = require('underscore');
|
||||
var util = require('util');
|
||||
|
||||
var conf = env.conf.eventDumper || {};
|
||||
var isRhino = require('jsdoc/util/runtime').isRhino();
|
||||
|
||||
// Dump the included parser events (defaults to all events)
|
||||
var events = conf.include || [
|
||||
'parseBegin',
|
||||
'fileBegin',
|
||||
'beforeParse',
|
||||
'jsdocCommentFound',
|
||||
'symbolFound',
|
||||
'newDoclet',
|
||||
'fileComplete',
|
||||
'parseComplete',
|
||||
'processingComplete'
|
||||
];
|
||||
// Don't dump the excluded parser events
|
||||
if (conf.exclude) {
|
||||
events = _.difference(events, conf.exclude);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a variable appears to be a Java native object.
|
||||
*
|
||||
* @param {*} o - The variable to check.
|
||||
* @return {boolean} Set to `true` for Java native objects and `false` in all other cases.
|
||||
*/
|
||||
function isJavaNativeObject(o) {
|
||||
if (!isRhino) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return o && typeof o === 'object' && typeof o.getClass === 'function';
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace AST node objects in events with a placeholder.
|
||||
*
|
||||
* @param {Object} o - An object whose properties may contain AST node objects.
|
||||
* @return {Object} The modified object.
|
||||
*/
|
||||
function replaceNodeObjects(o) {
|
||||
var doop = require('jsdoc/util/doop');
|
||||
|
||||
var OBJECT_PLACEHOLDER = '<Object>';
|
||||
|
||||
if (o.code && o.code.node) {
|
||||
// don't break the original object!
|
||||
o.code = doop(o.code);
|
||||
o.code.node = OBJECT_PLACEHOLDER;
|
||||
}
|
||||
|
||||
if (o.doclet && o.doclet.meta && o.doclet.meta.code && o.doclet.meta.code.node) {
|
||||
// don't break the original object!
|
||||
o.doclet.meta.code = doop(o.doclet.meta.code);
|
||||
o.doclet.meta.code.node = OBJECT_PLACEHOLDER;
|
||||
}
|
||||
|
||||
if (o.astnode) {
|
||||
o.astnode = OBJECT_PLACEHOLDER;
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rid of unwanted crud in an event object.
|
||||
*
|
||||
* @param {object} e The event object.
|
||||
* @return {object} The fixed-up object.
|
||||
*/
|
||||
function cleanse(e) {
|
||||
var result = {};
|
||||
|
||||
Object.keys(e).forEach(function(prop) {
|
||||
// by default, don't stringify properties that contain an array of functions
|
||||
if (!conf.includeFunctions && util.isArray(e[prop]) && e[prop][0] &&
|
||||
String(typeof e[prop][0]) === 'function') {
|
||||
result[prop] = 'function[' + e[prop].length + ']';
|
||||
}
|
||||
// never include functions that belong to the object
|
||||
else if (typeof e[prop] !== 'function') {
|
||||
// don't call JSON.stringify() on Java native objects--Rhino will throw an exception
|
||||
result[prop] = isJavaNativeObject(e[prop]) ? String(e[prop]) : e[prop];
|
||||
}
|
||||
});
|
||||
|
||||
// allow users to omit node objects, which can be enormous
|
||||
if (conf.omitNodes) {
|
||||
result = replaceNodeObjects(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
exports.handlers = {};
|
||||
|
||||
events.forEach(function(eventType) {
|
||||
exports.handlers[eventType] = function(e) {
|
||||
console.log( JSON.stringify({
|
||||
type: eventType,
|
||||
content: cleanse(e)
|
||||
}, null, 4) );
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @overview Translate doclet descriptions from MarkDown into HTML.
|
||||
* @module plugins/markdown
|
||||
* @author Michael Mathews <micmath@gmail.com>
|
||||
* @author Ben Blank <ben.blank@gmail.com>
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var config = global.env.conf.markdown || {};
|
||||
var defaultTags = [
|
||||
'classdesc',
|
||||
'description',
|
||||
'exceptions',
|
||||
'params',
|
||||
'properties',
|
||||
'returns',
|
||||
'see'
|
||||
];
|
||||
var hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var parse = require('jsdoc/util/markdown').getParser();
|
||||
var tags = [];
|
||||
var excludeTags = [];
|
||||
|
||||
function shouldProcessString(tagName, text) {
|
||||
var shouldProcess = false;
|
||||
|
||||
if (tagName !== 'see') {
|
||||
shouldProcess = true;
|
||||
}
|
||||
// we only want to process `@see` tags that contain Markdown links
|
||||
else if (tagName === 'see' && text.indexOf('[') !== -1) {
|
||||
shouldProcess = true;
|
||||
}
|
||||
|
||||
return shouldProcess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the markdown source in a doclet. The properties that should be
|
||||
* processed are configurable, but always include "classdesc", "description",
|
||||
* "params", "properties", and "returns". Handled properties can be bare
|
||||
* strings, objects, or arrays of objects.
|
||||
*/
|
||||
function process(doclet) {
|
||||
tags.forEach(function(tag) {
|
||||
if ( !hasOwnProp.call(doclet, tag) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof doclet[tag] === 'string' && shouldProcessString(tag, doclet[tag]) ) {
|
||||
doclet[tag] = parse(doclet[tag]);
|
||||
}
|
||||
else if ( Array.isArray(doclet[tag]) ) {
|
||||
doclet[tag].forEach(function(value, index, original) {
|
||||
var inner = {};
|
||||
inner[tag] = value;
|
||||
process(inner);
|
||||
original[index] = inner[tag];
|
||||
});
|
||||
}
|
||||
else if (doclet[tag]) {
|
||||
process(doclet[tag]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// set up the list of "tags" (properties) to process
|
||||
if (config.tags) {
|
||||
tags = config.tags.slice();
|
||||
}
|
||||
// set up the list of default tags to exclude from processing
|
||||
if (config.excludeTags) {
|
||||
excludeTags = config.excludeTags.slice();
|
||||
}
|
||||
defaultTags.forEach(function(tag) {
|
||||
if (excludeTags.indexOf(tag) === -1 && tags.indexOf(tag) === -1) {
|
||||
tags.push(tag);
|
||||
}
|
||||
});
|
||||
|
||||
exports.handlers = {
|
||||
/**
|
||||
* Translate markdown syntax in a new doclet's description into HTML. Is run
|
||||
* by JSDoc 3 whenever a "newDoclet" event fires.
|
||||
*/
|
||||
newDoclet: function(e) {
|
||||
process(e.doclet);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* The Overload Helper plugin automatically adds a signature-like string to the longnames of
|
||||
* overloaded functions and methods. In JSDoc, this string is known as a _variation_. (The longnames
|
||||
* of overloaded constructor functions are _not_ updated, so that JSDoc can identify the class'
|
||||
* members correctly.)
|
||||
*
|
||||
* Using this plugin allows you to link to overloaded functions without manually adding `@variation`
|
||||
* tags to your documentation.
|
||||
*
|
||||
* For example, suppose your code includes a function named `foo` that you can call in the
|
||||
* following ways:
|
||||
*
|
||||
* + `foo()`
|
||||
* + `foo(bar)`
|
||||
* + `foo(bar, baz)` (where `baz` is repeatable)
|
||||
*
|
||||
* This plugin assigns the following variations and longnames to each version of `foo`:
|
||||
*
|
||||
* + `foo()` gets the variation `()` and the longname `foo()`.
|
||||
* + `foo(bar)` gets the variation `(bar)` and the longname `foo(bar)`.
|
||||
* + `foo(bar, baz)` (where `baz` is repeatable) gets the variation `(bar, ...baz)` and the longname
|
||||
* `foo(bar, ...baz)`.
|
||||
*
|
||||
* You can then link to these functions with `{@link foo()}`, `{@link foo(bar)}`, and
|
||||
* `{@link foo(bar, ...baz)`. Note that the variation is based on the names of the function
|
||||
* parameters, _not_ their types.
|
||||
*
|
||||
* If you prefer to manually assign variations to certain functions, you can still do so with the
|
||||
* `@variation` tag. This plugin will not change these variations or add more variations for that
|
||||
* function, as long as the variations you've defined result in unique longnames.
|
||||
*
|
||||
* If an overloaded function includes multiple signatures with the same parameter names, the plugin
|
||||
* will assign numeric variations instead, starting at `(1)` and counting upwards.
|
||||
*
|
||||
* @module plugins/overloadHelper
|
||||
* @author Jeff Williams <jeffrey.l.williams@gmail.com>
|
||||
* @license Apache License 2.0
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
// lookup table of function doclets by longname
|
||||
var functionDoclets;
|
||||
|
||||
function hasUniqueValues(obj) {
|
||||
var isUnique = true;
|
||||
var seen = [];
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
if (seen.indexOf(obj[key]) !== -1) {
|
||||
isUnique = false;
|
||||
}
|
||||
|
||||
seen.push(obj[key]);
|
||||
});
|
||||
|
||||
return isUnique;
|
||||
}
|
||||
|
||||
function getParamNames(params) {
|
||||
var names = [];
|
||||
|
||||
params.forEach(function(param) {
|
||||
var name = param.name || '';
|
||||
if (param.variable) {
|
||||
name = '...' + name;
|
||||
}
|
||||
if (name !== '') {
|
||||
names.push(name);
|
||||
}
|
||||
});
|
||||
|
||||
return names.length ? names.join(', ') : '';
|
||||
}
|
||||
|
||||
function getParamVariation(doclet) {
|
||||
return getParamNames(doclet.params || []);
|
||||
}
|
||||
|
||||
function getUniqueVariations(doclets) {
|
||||
var counter = 0;
|
||||
var variations = {};
|
||||
var docletKeys = Object.keys(doclets);
|
||||
|
||||
function getUniqueNumbers() {
|
||||
var format = require('util').format;
|
||||
|
||||
docletKeys.forEach(function(doclet) {
|
||||
var newLongname;
|
||||
|
||||
while (true) {
|
||||
counter++;
|
||||
variations[doclet] = String(counter);
|
||||
|
||||
// is this longname + variation unique?
|
||||
newLongname = format('%s(%s)', doclets[doclet].longname, variations[doclet]);
|
||||
if ( !functionDoclets[newLongname] ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getUniqueNames() {
|
||||
// start by trying to preserve existing variations
|
||||
docletKeys.forEach(function(doclet) {
|
||||
variations[doclet] = doclets[doclet].variation || getParamVariation(doclets[doclet]);
|
||||
});
|
||||
|
||||
// if they're identical, try again, without preserving existing variations
|
||||
if ( !hasUniqueValues(variations) ) {
|
||||
docletKeys.forEach(function(doclet) {
|
||||
variations[doclet] = getParamVariation(doclets[doclet]);
|
||||
});
|
||||
|
||||
// if they're STILL identical, switch to numeric variations
|
||||
if ( !hasUniqueValues(variations) ) {
|
||||
getUniqueNumbers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// are we already using numeric variations? if so, keep doing that
|
||||
if (functionDoclets[doclets.newDoclet.longname + '(1)']) {
|
||||
getUniqueNumbers();
|
||||
}
|
||||
else {
|
||||
getUniqueNames();
|
||||
}
|
||||
|
||||
return variations;
|
||||
}
|
||||
|
||||
function ensureUniqueLongname(newDoclet) {
|
||||
var doclets = {
|
||||
oldDoclet: functionDoclets[newDoclet.longname],
|
||||
newDoclet: newDoclet
|
||||
};
|
||||
var docletKeys = Object.keys(doclets);
|
||||
var oldDocletLongname;
|
||||
var variations = {};
|
||||
|
||||
if (doclets.oldDoclet) {
|
||||
oldDocletLongname = doclets.oldDoclet.longname;
|
||||
// if the shared longname has a variation, like MyClass#myLongname(variation),
|
||||
// remove the variation
|
||||
if (doclets.oldDoclet.variation || doclets.oldDoclet.variation === '') {
|
||||
docletKeys.forEach(function(doclet) {
|
||||
doclets[doclet].longname = doclets[doclet].longname.replace(/\([\s\S]*\)$/, '');
|
||||
doclets[doclet].variation = null;
|
||||
});
|
||||
}
|
||||
|
||||
variations = getUniqueVariations(doclets);
|
||||
|
||||
// update the longnames/variations
|
||||
docletKeys.forEach(function(doclet) {
|
||||
doclets[doclet].longname += '(' + variations[doclet] + ')';
|
||||
doclets[doclet].variation = variations[doclet];
|
||||
});
|
||||
|
||||
// update the old doclet in the lookup table
|
||||
functionDoclets[oldDocletLongname] = null;
|
||||
functionDoclets[doclets.oldDoclet.longname] = doclets.oldDoclet;
|
||||
}
|
||||
|
||||
// always store the new doclet in the lookup table
|
||||
functionDoclets[doclets.newDoclet.longname] = doclets.newDoclet;
|
||||
|
||||
return doclets.newDoclet;
|
||||
}
|
||||
|
||||
exports.handlers = {
|
||||
parseBegin: function() {
|
||||
functionDoclets = {};
|
||||
},
|
||||
|
||||
newDoclet: function(e) {
|
||||
if (e.doclet.kind === 'function') {
|
||||
e.doclet = ensureUniqueLongname(e.doclet);
|
||||
}
|
||||
},
|
||||
|
||||
parseComplete: function() {
|
||||
functionDoclets = null;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
@overview Adds support for reusable partial jsdoc files.
|
||||
@module plugins/partial
|
||||
@author Ludo Antonov <ludo@hulu.com>
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var fs = require('jsdoc/fs');
|
||||
var path = require('path');
|
||||
|
||||
exports.handlers = {
|
||||
/**
|
||||
* Include a partial jsdoc
|
||||
*
|
||||
* @param e
|
||||
* @param e.filename
|
||||
* @param e.source
|
||||
* @example
|
||||
* @partial "partial_doc.jsdoc"
|
||||
*/
|
||||
beforeParse: function(e) {
|
||||
e.source = e.source.replace(/(@partial \".*\")+/g, function($) {
|
||||
var pathArg = $.match(/\".*\"/)[0].replace(/"/g, '');
|
||||
var fullPath = path.join(e.filename, '..', pathArg);
|
||||
|
||||
var partialData = fs.readFileSync(fullPath, global.env.opts.encoding);
|
||||
|
||||
return partialData;
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
@overview Strips the rails template tags from a js.erb file
|
||||
@module plugins/railsTemplate
|
||||
@author Jannon Frank <jannon@jannon.net>
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
exports.handlers = {
|
||||
/**
|
||||
* Remove rails tags from the source input (e.g. <% foo bar %>)
|
||||
* @param e
|
||||
* @param e.filename
|
||||
* @param e.source
|
||||
*/
|
||||
beforeParse: function(e) {
|
||||
if (e.filename.match(/\.erb$/)) {
|
||||
e.source = e.source.replace(/<%.*%>/g, '');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
@overview This is just an example.
|
||||
@module plugins/shout
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
exports.handlers = {
|
||||
/**
|
||||
Make your descriptions more shoutier.
|
||||
*/
|
||||
newDoclet: function(e) {
|
||||
if (typeof e.doclet.description === 'string') {
|
||||
e.doclet.description = e.doclet.description.toUpperCase();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
@module plugins/sourcetag
|
||||
@author Michael Mathews <micmath@gmail.com>
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var logger = require('jsdoc/util/logger');
|
||||
|
||||
exports.handlers = {
|
||||
/**
|
||||
Support @source tag. Expected value like:
|
||||
{ "filename": "myfile.js", "lineno": 123 }
|
||||
Modifies the corresponding meta values on the given doclet.
|
||||
|
||||
WARNING: If you are using a JSDoc template that generates pretty-printed source files,
|
||||
such as JSDoc's default template, this plugin can cause JSDoc to crash. To fix this issue,
|
||||
update your template settings to disable pretty-printed source files.
|
||||
|
||||
@source { "filename": "sourcetag.js", "lineno": 13 }
|
||||
*/
|
||||
newDoclet: function(e) {
|
||||
var tags = e.doclet.tags,
|
||||
tag,
|
||||
value;
|
||||
|
||||
// any user-defined tags in this doclet?
|
||||
if (typeof tags !== 'undefined') {
|
||||
// only interested in the @source tags
|
||||
tags = tags.filter(function($) {
|
||||
return $.title === 'source';
|
||||
});
|
||||
|
||||
if (tags.length) {
|
||||
// take the first one
|
||||
tag = tags[0];
|
||||
|
||||
try {
|
||||
value = JSON.parse(tag.value);
|
||||
}
|
||||
catch(e) {
|
||||
logger.error('@source tag expects a valid JSON value, like { "filename": "myfile.js", "lineno": 123 }.');
|
||||
return;
|
||||
}
|
||||
|
||||
e.doclet.meta = e.doclet.meta || {};
|
||||
e.doclet.meta.filename = value.filename || '';
|
||||
e.doclet.meta.lineno = value.lineno || '';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @overview This plugin creates a summary tag, if missing, from the first sentence in the
|
||||
* description.
|
||||
* @module plugins/summarize
|
||||
* @author Mads Bondo Dydensborg <mbd@dbc.dk>
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
exports.handlers = {
|
||||
/**
|
||||
* Autogenerate summaries, if missing, from the description, if present.
|
||||
*/
|
||||
newDoclet: function(e) {
|
||||
var endTag;
|
||||
var tags;
|
||||
var stack;
|
||||
|
||||
// If the summary is missing, grab the first sentence from the description
|
||||
// and use that.
|
||||
if (e.doclet && !e.doclet.summary && e.doclet.description) {
|
||||
// The summary may end with `.$`, `. `, or `.<` (a period followed by an HTML tag).
|
||||
e.doclet.summary = e.doclet.description.split(/\.$|\.\s|\.</)[0];
|
||||
// Append `.` as it was removed in both cases, or is possibly missing.
|
||||
e.doclet.summary += '.';
|
||||
|
||||
// This is an excerpt of something that is possibly HTML.
|
||||
// Balance it using a stack. Assume it was initially balanced.
|
||||
tags = e.doclet.summary.match(/<[^>]+>/g) || [];
|
||||
stack = [];
|
||||
|
||||
tags.forEach(function(tag) {
|
||||
var idx = tag.indexOf('/');
|
||||
|
||||
if (idx === -1) {
|
||||
// start tag -- push onto the stack
|
||||
stack.push(tag);
|
||||
} else if (idx === 1) {
|
||||
// end tag -- pop off of the stack
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
// otherwise, it's a self-closing tag; don't modify the stack
|
||||
});
|
||||
|
||||
// stack should now contain only the start tags that lack end tags,
|
||||
// with the most deeply nested start tag at the top
|
||||
while (stack.length > 0) {
|
||||
// pop the unmatched tag off the stack
|
||||
endTag = stack.pop();
|
||||
// get just the tag name
|
||||
endTag = endTag.substring(1, endTag.search(/[ >]/));
|
||||
// append the end tag
|
||||
e.doclet.summary += '</' + endTag + '>';
|
||||
}
|
||||
|
||||
// and, finally, if the summary starts and ends with a <p> tag, remove it; let the
|
||||
// template decide whether to wrap the summary in a <p> tag
|
||||
e.doclet.summary = e.doclet.summary.replace(/^<p>(.*)<\/p>$/i, '$1');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @see [Nowhere](http://nowhere.com)
|
||||
*/
|
||||
function foo() {}
|
||||
|
||||
/**
|
||||
* @see AnObject#myProperty
|
||||
*/
|
||||
function bar() {}
|
||||
|
||||
/**
|
||||
* @classdesc My class.
|
||||
* @description My class.
|
||||
* @exception {Error} Some error.
|
||||
* @param {string} myParam - My parameter.
|
||||
* @property {string} value - Value of myParam.
|
||||
* @return {MyClass} Class instance.
|
||||
* @see [Example Inc.](http://example.com)
|
||||
*/
|
||||
function MyClass(myParam) {
|
||||
this.value = myParam;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* A bowl of non-spicy soup.
|
||||
* @class
|
||||
*//**
|
||||
* A bowl of spicy soup.
|
||||
* @class
|
||||
* @param {number} spiciness - The spiciness of the soup, in Scoville heat units (SHU).
|
||||
*/
|
||||
function Soup(spiciness) {}
|
||||
|
||||
/**
|
||||
* Slurp the soup.
|
||||
*//**
|
||||
* Slurp the soup loudly.
|
||||
* @param {number} dBA - The slurping volume, in A-weighted decibels.
|
||||
*/
|
||||
Soup.prototype.slurp = function(dBA) {};
|
||||
|
||||
/**
|
||||
* Salt the soup as needed, using a highly optimized soup-salting heuristic.
|
||||
*//**
|
||||
* Salt the soup, specifying the amount of salt to add.
|
||||
* @variation mg
|
||||
* @param {number} amount - The amount of salt to add, in milligrams.
|
||||
*/
|
||||
Soup.prototype.salt = function(amount) {};
|
||||
|
||||
/**
|
||||
* Heat the soup by the specified number of degrees.
|
||||
* @param {number} degrees - The number of degrees, in Fahrenheit, by which to heat the soup.
|
||||
*//**
|
||||
* Heat the soup by the specified number of degrees.
|
||||
* @variation 1
|
||||
* @param {string} degrees - The number of degrees, in Fahrenheit, by which to heat the soup, but
|
||||
* as a string for some reason.
|
||||
*//**
|
||||
* Heat the soup by the specified number of degrees.
|
||||
* @param {boolean} degrees - The number of degrees, as a boolean. Wait, what?
|
||||
*/
|
||||
Soup.prototype.heat = function(degrees) {};
|
||||
|
||||
/**
|
||||
* Discard the soup.
|
||||
* @variation discardSoup
|
||||
*//**
|
||||
* Discard the soup by pouring it into the specified container.
|
||||
* @variation discardSoup
|
||||
* @param {Object} container - The container in which to discard the soup.
|
||||
*/
|
||||
Soup.prototype.discard = function(container) {};
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
@overview Strips the rails template tags from a js.erb file
|
||||
@module plugins/railsTemplate
|
||||
@author Jannon Frank <jannon@jannon.net>
|
||||
*/
|
||||
|
||||
exports.handlers = {
|
||||
/**
|
||||
* Remove rails tags from the source input (e.g. <% foo bar %>)
|
||||
* @param e
|
||||
* @param e.filename
|
||||
* @param e.source
|
||||
*/
|
||||
beforeParse: function(e) {
|
||||
if (e.filename.match(/\.erb$/)) {
|
||||
e.source = e.source.replace(/<%.*%> /g, "");
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
/*global describe: true, env: true, expect: true, it: true, jasmine: true */
|
||||
describe("commentConvert plugin", function() {
|
||||
var parser = jasmine.createParser();
|
||||
var path = require('jsdoc/path');
|
||||
|
||||
var docSet;
|
||||
|
||||
var pluginPath = 'plugins/commentConvert';
|
||||
var pluginPathResolved = path.join(env.dirname, pluginPath);
|
||||
var plugin = require(pluginPathResolved);
|
||||
|
||||
require('jsdoc/plugins').installPlugins([pluginPathResolved], parser);
|
||||
docSet = jasmine.getDocSetFromFile(pluginPath + '.js', parser);
|
||||
|
||||
it("should convert '///-style comments into jsdoc comments", function() {
|
||||
var doclet = docSet.getByLongname("module:plugins/commentConvert.handlers.beforeParse");
|
||||
expect(doclet.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
/*global describe: true, env: true, expect: true, it: true, jasmine: true */
|
||||
describe("escapeHtml plugin", function() {
|
||||
var parser = jasmine.createParser();
|
||||
var path = require('jsdoc/path');
|
||||
|
||||
var docSet;
|
||||
|
||||
var pluginPath = 'plugins/escapeHtml';
|
||||
var pluginPathResolved = path.join(env.dirname,pluginPath);
|
||||
var plugin = require(pluginPathResolved);
|
||||
|
||||
require('jsdoc/plugins').installPlugins([pluginPathResolved], parser);
|
||||
docSet = jasmine.getDocSetFromFile(pluginPath + '.js', parser);
|
||||
|
||||
it("should escape '&', '<' and newlines in doclet descriptions", function() {
|
||||
var doclet = docSet.getByLongname("module:plugins/escapeHtml.handlers.newDoclet");
|
||||
expect(doclet[0].description).toEqual("Translate HTML tags in descriptions into safe entities.<br> Replaces <, & and newlines");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('jsdoc/path');
|
||||
|
||||
describe('markdown plugin', function() {
|
||||
var pluginPath = 'plugins/markdown';
|
||||
var pluginPathResolved = path.join(global.env.dirname, pluginPath);
|
||||
var plugin = require(pluginPathResolved);
|
||||
|
||||
var docSet = jasmine.getDocSetFromFile('plugins/test/fixtures/markdown.js');
|
||||
|
||||
// TODO: more tests; refactor the plugin so multiple settings can be tested
|
||||
|
||||
it('should process the correct tags by default', function() {
|
||||
var myClass = docSet.getByLongname('MyClass')[0];
|
||||
|
||||
plugin.handlers.newDoclet({ doclet: myClass });
|
||||
[
|
||||
myClass.classdesc,
|
||||
myClass.description,
|
||||
myClass.exceptions[0].description,
|
||||
myClass.params[0].description,
|
||||
myClass.properties[0].description,
|
||||
myClass.returns[0].description,
|
||||
myClass.see
|
||||
].forEach(function(value) {
|
||||
// if we processed the value, it should be wrapped in a <p> tag
|
||||
expect( /^<p>(?:.+)<\/p>$/.test(value) ).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('@see tag support', function() {
|
||||
var foo = docSet.getByLongname('foo')[0];
|
||||
var bar = docSet.getByLongname('bar')[0];
|
||||
|
||||
it('should parse @see tags containing links', function() {
|
||||
plugin.handlers.newDoclet({ doclet: foo });
|
||||
expect(typeof foo).toEqual('object');
|
||||
expect(foo.see[0]).toEqual('<p><a href="http://nowhere.com">Nowhere</a></p>');
|
||||
});
|
||||
|
||||
it('should not parse @see tags that do not contain links', function() {
|
||||
plugin.handlers.newDoclet({ doclet: bar });
|
||||
expect(typeof bar).toEqual('object');
|
||||
expect(bar.see[0]).toEqual('AnObject#myProperty');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,101 @@
|
||||
/*global describe: true, env: true, expect: true, it: true, jasmine: true, xit: true */
|
||||
describe('plugins/overloadHelper', function() {
|
||||
var parser = jasmine.createParser();
|
||||
var path = require('jsdoc/path');
|
||||
|
||||
var docSet;
|
||||
|
||||
var pluginPath = 'plugins/overloadHelper';
|
||||
var pluginPathResolved = path.resolve(env.dirname, pluginPath);
|
||||
var plugin = require(pluginPathResolved);
|
||||
|
||||
require('jsdoc/plugins').installPlugins([pluginPathResolved], parser);
|
||||
docSet = jasmine.getDocSetFromFile('plugins/test/fixtures/overloadHelper.js', parser);
|
||||
|
||||
it('should exist', function() {
|
||||
expect(plugin).toBeDefined();
|
||||
expect(typeof plugin).toBe('object');
|
||||
});
|
||||
|
||||
it('should export handlers', function() {
|
||||
expect(plugin.handlers).toBeDefined();
|
||||
expect(typeof plugin.handlers).toBe('object');
|
||||
});
|
||||
|
||||
it('should export a "newDoclet" handler', function() {
|
||||
expect(plugin.handlers.newDoclet).toBeDefined();
|
||||
expect(typeof plugin.handlers.newDoclet).toBe('function');
|
||||
});
|
||||
|
||||
it('should export a "parseComplete" handler', function() {
|
||||
expect(plugin.handlers.parseComplete).toBeDefined();
|
||||
expect(typeof plugin.handlers.parseComplete).toBe('function');
|
||||
});
|
||||
|
||||
describe('newDoclet handler', function() {
|
||||
it('should not add unique longnames to constructors', function() {
|
||||
var soup = docSet.getByLongname('Soup');
|
||||
var soup1 = docSet.getByLongname('Soup()');
|
||||
var soup2 = docSet.getByLongname('Soup(spiciness)');
|
||||
|
||||
expect(soup.length).toBe(2);
|
||||
expect(soup1.length).toBe(0);
|
||||
expect(soup2.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should add unique longnames to methods', function() {
|
||||
var slurp = docSet.getByLongname('Soup#slurp');
|
||||
var slurp1 = docSet.getByLongname('Soup#slurp()');
|
||||
var slurp2 = docSet.getByLongname('Soup#slurp(dBA)');
|
||||
|
||||
expect(slurp.length).toBe(0);
|
||||
expect(slurp1.length).toBe(1);
|
||||
expect(slurp2.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should update the "variation" property of the method', function() {
|
||||
var slurp1 = docSet.getByLongname('Soup#slurp()')[0];
|
||||
var slurp2 = docSet.getByLongname('Soup#slurp(dBA)')[0];
|
||||
|
||||
expect(slurp1.variation).toBe('');
|
||||
expect(slurp2.variation).toBe('dBA');
|
||||
});
|
||||
|
||||
it('should not add to or change existing variations that are unique', function() {
|
||||
var salt1 = docSet.getByLongname('Soup#salt');
|
||||
var salt2 = docSet.getByLongname('Soup#salt(mg)');
|
||||
|
||||
expect(salt1.length).toBe(1);
|
||||
expect(salt2.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should not duplicate the names of existing numeric variations', function() {
|
||||
var heat1 = docSet.getByLongname('Soup#heat(1)');
|
||||
var heat2 = docSet.getByLongname('Soup#heat(2)');
|
||||
var heat3 = docSet.getByLongname('Soup#heat(3)');
|
||||
|
||||
expect(heat1.length).toBe(1);
|
||||
expect(heat2.length).toBe(1);
|
||||
expect(heat3.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should replace identical variations with new, unique variations', function() {
|
||||
var discard1 = docSet.getByLongname('Soup#discard()');
|
||||
var discard2 = docSet.getByLongname('Soup#discard(container)');
|
||||
|
||||
expect(discard1.length).toBe(1);
|
||||
expect(discard2.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseComplete handler', function() {
|
||||
// disabled because on the second run, each comment is being parsed twice; who knows why...
|
||||
xit('should not retain parse results between parser runs', function() {
|
||||
parser.clear();
|
||||
docSet = jasmine.getDocSetFromFile('plugins/test/fixtures/overloadHelper.js', parser);
|
||||
var heat = docSet.getByLongname('Soup#heat(4)');
|
||||
|
||||
expect(heat.length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/*global describe: true, env: true, expect: true, it: true, jasmine: true */
|
||||
describe("railsTemplate plugin", function() {
|
||||
var parser = jasmine.createParser();
|
||||
var path = require('jsdoc/path');
|
||||
|
||||
var pluginPath = path.join(env.dirname, 'plugins/railsTemplate');
|
||||
var plugin = require(pluginPath);
|
||||
|
||||
require('jsdoc/plugins').installPlugins([pluginPath], parser);
|
||||
require('jsdoc/src/handlers').attachTo(parser);
|
||||
|
||||
it("should remove <% %> rails template tags from the source of *.erb files", function() {
|
||||
var docSet = parser.parse([path.join(env.dirname, "plugins/test/fixtures/railsTemplate.js.erb")]);
|
||||
|
||||
expect(docSet[2].description).toEqual("Remove rails tags from the source input (e.g. )");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
/*global describe: true, env: true, expect: true, it: true, jasmine: true */
|
||||
describe("shout plugin", function() {
|
||||
var parser = jasmine.createParser();
|
||||
var path = require('jsdoc/path');
|
||||
|
||||
var docSet;
|
||||
|
||||
var pluginPath = 'plugins/shout';
|
||||
var pluginPathResolved = path.join(env.dirname, pluginPath);
|
||||
var plugin = require(pluginPathResolved);
|
||||
|
||||
require('jsdoc/plugins').installPlugins([pluginPathResolved], parser);
|
||||
docSet = jasmine.getDocSetFromFile(pluginPath + '.js', parser);
|
||||
|
||||
it("should make the description uppercase", function() {
|
||||
var doclet = docSet.getByLongname("module:plugins/shout.handlers.newDoclet");
|
||||
expect(doclet[0].description).toEqual("MAKE YOUR DESCRIPTIONS MORE SHOUTIER.");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
/*global describe, expect, it, jasmine */
|
||||
'use strict';
|
||||
|
||||
describe('sourcetag plugin', function() {
|
||||
var parser = jasmine.createParser();
|
||||
var path = require('jsdoc/path');
|
||||
|
||||
var docSet;
|
||||
|
||||
var pluginPath = 'plugins/sourcetag';
|
||||
var pluginPathResolved = path.join(global.env.dirname, pluginPath);
|
||||
var plugin = require(pluginPathResolved);
|
||||
|
||||
require('jsdoc/plugins').installPlugins([pluginPathResolved], parser);
|
||||
docSet = jasmine.getDocSetFromFile(pluginPath + '.js', parser);
|
||||
|
||||
it("should set the lineno and filename of the doclet's meta property", function() {
|
||||
var doclet = docSet.getByLongname('module:plugins/sourcetag.handlers.newDoclet');
|
||||
expect(doclet[0].meta).toBeDefined();
|
||||
expect(doclet[0].meta.filename).toEqual('sourcetag.js');
|
||||
expect(doclet[0].meta.lineno).toEqual(13);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,112 @@
|
||||
/*global describe, expect, it */
|
||||
'use strict';
|
||||
|
||||
var summarize = require('../../summarize');
|
||||
|
||||
describe('summarize', function() {
|
||||
it('should export handlers', function() {
|
||||
expect(summarize.handlers).toBeDefined();
|
||||
expect(typeof summarize.handlers).toBe('object');
|
||||
});
|
||||
|
||||
it('should export a newDoclet handler', function() {
|
||||
expect(summarize.handlers.newDoclet).toBeDefined();
|
||||
expect(typeof summarize.handlers.newDoclet).toBe('function');
|
||||
});
|
||||
|
||||
describe('newDoclet handler', function() {
|
||||
var handler = summarize.handlers.newDoclet;
|
||||
|
||||
it('should not blow up if the doclet is missing', function() {
|
||||
function noDoclet() {
|
||||
return handler({});
|
||||
}
|
||||
|
||||
expect(noDoclet).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not change the summary if it is already defined', function() {
|
||||
var doclet = {
|
||||
summary: 'This is a summary.',
|
||||
description: 'Descriptions are good.'
|
||||
};
|
||||
handler({ doclet: doclet });
|
||||
|
||||
expect(doclet.summary).not.toBe(doclet.description);
|
||||
});
|
||||
|
||||
it('should not do anything if the description is missing', function() {
|
||||
var doclet = {};
|
||||
handler({ doclet: doclet });
|
||||
|
||||
expect(doclet.summary).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should use the first sentence as the summary', function() {
|
||||
var doclet = {
|
||||
description: 'This sentence is the summary. This sentence is not.'
|
||||
};
|
||||
handler({ doclet: doclet });
|
||||
|
||||
expect(doclet.summary).toBe('This sentence is the summary.');
|
||||
});
|
||||
|
||||
it('should not add an extra period if there is only one sentence in the description',
|
||||
function() {
|
||||
var doclet = {
|
||||
description: 'This description has only one sentence.'
|
||||
};
|
||||
handler({ doclet: doclet });
|
||||
|
||||
expect(doclet.summary).toBe('This description has only one sentence.');
|
||||
});
|
||||
|
||||
it('should use the entire description, plus a period, as the summary if the description ' +
|
||||
'does not contain a period', function() {
|
||||
var doclet = {
|
||||
description: 'This is a description'
|
||||
};
|
||||
handler({ doclet: doclet });
|
||||
|
||||
expect(doclet.summary).toBe('This is a description.');
|
||||
});
|
||||
|
||||
it('should use the entire description as the summary if the description contains only ' +
|
||||
'one sentence', function() {
|
||||
var doclet = {
|
||||
description: 'This is a description.'
|
||||
};
|
||||
handler({ doclet: doclet });
|
||||
|
||||
expect(doclet.description).toBe('This is a description.');
|
||||
});
|
||||
|
||||
it('should work when an HTML tag immediately follows the first sentence', function() {
|
||||
var doclet = {
|
||||
description: 'This sentence is the summary.<small>This sentence is small.</small>'
|
||||
};
|
||||
handler({ doclet: doclet });
|
||||
|
||||
expect(doclet.summary).toBe('This sentence is the summary.');
|
||||
});
|
||||
|
||||
it('should generate valid HTML if a tag is opened, but not closed, in the summary',
|
||||
function() {
|
||||
var doclet = {
|
||||
description: 'This description has <em>a tag. The tag straddles</em> sentences.'
|
||||
};
|
||||
handler({ doclet: doclet });
|
||||
|
||||
expect(doclet.summary).toBe('This description has <em>a tag.</em>');
|
||||
});
|
||||
|
||||
it('should not include a <p> tag in the summary', function() {
|
||||
var doclet = {
|
||||
description: '<p>This description contains HTML.</p><p>And plenty of it!</p>'
|
||||
};
|
||||
handler({ doclet: doclet });
|
||||
|
||||
expect(doclet.summary).toBe('This description contains HTML.');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user