mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
allow inline {@type} tag in description to override type expression (#152)
- create `jsdoc/tag/inline` module, a generalized parser for inline tags
- use the new module to look for an inline `{@type}` tag in tag text;
for tags that can have a type, the inline tag overrides the type
expression
- update submodule
This commit is contained in:
parent
fdf5293f1c
commit
70bea4648e
@ -18,7 +18,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"async": "0.1.22",
|
||||
"catharsis": "0.4.2",
|
||||
"catharsis": "0.5.0",
|
||||
"crypto-browserify": "git://github.com/dominictarr/crypto-browserify.git#95c5d505",
|
||||
"github-flavored-markdown": "git://github.com/hegemonic/github-flavored-markdown.git",
|
||||
"js2xmlparser": "0.1.0",
|
||||
|
||||
115
lib/jsdoc/tag/inline.js
Normal file
115
lib/jsdoc/tag/inline.js
Normal file
@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @module jsdoc/tag/inline
|
||||
*
|
||||
* @author Jeff Williams <jeffrey.l.williams@gmail.com>
|
||||
* @license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Information about the result of extracting an inline tag from a text string.
|
||||
*
|
||||
* @typedef {Object} InlineTagInfo
|
||||
* @memberof module:jsdoc/tag/inline
|
||||
* @property {?string} tag - The tag whose text was found, or `null` if no tag was specified.
|
||||
* @property {string} text - The tag text that was found.
|
||||
* @property {string} newString - The updated text string after extracting or replacing the inline
|
||||
* tag.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function that replaces an inline tag with other text.
|
||||
*
|
||||
* @callback InlineTagReplacer
|
||||
* @memberof module:jsdoc/tag/inline
|
||||
* @param {string} string - The complete string containing the inline tag.
|
||||
* @param {string} completeTag - The entire inline tag, including its enclosing braces.
|
||||
* @param {string} tagText - The text contained in the inline tag.
|
||||
* @return {string} An updated version of the string that contained the inline tag.
|
||||
*/
|
||||
|
||||
/** @private */
|
||||
function unescapeBraces(text) {
|
||||
return text.replace(/\\\{/g, '{')
|
||||
.replace(/\\\}/g, '}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace an inline tag with other text.
|
||||
*
|
||||
* To replace untagged text that is enclosed in braces, set the `tag` parameter to `null`.
|
||||
*
|
||||
* @param {string} string - The string in which to replace the inline tag.
|
||||
* @param {string?} tag - The inline tag that must follow the opening brace (for example, `@link`).
|
||||
* @param {module:jsdoc/tag/inline.InlineTagReplacer} The function that is used to replace text in
|
||||
* the string.
|
||||
* @return {module:jsdoc/tag/inline.InlineTagInfo} The updated string, as well as information about
|
||||
* the inline tag.
|
||||
*/
|
||||
exports.replaceInlineTag = function(string, tag, replacer) {
|
||||
string = string || '';
|
||||
tag = tag || '';
|
||||
|
||||
var count = 0;
|
||||
var position = 0;
|
||||
var completeTag = '';
|
||||
var text = '';
|
||||
var start = '{' + tag;
|
||||
var startIndex = string.indexOf(start);
|
||||
var textStartIndex;
|
||||
|
||||
if (startIndex !== -1) {
|
||||
// advance to the first character after `start`
|
||||
position = textStartIndex = startIndex + start.length;
|
||||
count++;
|
||||
|
||||
while (position < string.length) {
|
||||
position++;
|
||||
|
||||
switch (string[position]) {
|
||||
case '\\':
|
||||
// backslash is an escape character, so skip the next character
|
||||
position++;
|
||||
break;
|
||||
case '{':
|
||||
count++;
|
||||
break;
|
||||
case '}':
|
||||
count--;
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
}
|
||||
|
||||
if (count === 0) {
|
||||
completeTag = string.slice(startIndex, position + 1);
|
||||
text = string.slice(textStartIndex, position).trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string = replacer.call(this, string, completeTag, text);
|
||||
|
||||
return {
|
||||
tag: tag || null,
|
||||
text: unescapeBraces(text),
|
||||
newString: string.trim()
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Extract the first portion of a string that is enclosed in braces, with the `tag` parameter
|
||||
* immediately following the opening brace.
|
||||
*
|
||||
* To extract untagged text that is enclosed in braces, omit the `tag` parameter.
|
||||
*
|
||||
* @param {string} string - The string from which to extract text.
|
||||
* @param {string?} tag - The inline tag that must follow the opening brace (for example, `@link`).
|
||||
* @return {module:jsdoc/tag/inline.InlineTagInfo} Information about the string and inline tag.
|
||||
*/
|
||||
exports.extractInlineTag = function(string, tag) {
|
||||
return exports.replaceInlineTag(string, tag, function(string, completeTag,
|
||||
tagText) {
|
||||
return string.replace(completeTag, '');
|
||||
});
|
||||
};
|
||||
@ -7,37 +7,20 @@
|
||||
*/
|
||||
|
||||
|
||||
/** @private */
|
||||
function trim(text) {
|
||||
return text.trim();
|
||||
}
|
||||
|
||||
/** @private */
|
||||
function getTagInfo(tagValue, canHaveName, canHaveType) {
|
||||
var name = '',
|
||||
typeExpression = '',
|
||||
text = tagValue,
|
||||
count = 0;
|
||||
var extractInlineTag = require('jsdoc/tag/inline').extractInlineTag;
|
||||
|
||||
// type expressions start with '{'
|
||||
if (canHaveType && tagValue[0] === '{') {
|
||||
count++;
|
||||
var name = '';
|
||||
var typeExpression = '';
|
||||
var text = tagValue;
|
||||
var typeAndText;
|
||||
var typeOverride;
|
||||
|
||||
// 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) {
|
||||
typeExpression = trim(tagValue.slice(1, i))
|
||||
.replace(/\\\{/g, '{') // unescape escaped curly braces
|
||||
.replace(/\\\}/g, '}');
|
||||
text = trim(tagValue.slice(i+1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (canHaveType) {
|
||||
typeAndText = extractInlineTag(text);
|
||||
typeExpression = typeAndText.text || typeExpression;
|
||||
text = typeAndText.newString;
|
||||
}
|
||||
|
||||
if (canHaveName) {
|
||||
@ -46,8 +29,19 @@ function getTagInfo(tagValue, canHaveName, canHaveType) {
|
||||
name = RegExp.$1;
|
||||
text = RegExp.$3;
|
||||
}
|
||||
|
||||
// an inline @type tag, like {@type Foo}, overrides the type expression
|
||||
if (canHaveType) {
|
||||
typeOverride = extractInlineTag(text, '@type');
|
||||
typeExpression = typeOverride.text || typeExpression;
|
||||
text = typeOverride.newString;
|
||||
}
|
||||
|
||||
return { name: name, typeExpression: typeExpression, text: text };
|
||||
return {
|
||||
name: name,
|
||||
typeExpression: typeExpression,
|
||||
text: text
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,14 +65,14 @@ function getTagInfo(tagValue, canHaveName, canHaveType) {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extract JSDoc-style type information from the tag info, including the member name; whether the
|
||||
* member is optional; and the default value of the member.
|
||||
* Extract JSDoc-style type information from the name specified in the tag info, including the
|
||||
* member name; whether the member is optional; and the default value of the member.
|
||||
*
|
||||
* @private
|
||||
* @param {module:jsdoc/tag/type.TagInfo} tagInfo - Information contained in the tag.
|
||||
* @return {module:jsdoc/tag/type.TagInfo} Updated information from the tag.
|
||||
*/
|
||||
function parseJsdocType(tagInfo) {
|
||||
function parseName(tagInfo) {
|
||||
// like '[foo]' or '[ foo ]' or '[foo=bar]' or '[ foo=bar ]' or '[ foo = bar ]'
|
||||
if ( /^\[\s*(.+?)\s*\]$/.test(tagInfo.name) ) {
|
||||
tagInfo.name = RegExp.$1;
|
||||
@ -142,13 +136,14 @@ function getTypeStrings(parsedType) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract Closure Compiler-style type information from the tag info.
|
||||
* Extract JSDoc-style and Closure Compiler-style type information from the type expression
|
||||
* specified in the tag info.
|
||||
*
|
||||
* @private
|
||||
* @param {module:jsdoc/tag/type.TagInfo} tagInfo - Information contained in the tag.
|
||||
* @return {module:jsdoc/tag/type.TagInfo} Updated information from the tag.
|
||||
*/
|
||||
function parseClosureCompilerType(tagInfo) {
|
||||
function parseTypeExpression(tagInfo) {
|
||||
var catharsis = require('catharsis');
|
||||
var util = require('util');
|
||||
|
||||
@ -161,7 +156,7 @@ function parseClosureCompilerType(tagInfo) {
|
||||
}
|
||||
|
||||
try {
|
||||
parsedType = catharsis.parse(tagInfo.typeExpression, {lenient: true});
|
||||
parsedType = catharsis.parse(tagInfo.typeExpression, {jsdoc: true});
|
||||
}
|
||||
catch (e) {
|
||||
errorMessage = util.format('unable to parse the type expression "%s": %s',
|
||||
@ -183,7 +178,7 @@ function parseClosureCompilerType(tagInfo) {
|
||||
}
|
||||
|
||||
// TODO: allow users to add/remove type parsers (perhaps via plugins)
|
||||
var typeParsers = [parseJsdocType, parseClosureCompilerType];
|
||||
var typeParsers = [parseName, parseTypeExpression];
|
||||
|
||||
/**
|
||||
* Parse the value of a JSDoc tag.
|
||||
|
||||
18
node_modules/catharsis/catharsis.js
generated
vendored
18
node_modules/catharsis/catharsis.js
generated
vendored
@ -13,7 +13,7 @@ var stringify = require('./lib/stringify');
|
||||
|
||||
var typeExpressionCache = {
|
||||
normal: {},
|
||||
lenient: {}
|
||||
jsdoc: {}
|
||||
};
|
||||
|
||||
var parsedTypeCache = {
|
||||
@ -24,15 +24,15 @@ var parsedTypeCache = {
|
||||
function getTypeExpressionCache(options) {
|
||||
if (options.useCache === false) {
|
||||
return null;
|
||||
} else if (options.lenient === true) {
|
||||
return typeExpressionCache.lenient;
|
||||
} else if (options.jsdoc === true) {
|
||||
return typeExpressionCache.jsdoc;
|
||||
} else {
|
||||
return typeExpressionCache.normal;
|
||||
}
|
||||
}
|
||||
|
||||
function getParsedTypeCache(options) {
|
||||
if (options.useCache === false) {
|
||||
if (options.useCache === false || options.links !== null || options.links !== undefined) {
|
||||
return null;
|
||||
} else if (options.htmlSafe === true) {
|
||||
return parsedTypeCache.htmlSafe;
|
||||
@ -41,8 +41,14 @@ function getParsedTypeCache(options) {
|
||||
}
|
||||
}
|
||||
|
||||
// can't return the original if any of the following are true:
|
||||
// 1. restringification was requested
|
||||
// 2. htmlSafe option was requested
|
||||
// 3. links option was provided
|
||||
// 4. typeExpression property is missing
|
||||
function canReturnOriginalExpression(parsedType, options) {
|
||||
return options.restringify !== true && options.htmlSafe !== true &&
|
||||
(options.links === null || options.links === undefined) &&
|
||||
Object.prototype.hasOwnProperty.call(parsedType, 'typeExpression');
|
||||
}
|
||||
|
||||
@ -59,8 +65,8 @@ function cachedParse(expr, options) {
|
||||
typeExpression: {
|
||||
value: expr
|
||||
},
|
||||
lenient: {
|
||||
value: options.lenient === true ? true : false
|
||||
jsdoc: {
|
||||
value: options.jsdoc === true ? true : false
|
||||
}
|
||||
});
|
||||
parsedType = Object.freeze(parsedType);
|
||||
|
||||
5083
node_modules/catharsis/lib/parser.js
generated
vendored
5083
node_modules/catharsis/lib/parser.js
generated
vendored
File diff suppressed because one or more lines are too long
26
node_modules/catharsis/lib/stringify.js
generated
vendored
26
node_modules/catharsis/lib/stringify.js
generated
vendored
@ -2,12 +2,14 @@
|
||||
|
||||
var Types = require('./types');
|
||||
|
||||
function Stringifier() {
|
||||
function Stringifier(options) {
|
||||
this._options = options || {};
|
||||
|
||||
// in a list of function signature params, repeatable params are stringified differently
|
||||
this._inFunctionSignatureParams = false;
|
||||
}
|
||||
|
||||
Stringifier.prototype.applications = function(applications, options) {
|
||||
Stringifier.prototype.applications = function(applications) {
|
||||
if (!applications) {
|
||||
return '';
|
||||
}
|
||||
@ -19,7 +21,7 @@ Stringifier.prototype.applications = function(applications, options) {
|
||||
parsedApplications.push(this.type(applications[i]));
|
||||
}
|
||||
|
||||
if (options.htmlSafe) {
|
||||
if (this._options.htmlSafe) {
|
||||
result = '.<';
|
||||
} else {
|
||||
result = '.<';
|
||||
@ -109,11 +111,10 @@ Stringifier.prototype['this'] = function(funcThis) {
|
||||
return funcThis ? 'this:' + this.type(funcThis) : '';
|
||||
};
|
||||
|
||||
Stringifier.prototype.type = function(type, options) {
|
||||
Stringifier.prototype.type = function(type) {
|
||||
if (!type) {
|
||||
return '';
|
||||
}
|
||||
options = options || {};
|
||||
|
||||
// nullable comes first
|
||||
var result = this.nullable(type.nullable);
|
||||
@ -134,7 +135,7 @@ Stringifier.prototype.type = function(type, options) {
|
||||
break;
|
||||
case Types.TypeApplication:
|
||||
result += this.type(type.expression);
|
||||
result += this.applications(type.applications, options);
|
||||
result += this.applications(type.applications);
|
||||
break;
|
||||
case Types.UndefinedLiteral:
|
||||
result += this._formatNameAndType(type, 'undefined');
|
||||
@ -202,6 +203,17 @@ Stringifier.prototype._formatRepeatable = function(nameString, typeString) {
|
||||
Stringifier.prototype._formatNameAndType = function(type, literal) {
|
||||
var nameString = type.name || literal || '';
|
||||
var typeString = type.type ? this.type(type.type) : '';
|
||||
var cssClass;
|
||||
var openTag;
|
||||
|
||||
// replace the type with an HTML link if necessary
|
||||
if (this._options.links && Object.prototype.hasOwnProperty.call(this._options.links,
|
||||
nameString)) {
|
||||
cssClass = this._options.cssClass ? ' class="' + this._options.cssClass + '"' : '';
|
||||
|
||||
openTag = '<a href="' + this._options.links[nameString] + '"' + cssClass + '>';
|
||||
nameString = openTag + nameString + '</a>';
|
||||
}
|
||||
|
||||
if (type.repeatable === true) {
|
||||
return this._formatRepeatable(nameString, typeString);
|
||||
@ -241,5 +253,5 @@ Stringifier.prototype._signature = function(type) {
|
||||
|
||||
|
||||
module.exports = function(type, options) {
|
||||
return new Stringifier().stringify(type, options);
|
||||
return new Stringifier(options).stringify(type);
|
||||
};
|
||||
|
||||
18
node_modules/catharsis/package.json
generated
vendored
18
node_modules/catharsis/package.json
generated
vendored
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jsdoc",
|
||||
"version": "3.2.0-dev",
|
||||
"revision": "1363362219237",
|
||||
"revision": "1363617959876",
|
||||
"description": "An API documentation generator for JavaScript.",
|
||||
"keywords": [ "documentation", "javascript" ],
|
||||
"licenses": [
|
||||
@ -18,7 +18,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"async": "0.1.22",
|
||||
"catharsis": "0.4.3",
|
||||
"catharsis": "0.5.0",
|
||||
"crypto-browserify": "git://github.com/dominictarr/crypto-browserify.git#95c5d505",
|
||||
"github-flavored-markdown": "git://github.com/hegemonic/github-flavored-markdown.git",
|
||||
"js2xmlparser": "0.1.0",
|
||||
|
||||
185
test/specs/jsdoc/tag/inline.js
Normal file
185
test/specs/jsdoc/tag/inline.js
Normal file
@ -0,0 +1,185 @@
|
||||
/*global describe: true, expect: true, it: true */
|
||||
|
||||
describe('jsdoc/tag/inline', function() {
|
||||
var jsdoc = {
|
||||
tag: {
|
||||
inline: require('jsdoc/tag/inline')
|
||||
}
|
||||
};
|
||||
|
||||
it('should exist', function() {
|
||||
expect(jsdoc.tag.inline).toBeDefined();
|
||||
expect(typeof jsdoc.tag.inline).toBe('object');
|
||||
});
|
||||
|
||||
it('should export a replaceInlineTag function', function() {
|
||||
expect(jsdoc.tag.inline.replaceInlineTag).toBeDefined();
|
||||
expect(typeof jsdoc.tag.inline.replaceInlineTag).toBe('function');
|
||||
});
|
||||
|
||||
it('should export an extractInlineTag function', function() {
|
||||
expect(jsdoc.tag.inline.extractInlineTag).toBeDefined();
|
||||
expect(typeof jsdoc.tag.inline.replaceInlineTag).toBe('function');
|
||||
});
|
||||
|
||||
describe('replaceInlineTag', function() {
|
||||
it('should throw if the replacer parameter is invalid', function() {
|
||||
function badReplacerUndefined() {
|
||||
jsdoc.tag.inline.replaceInlineTag('foo', '@bar');
|
||||
}
|
||||
|
||||
function badReplacerString() {
|
||||
jsdoc.tag.inline.replaceInlineTag('foo', '@bar', 'hello');
|
||||
}
|
||||
|
||||
expect(badReplacerUndefined).toThrow();
|
||||
expect(badReplacerString).toThrow();
|
||||
});
|
||||
|
||||
it('should not find anything if there is no text in braces', function() {
|
||||
function replacer(string, completeTag, tagText) {
|
||||
expect(string).toBe('braceless text');
|
||||
expect(completeTag).toBe('');
|
||||
expect(tagText).toBe('');
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('braceless text', null, replacer);
|
||||
expect(result.tag).toBe(null);
|
||||
expect(result.text).toBe('');
|
||||
expect(result.newString).toBe('braceless text');
|
||||
});
|
||||
|
||||
it('should cope with bad escapement at the end of the string', function() {
|
||||
function replacer(string, completeTag, tagText) {
|
||||
expect(string).toBe('bad {escapement \\');
|
||||
expect(completeTag).toBe('');
|
||||
expect(tagText).toBe('');
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('bad {escapement \\', null, replacer);
|
||||
expect(result.tag).toBe(null);
|
||||
expect(result.text).toBe('');
|
||||
expect(result.newString).toBe('bad {escapement \\');
|
||||
});
|
||||
|
||||
it('should handle escaped braces correctly', function() {
|
||||
function replacer(string, completeTag, tagText) {
|
||||
expect(string).toBe('a {braces \\} test}');
|
||||
expect(completeTag).toBe('{braces \\} test}');
|
||||
expect(tagText).toBe('braces \\} test');
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('a {braces \\} test}', null, replacer);
|
||||
expect(result.tag).toBe(null);
|
||||
expect(result.text).toBe('braces } test');
|
||||
expect(result.newString).toBe('a {braces \\} test}');
|
||||
});
|
||||
|
||||
it('should work if the tag is the entire string', function() {
|
||||
function replacer(string, completeTag, tagText) {
|
||||
expect(string).toBe('{text in braces}');
|
||||
expect(completeTag).toBe('{text in braces}');
|
||||
expect(tagText).toBe('text in braces');
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('{text in braces}', null, replacer);
|
||||
expect(result.tag).toBe(null);
|
||||
expect(result.text).toBe('text in braces');
|
||||
expect(result.newString).toBe('{text in braces}');
|
||||
});
|
||||
|
||||
it('should work if the tag is at the beginning of the string', function() {
|
||||
function replacer(string, completeTag, tagText) {
|
||||
expect(string).toBe('{test string} ahoy');
|
||||
expect(completeTag).toBe('{test string}');
|
||||
expect(tagText).toBe('test string');
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('{test string} ahoy', null, replacer);
|
||||
expect(result.tag).toBe(null);
|
||||
expect(result.text).toBe('test string');
|
||||
expect(result.newString).toBe('{test string} ahoy');
|
||||
});
|
||||
|
||||
it('should work if the tag is in the middle of the string', function() {
|
||||
function replacer(string, completeTag, tagText) {
|
||||
expect(string).toBe('a {test string} yay');
|
||||
expect(completeTag).toBe('{test string}');
|
||||
expect(tagText).toBe('test string');
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('a {test string} yay', null, replacer);
|
||||
expect(result.tag).toBe(null);
|
||||
expect(result.text).toBe('test string');
|
||||
expect(result.newString).toBe('a {test string} yay');
|
||||
});
|
||||
|
||||
it('should work if the tag is at the end of the string', function() {
|
||||
function replacer(string, completeTag, tagText) {
|
||||
expect(string).toBe('a {test string}');
|
||||
expect(completeTag).toBe('{test string}');
|
||||
expect(tagText).toBe('test string');
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('a {test string}', null, replacer);
|
||||
expect(result.tag).toBe(null);
|
||||
expect(result.text).toBe('test string');
|
||||
expect(result.newString).toBe('a {test string}');
|
||||
});
|
||||
|
||||
it('should replace the string with the specified value', function() {
|
||||
function replacer() {
|
||||
return 'REPLACED!';
|
||||
}
|
||||
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('a {test string}', null, replacer);
|
||||
expect(result.newString).toBe('REPLACED!');
|
||||
});
|
||||
|
||||
it('should work when a tag is specified', function() {
|
||||
function replacer(string, completeTag, tagText) {
|
||||
expect(string).toBe('a {@foo tag} test');
|
||||
expect(completeTag).toBe('{@foo tag}');
|
||||
expect(tagText).toBe('tag');
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('a {@foo tag} test', '@foo', replacer);
|
||||
expect(result.tag).toBe('@foo');
|
||||
expect(result.text).toBe('tag');
|
||||
expect(result.newString).toBe('a {@foo tag} test');
|
||||
});
|
||||
});
|
||||
|
||||
// largely covered by the replaceInlineTag tests
|
||||
describe('extractInlineTag', function() {
|
||||
it('should work when there is no tag specified', function() {
|
||||
var result = jsdoc.tag.inline.extractInlineTag('some {braced text}');
|
||||
expect(result.tag).toBe(null);
|
||||
expect(result.text).toBe('braced text');
|
||||
expect(result.newString).toBe('some');
|
||||
});
|
||||
|
||||
it('should work when a tag is specified', function() {
|
||||
var result = jsdoc.tag.inline.extractInlineTag('some {@tagged text}', '@tagged');
|
||||
expect(result.tag).toBe('@tagged');
|
||||
expect(result.text).toBe('text');
|
||||
expect(result.newString).toBe('some');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -118,6 +118,33 @@ describe('jsdoc/tag/type', function() {
|
||||
expect(info.type).toEqual( ['string', 'number', 'boolean', 'function'] );
|
||||
});
|
||||
|
||||
it('should override the type expression if an inline @type tag is specified', function() {
|
||||
var desc = '{Object} cookie {@type Monster}';
|
||||
var info = jsdoc.tag.type.parse(desc, true, true);
|
||||
expect(info.type).toEqual( ['Monster'] );
|
||||
expect(info.text).toBe('');
|
||||
|
||||
desc = '{Object} cookie - {@type Monster}';
|
||||
info = jsdoc.tag.type.parse(desc, true, true);
|
||||
expect(info.type).toEqual( ['Monster'] );
|
||||
expect(info.text).toBe('');
|
||||
|
||||
desc = '{Object} cookie - The cookie parameter. {@type Monster}';
|
||||
info = jsdoc.tag.type.parse(desc, true, true);
|
||||
expect(info.type).toEqual( ['Monster'] );
|
||||
expect(info.text).toBe('The cookie parameter.');
|
||||
|
||||
desc = '{Object} cookie - The cookie parameter. {@type (Monster|Jar)}';
|
||||
info = jsdoc.tag.type.parse(desc, true, true);
|
||||
expect(info.type).toEqual( ['Monster', 'Jar'] );
|
||||
expect(info.text).toBe('The cookie parameter.');
|
||||
|
||||
desc = '{Object} cookie - The cookie parameter. {@type (Monster|Jar)} Mmm, cookie.';
|
||||
info = jsdoc.tag.type.parse(desc, true, true);
|
||||
expect(info.type).toEqual( ['Monster', 'Jar'] );
|
||||
expect(info.text).toBe('The cookie parameter. Mmm, cookie.');
|
||||
});
|
||||
|
||||
describe('JSDoc-style type info', function() {
|
||||
it('should parse JSDoc-style optional parameters', function() {
|
||||
var name = '[qux]';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user