mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
rework type extraction and inline tag parsing
- brace-counting logic now lives in the type code, which is where it's needed - we now replace (and return) ALL instances of an inline tag, not just the first one
This commit is contained in:
parent
d6f1eed8c0
commit
9de918ab94
@ -6,15 +6,23 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Information about the result of manipulating inline tags within a text string.
|
||||
* Information about an inline tag that was found within a string.
|
||||
*
|
||||
* @typedef {Object} InlineTagInfo
|
||||
* @memberof module:jsdoc/tag/inline
|
||||
* @property {?string} completeTag - The entire inline tag, including its enclosing braces.
|
||||
* @property {?string} tag - The tag whose text was found.
|
||||
* @property {?string} text - The tag text that was found.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Information about the results of replacing inline tags within a string.
|
||||
*
|
||||
* @typedef {Object} InlineTagResult
|
||||
* @memberof module:jsdoc/tag/inline
|
||||
* @property {Array.<module:jsdoc/tag/inline.InlineTagInfo>} tags - The inline tags that were found.
|
||||
* @property {string} newString - The updated text string after extracting or replacing the inline
|
||||
* tag.
|
||||
* tags.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -24,118 +32,75 @@
|
||||
* @memberof module:jsdoc/tag/inline
|
||||
* @param {string} string - The complete string containing the inline tag.
|
||||
* @param {module:jsdoc/tag/inline.InlineTagInfo} tagInfo - Information about the inline tag.
|
||||
* @return {string} An updated version of the string that contained the inline tag.
|
||||
* @return {string} The text that will replace the inline tag.
|
||||
*/
|
||||
|
||||
/** @private */
|
||||
function unescapeBraces(text) {
|
||||
return text.replace(/\\\{/g, '{')
|
||||
.replace(/\\\}/g, '}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace an inline tag with other text.
|
||||
* Replace all instances of multiple inline tags 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} replacer - 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.
|
||||
* @param {string} string - The string in which to replace the inline tags.
|
||||
* @param {Object} replacers - The functions that are used to replace text in the string. The keys
|
||||
* must contain tag names (for example, `link`), and the values must contain functions with the
|
||||
* type {@link module:jsdoc/tag/inline.InlineTagReplacer}.
|
||||
* @return {module:jsdoc/tag/inline.InlineTagResult} The updated string, as well as information
|
||||
* about the inline tags that were found.
|
||||
*/
|
||||
exports.replaceInlineTag = function(string, tag, replacer) {
|
||||
string = string || '';
|
||||
tag = tag ? '@' + tag : '';
|
||||
exports.replaceInlineTags = function(string, replacers) {
|
||||
var tagRegExp;
|
||||
var tagInfo = [];
|
||||
|
||||
var count = 0;
|
||||
var position = 0;
|
||||
var completeTag = '';
|
||||
var text = '';
|
||||
var start = '{' + tag;
|
||||
var startIndex = string.indexOf(start);
|
||||
var textStartIndex;
|
||||
function replaceMatch(replacer, tag, match, text) {
|
||||
var matchedTag = {
|
||||
completeTag: match,
|
||||
tag: tag,
|
||||
text: text
|
||||
};
|
||||
tagInfo.push(matchedTag);
|
||||
|
||||
if (startIndex !== -1) {
|
||||
// advance to the first character after `start`
|
||||
position = textStartIndex = startIndex + start.length;
|
||||
count++;
|
||||
|
||||
while (position < string.length) {
|
||||
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;
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
return replacer.call(this, string, matchedTag);
|
||||
}
|
||||
|
||||
string = replacer.call(this, string, {
|
||||
completeTag: completeTag,
|
||||
tag: tag.replace(/^@/, ''),
|
||||
text: text
|
||||
string = string || '';
|
||||
Object.keys(replacers).forEach(function(replacer) {
|
||||
tagRegExp = new RegExp('\\{@' + replacer + '\\s+(.+?)\\}', 'gi');
|
||||
string = string.replace(tagRegExp, function(match, text) {
|
||||
return replaceMatch(replacers[replacer], replacer, match, text);
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
completeTag: completeTag || null,
|
||||
tag: tag ? tag.replace(/^@/, '') : null,
|
||||
text: unescapeBraces(text),
|
||||
|
||||
return {
|
||||
tags: tagInfo,
|
||||
newString: string.trim()
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace multiple inline tags with other text.
|
||||
* Replace all instances of an inline tag with other text.
|
||||
*
|
||||
* @param {string} string - The string in which to replace the inline tag.
|
||||
* @param {Object} replacers - The functions that are used to replace text in the string. The keys
|
||||
* must contain tag names (for example, `@link`), and the values must contain functions with the
|
||||
* type {@link module:jsdoc/tag/inline.InlineTagReplacer}.
|
||||
* @return {module:jsdoc/tag/inline.InlineTagInfo} The updated string, as well as information about
|
||||
* the inline tag.
|
||||
* @param {string} tag - The name of the inline tag to replace.
|
||||
* @param {module:jsdoc/tag/inline.InlineTagReplacer} replacer - The function that is used to
|
||||
* replace text in the string.
|
||||
* @return {module:jsdoc/tag/inline.InlineTagResult} The updated string, as well as information
|
||||
* about the inline tags that were found.
|
||||
*/
|
||||
exports.replaceInlineTags = function(string, replacers) {
|
||||
var result = {
|
||||
newString: string
|
||||
};
|
||||
exports.replaceInlineTag = function(string, tag, replacer) {
|
||||
var replacers = {};
|
||||
replacers[tag] = replacer;
|
||||
|
||||
Object.keys(replacers).forEach(function(tag) {
|
||||
result = exports.replaceInlineTag.call(this, result.newString, tag, replacers[tag]);
|
||||
});
|
||||
|
||||
return result;
|
||||
return exports.replaceInlineTags(string, replacers);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Extract inline tags from a string, replacing them with an empty string.
|
||||
*
|
||||
* @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.
|
||||
* @param {?string} tag - The inline tag to extract.
|
||||
* @return {module:jsdoc/tag/inline.InlineTagResult} The updated string, as well as information
|
||||
* about the inline tags that were found.
|
||||
*/
|
||||
exports.extractInlineTag = function(string, tag) {
|
||||
return exports.replaceInlineTag(string, tag, function(string, tagInfo) {
|
||||
return string.replace(tagInfo.completeTag, '');
|
||||
return exports.replaceInlineTag(string, tag, function() {
|
||||
return '';
|
||||
});
|
||||
};
|
||||
|
||||
@ -6,21 +6,89 @@
|
||||
* @license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Information about a type expression extracted from tag text.
|
||||
*
|
||||
* @typedef TypeExpressionInfo
|
||||
* @memberof module:jsdoc/tag/type
|
||||
* @property {string} expression - The type expression.
|
||||
* @property {string} text - The updated tag text.
|
||||
*/
|
||||
|
||||
/** @private */
|
||||
function unescapeBraces(text) {
|
||||
return text.replace(/\\\{/g, '{')
|
||||
.replace(/\\\}/g, '}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a type expression from the tag text.
|
||||
*
|
||||
* @private
|
||||
* @param {string} string - The tag text.
|
||||
* @return {module:jsdoc/tag/type.TypeExpressionInfo} The type expression and updated tag text.
|
||||
*/
|
||||
function extractTypeExpression(string) {
|
||||
string = string || '';
|
||||
|
||||
var completeExpression;
|
||||
var count = 0;
|
||||
var position = 0;
|
||||
var expression = '';
|
||||
var startIndex = string.indexOf('{');
|
||||
var textStartIndex;
|
||||
|
||||
if (startIndex !== -1) {
|
||||
// advance to the first character in the type expression
|
||||
position = textStartIndex = startIndex + 1;
|
||||
count++;
|
||||
|
||||
while (position < string.length) {
|
||||
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) {
|
||||
completeExpression = string.slice(startIndex, position + 1);
|
||||
expression = string.slice(textStartIndex, position).trim();
|
||||
break;
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
}
|
||||
|
||||
string = completeExpression ? string.replace(completeExpression, '') : string;
|
||||
|
||||
return {
|
||||
expression: unescapeBraces(expression),
|
||||
newString: string.trim()
|
||||
};
|
||||
}
|
||||
|
||||
/** @private */
|
||||
function getTagInfo(tagValue, canHaveName, canHaveType) {
|
||||
var extractInlineTag = require('jsdoc/tag/inline').extractInlineTag;
|
||||
|
||||
var name = '';
|
||||
var typeExpression = '';
|
||||
var text = tagValue;
|
||||
var typeAndText;
|
||||
var expressionAndText;
|
||||
var typeOverride;
|
||||
|
||||
if (canHaveType) {
|
||||
typeAndText = extractInlineTag(text);
|
||||
typeExpression = typeAndText.text || typeExpression;
|
||||
text = typeAndText.newString;
|
||||
expressionAndText = extractTypeExpression(text);
|
||||
typeExpression = expressionAndText.expression;
|
||||
text = expressionAndText.newString;
|
||||
}
|
||||
|
||||
if (canHaveName) {
|
||||
@ -32,8 +100,10 @@ function getTagInfo(tagValue, canHaveName, canHaveType) {
|
||||
|
||||
// an inline @type tag, like {@type Foo}, overrides the type expression
|
||||
if (canHaveType) {
|
||||
typeOverride = extractInlineTag(text, 'type');
|
||||
typeExpression = typeOverride.text || typeExpression;
|
||||
typeOverride = require('jsdoc/tag/inline').extractInlineTag(text, 'type');
|
||||
if (typeOverride.tags && typeOverride.tags[0]) {
|
||||
typeExpression = typeOverride.tags[0].text || typeExpression;
|
||||
}
|
||||
text = typeOverride.newString;
|
||||
}
|
||||
|
||||
@ -191,9 +261,9 @@ var typeParsers = [parseName, parseTypeExpression];
|
||||
*
|
||||
* @param {string} tagValue - The value of the tag. For example, the tag `@param {string} name` has
|
||||
* a value of `{string} name`.
|
||||
* @param {boolean} canHaveName - Indicates whether the value can include a member name.
|
||||
* @param {boolean} canHaveName - Indicates whether the value can include a symbol name.
|
||||
* @param {boolean} canHaveType - Indicates whether the value can include a type expression that
|
||||
* describes the member.
|
||||
* describes the symbol.
|
||||
* @return {module:jsdoc/tag/type.TagInfo} Information obtained from the tag.
|
||||
* @throws {Error} Thrown if a type expression cannot be parsed.
|
||||
*/
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/*global describe: true, expect: true, it: true */
|
||||
/*global describe: true, expect: true, it: true, jasmine: true */
|
||||
|
||||
describe('jsdoc/tag/inline', function() {
|
||||
var jsdoc = {
|
||||
@ -23,13 +23,13 @@ describe('jsdoc/tag/inline', function() {
|
||||
});
|
||||
|
||||
describe('replaceInlineTag', function() {
|
||||
it('should throw if the replacer parameter is invalid', function() {
|
||||
it('should throw if the tag is matched and the replacer is invalid', function() {
|
||||
function badReplacerUndefined() {
|
||||
jsdoc.tag.inline.replaceInlineTag('foo', 'bar');
|
||||
jsdoc.tag.inline.replaceInlineTag('{@foo tag}', 'foo');
|
||||
}
|
||||
|
||||
function badReplacerString() {
|
||||
jsdoc.tag.inline.replaceInlineTag('foo', 'bar', 'hello');
|
||||
jsdoc.tag.inline.replaceInlineTag('{@foo tag}', 'foo', 'hello');
|
||||
}
|
||||
|
||||
expect(badReplacerUndefined).toThrow();
|
||||
@ -37,108 +37,87 @@ describe('jsdoc/tag/inline', function() {
|
||||
});
|
||||
|
||||
it('should not find anything if there is no text in braces', function() {
|
||||
function replacer(string, tagInfo) {
|
||||
expect(string).toBe('braceless text');
|
||||
expect(tagInfo.completeTag).toBe('');
|
||||
expect(tagInfo.text).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');
|
||||
var replacer = jasmine.createSpy('replacer');
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('braceless text', 'foo', replacer);
|
||||
expect(replacer).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should cope with bad escapement at the end of the string', function() {
|
||||
function replacer(string, tagInfo) {
|
||||
expect(string).toBe('bad {escapement \\');
|
||||
expect(tagInfo.completeTag).toBe('');
|
||||
expect(tagInfo.text).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, tagInfo) {
|
||||
expect(string).toBe('a {braces \\} test}');
|
||||
expect(tagInfo.completeTag).toBe('{braces \\} test}');
|
||||
expect(tagInfo.text).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}');
|
||||
var replacer = jasmine.createSpy('replacer');
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('bad {@foo escapement \\', 'foo',
|
||||
replacer);
|
||||
expect(replacer).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should work if the tag is the entire string', function() {
|
||||
function replacer(string, tagInfo) {
|
||||
expect(string).toBe('{text in braces}');
|
||||
expect(tagInfo.completeTag).toBe('{text in braces}');
|
||||
expect(string).toBe('{@foo text in braces}');
|
||||
expect(tagInfo.completeTag).toBe('{@foo text in braces}');
|
||||
expect(tagInfo.text).toBe('text in braces');
|
||||
|
||||
return string;
|
||||
return tagInfo.completeTag;
|
||||
}
|
||||
|
||||
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}');
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('{@foo text in braces}', 'foo',
|
||||
replacer);
|
||||
expect(result.tags[0]).toBeDefined();
|
||||
expect(typeof result.tags[0]).toBe('object');
|
||||
expect(result.tags[0].tag).toBe('foo');
|
||||
expect(result.tags[0].text).toBe('text in braces');
|
||||
expect(result.newString).toBe('{@foo text in braces}');
|
||||
});
|
||||
|
||||
it('should work if the tag is at the beginning of the string', function() {
|
||||
function replacer(string, tagInfo) {
|
||||
expect(string).toBe('{test string} ahoy');
|
||||
expect(tagInfo.completeTag).toBe('{test string}');
|
||||
expect(string).toBe('{@foo test string} ahoy');
|
||||
expect(tagInfo.completeTag).toBe('{@foo test string}');
|
||||
expect(tagInfo.text).toBe('test string');
|
||||
|
||||
return string;
|
||||
return tagInfo.completeTag;
|
||||
}
|
||||
|
||||
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');
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('{@foo test string} ahoy', 'foo',
|
||||
replacer);
|
||||
expect(result.tags[0]).toBeDefined();
|
||||
expect(typeof result.tags[0]).toBe('object');
|
||||
expect(result.tags[0].tag).toBe('foo');
|
||||
expect(result.tags[0].text).toBe('test string');
|
||||
expect(result.newString).toBe('{@foo test string} ahoy');
|
||||
});
|
||||
|
||||
it('should work if the tag is in the middle of the string', function() {
|
||||
function replacer(string, tagInfo) {
|
||||
expect(string).toBe('a {test string} yay');
|
||||
expect(tagInfo.completeTag).toBe('{test string}');
|
||||
expect(string).toBe('a {@foo test string} yay');
|
||||
expect(tagInfo.completeTag).toBe('{@foo test string}');
|
||||
expect(tagInfo.text).toBe('test string');
|
||||
|
||||
return string;
|
||||
return tagInfo.completeTag;
|
||||
}
|
||||
|
||||
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');
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('a {@foo test string} yay', 'foo',
|
||||
replacer);
|
||||
expect(result.tags[0]).toBeDefined();
|
||||
expect(typeof result.tags[0]).toBe('object');
|
||||
expect(result.tags[0].tag).toBe('foo');
|
||||
expect(result.tags[0].text).toBe('test string');
|
||||
expect(result.newString).toBe('a {@foo test string} yay');
|
||||
});
|
||||
|
||||
it('should work if the tag is at the end of the string', function() {
|
||||
function replacer(string, tagInfo) {
|
||||
expect(string).toBe('a {test string}');
|
||||
expect(tagInfo.completeTag).toBe('{test string}');
|
||||
expect(string).toBe('a {@foo test string}');
|
||||
expect(tagInfo.completeTag).toBe('{@foo test string}');
|
||||
expect(tagInfo.text).toBe('test string');
|
||||
|
||||
return string;
|
||||
return tagInfo.completeTag;
|
||||
}
|
||||
|
||||
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}');
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('a {@foo test string}', 'foo', replacer);
|
||||
expect(result.tags[0]).toBeDefined();
|
||||
expect(typeof result.tags[0]).toBe('object');
|
||||
expect(result.tags[0].tag).toBe('foo');
|
||||
expect(result.tags[0].text).toBe('test string');
|
||||
expect(result.newString).toBe('a {@foo test string}');
|
||||
});
|
||||
|
||||
it('should replace the string with the specified value', function() {
|
||||
@ -146,40 +125,31 @@ describe('jsdoc/tag/inline', function() {
|
||||
return 'REPLACED!';
|
||||
}
|
||||
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('a {test string}', null, replacer);
|
||||
expect(result.newString).toBe('REPLACED!');
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('a {@foo test string}', 'foo', replacer);
|
||||
expect(result.newString).toBe('a REPLACED!');
|
||||
});
|
||||
|
||||
it('should work when there are nested braces', function() {
|
||||
function replacer(string, tagInfo) {
|
||||
expect(string).toBe('some {{double}} braces');
|
||||
expect(tagInfo.completeTag).toBe('{{double}}');
|
||||
expect(tagInfo.text).toBe('{double}');
|
||||
|
||||
return string;
|
||||
it('should process all occurrences of a tag', function() {
|
||||
function replacer() {
|
||||
return 'stuff';
|
||||
}
|
||||
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('some {{double}} braces', null,
|
||||
replacer);
|
||||
expect(result.tag).toBe(null);
|
||||
expect(result.text).toBe('{double}');
|
||||
expect(result.newString).toBe('some {{double}} braces');
|
||||
var result = jsdoc.tag.inline.replaceInlineTag('some {@foo text} with multiple ' +
|
||||
'{@foo tags}', 'foo', replacer);
|
||||
|
||||
expect(result.tags[0]).toBeDefined();
|
||||
expect(typeof result.tags[0]).toBe('object');
|
||||
expect(result.tags[0].tag).toBe('foo');
|
||||
expect(result.tags[0].text).toBe('text');
|
||||
|
||||
expect(result.tags[1]).toBeDefined();
|
||||
expect(typeof result.tags[1]).toBe('object');
|
||||
expect(result.tags[1].tag).toBe('foo');
|
||||
expect(result.tags[1].text).toBe('tags');
|
||||
|
||||
expect(result.newString).toBe('some stuff with multiple stuff');
|
||||
});
|
||||
|
||||
it('should work when a tag is specified', function() {
|
||||
function replacer(string, tagInfo) {
|
||||
expect(string).toBe('a {@foo tag} test');
|
||||
expect(tagInfo.completeTag).toBe('{@foo tag}');
|
||||
expect(tagInfo.text).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
|
||||
@ -198,7 +168,7 @@ describe('jsdoc/tag/inline', function() {
|
||||
foo: function(string, tagInfo) {
|
||||
expect(tagInfo.completeTag).toBe('{@foo text}');
|
||||
expect(tagInfo.text).toBe('text');
|
||||
return string.replace(tagInfo.completeTag, 'stuff');
|
||||
return 'stuff';
|
||||
}
|
||||
};
|
||||
|
||||
@ -213,12 +183,12 @@ describe('jsdoc/tag/inline', function() {
|
||||
foo: function(string, tagInfo) {
|
||||
expect(tagInfo.completeTag).toBe('{@foo text}');
|
||||
expect(tagInfo.text).toBe('text');
|
||||
return string.replace(tagInfo.completeTag, 'stuff');
|
||||
return 'stuff';
|
||||
},
|
||||
bar: function(string, tagInfo) {
|
||||
expect(tagInfo.completeTag).toBe('{@bar multiple}');
|
||||
expect(tagInfo.text).toBe('multiple');
|
||||
return string.replace(tagInfo.completeTag, 'awesome');
|
||||
return 'awesome';
|
||||
}
|
||||
};
|
||||
|
||||
@ -229,17 +199,12 @@ describe('jsdoc/tag/inline', function() {
|
||||
|
||||
// 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.tags[0]).toBeDefined();
|
||||
expect(typeof result.tags[0]).toBe('object');
|
||||
expect(result.tags[0].tag).toBe('tagged');
|
||||
expect(result.tags[0].text).toBe('text');
|
||||
expect(result.newString).toBe('some');
|
||||
});
|
||||
});
|
||||
|
||||
@ -122,6 +122,60 @@ describe('jsdoc/tag/type', function() {
|
||||
expect(info.type).toEqual( ['string', 'number', 'boolean', 'function'] );
|
||||
});
|
||||
|
||||
it('should not find any type if there is no text in braces', function() {
|
||||
var desc = 'braceless text';
|
||||
var info = jsdoc.tag.type.parse(desc, false, true);
|
||||
expect(info.type).toEqual([]);
|
||||
});
|
||||
|
||||
it('should cope with bad escapement at the end of the string', function() {
|
||||
var desc = 'bad {escapement \\';
|
||||
var info = jsdoc.tag.type.parse(desc, false, true);
|
||||
expect(info.type).toEqual([]);
|
||||
expect(info.text).toBe(desc);
|
||||
});
|
||||
|
||||
it('should handle escaped braces correctly', function() {
|
||||
var desc = '{weirdObject."with\\}AnnoyingProperty"}';
|
||||
var info = jsdoc.tag.type.parse(desc, false, true);
|
||||
expect(info.type[0]).toBe('weirdObject."with}AnnoyingProperty"');
|
||||
});
|
||||
|
||||
it('should work if the type expression is the entire string', function() {
|
||||
var desc = '{textInBraces}';
|
||||
var info = jsdoc.tag.type.parse(desc, false, true);
|
||||
expect(info.type[0]).toBe('textInBraces');
|
||||
});
|
||||
|
||||
it('should work if the type expression is at the beginning of the string', function() {
|
||||
var desc = '{testString} ahoy';
|
||||
var info = jsdoc.tag.type.parse(desc, false, true);
|
||||
expect(info.type[0]).toBe('testString');
|
||||
expect(info.text).toBe('ahoy');
|
||||
});
|
||||
|
||||
it('should work if the type expression is in the middle of the string', function() {
|
||||
var desc = 'a {testString} yay';
|
||||
var info = jsdoc.tag.type.parse(desc, false, true);
|
||||
expect(info.type[0]).toBe('testString');
|
||||
expect(info.text).toBe('a yay');
|
||||
});
|
||||
|
||||
it('should work if the tag is at the end of the string', function() {
|
||||
var desc = 'a {testString}';
|
||||
var info = jsdoc.tag.type.parse(desc, false, true);
|
||||
expect(info.type[0]).toBe('testString');
|
||||
expect(info.text).toBe('a');
|
||||
});
|
||||
|
||||
it('should work when there are nested braces', function() {
|
||||
var desc = 'some {{double}} braces';
|
||||
var info = jsdoc.tag.type.parse(desc, false, true);
|
||||
// we currently stringify all record types as 'Object'
|
||||
expect(info.type[0]).toBe('Object');
|
||||
expect(info.text).toBe('some braces');
|
||||
});
|
||||
|
||||
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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user