Fixes and tests related to params and types.

This commit is contained in:
Michael Mathews 2010-06-15 15:37:00 +01:00
parent 9a45e4a8a4
commit 1dac5e534d
5 changed files with 195 additions and 153 deletions

View File

@ -137,49 +137,48 @@
tagName = tag.name;
tagValue = {};
// if (tag.type && tag.type.length) {
// tagValue.type = tag.type;
// // not a long tag
// if (!tag.pname && tag.text) { tagValue.text = tag.text; }
// }
// a long tag
if (tag.pname) {
if (tag.pname || tag.pdesc) { // TODO: should check the list instead?
if ( /^\[(.+)\]$/.test(tag.pname) ) {
tagValue.name = RegExp.$1;
tag.poptional = true;
if (tag.pname) {
if ( /^\[(.+)\]$/.test(tag.pname) ) {
tagValue.name = RegExp.$1;
tag.poptional = true;
}
else {
tagValue.name = tag.pname;
}
}
else {
tagValue.name = tag.pname;
if (tag.type && tag.type.length) {
tagValue.type = tag.type;
}
tagValue.type = tag.type;
// print('```` name is '+tagName+': '+tagValue);
}
if (tag.pdesc) { tagValue.desc = tag.pdesc; }
if (typeof tag.poptional === 'boolean') { tagValue.optional = tag.poptional; }
if (typeof tag.pnullable === 'boolean') { tagValue.nullable = tag.pnullable; }
// tag value is not an object, it's just a simple string
if (!tag.pname) {
if (!tag.pname && !tag.pdesc) { // TODO: should check the list instead?
tagValue = tag.text;
}
if (typeof o[tagName] === 'undefined') { // not defined
o[tagName] = tagValue;
}
else if (o[tagName].push) { // 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);
if (tagValue) {
if (typeof o[tagName] === 'undefined') { // not defined
o[tagName] = tagValue;
}
else if (o[tagName].push) { // 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;
}
@ -265,6 +264,9 @@
else if (tags[i].name === 'protected') {
tags[tags.length] = tag.fromTagText('access protected');
}
else if (tags[i].name === 'public') {
tags[tags.length] = tag.fromTagText('access public');
}
else if (tags[i].name === 'const') {
tags[tags.length] = tag.fromTagText('attribute constant');
}

View File

@ -134,7 +134,7 @@
throw 'module:jsdoc/parser.parseFiles requires argument sourceFiles(none provided).';
}
if (typeof sourceFiles[0] === 'string') { sourceFiles = [sourceFiles]; }
if (typeof sourceFiles === 'string') { sourceFiles = [sourceFiles]; }
for (i = 0, leni = sourceFiles.length; i < leni; i++) {
try {

View File

@ -37,7 +37,8 @@
return new Tag(tagText);
}
var longTags = ['param', 'constructor', 'const', 'module', 'event', 'namespace', 'method', 'member', 'function', 'variable', 'enum'];
var longTags = ['param', 'constructor', 'const', 'module', 'event', 'namespace', 'method', 'member', 'function', 'variable', 'enum', 'returns'];
var anonTags = ['returns'];
/**
@private
@constructor Tag
@ -56,11 +57,14 @@
if (bits) {
this.name = (bits[1] || '').toLowerCase(); // like @name
this.name = synonym(this.name);
this.name = trim( resolveSynonyms(this.name) );
this.text = bits[2] || ''; // all the rest of the tag
this.text = trim( bits[2] ) || ''; // all the rest of the tag
var type, text, optional, nullable;
var /*Array.<string>*/ type,
/*string*/ text,
/*?boolean*/ optional,
/*?boolean*/ nullable;
[type, text, optional, nullable] = jsdoc_type.parse(this.text);
// @type tags are the only tag that is not allowed to have a {type}!
@ -69,17 +73,21 @@
type = [];
}
if (type && type.length) {
this.type = type;
}
// don't add an empty type or null attributes
if (type && type.length) { this.type = type; }
if (optional !== null) { this.poptional = optional; }
if (nullable !== null) { this.pnullable = nullable; }
this.text = text;
if (longTags.indexOf(this.name) > -1) { // is a tag that uses the long format
var [pname, pdesc] = parsePname(this.text);
this.pname = pname;
this.pdesc = pdesc;
if (anonTags.indexOf(this.name) > -1) {
this.pdesc = this.text;
}
else {
var [pname, pdesc] = parsePname(this.text);
this.pname = pname;
this.pdesc = pdesc;
}
}
}
}
@ -96,23 +104,31 @@
@returns Array.<string> The pname and the pdesc.
*/
function parsePname(tagText) {
tagText.match(/^(\S+)(\s+(\S.*))?$/);
tagText.match(/^(\S+)(\s+(\S[\s\S]*))?$/);
return [RegExp.$1, RegExp.$3];
}
function synonym(name) {
if ( synonym.map.hasOwnProperty(name) ) {
return synonym.map[name];
function resolveSynonyms(name) {
if ( exports.synonyms.hasOwnProperty(name) ) {
return exports.synonyms[name];
}
else {
return name;
}
}
synonym.map = {
exports.synonyms = {
'description': 'desc',
'function': 'method',
'variable': 'member'
'function': 'method',
'variable': 'member',
'return': 'returns'
}
//TODO: move into a shared module?
/** @private */
function trim(text) {
if (!text) { return ''; }
return text.replace(/^\s+|\s+$/g, '');
}
})();

View File

@ -17,7 +17,6 @@
exports.parse = function(tagText) {
if (typeof tagText !== 'string') { tagText = ''; }
var type = '',
types = [],
text = '',
count = 0;
@ -43,9 +42,9 @@
[type, optional] = parseOptional(type);
[type, nullable] = parseNullable(type);
types = parseTypes(type); // make it into an array
return [types, text, optional, nullable];
type = parseTypes(type); // make it into an array
return [type, text, optional, nullable];
}
function parseOptional(type) {

View File

@ -1,105 +1,130 @@
(function() {
var jsdoc = { parser: require('jsdoc/parser') };
jsdoc.parser.parseFiles(BASEDIR + 'tests/tag_param.js');
var docset = jsdoc.parser.result;
var testSuite = {
suiteName: 'tag_param',
setUp: function() {
},
tearDown: function() {
},
testParamWithSimpleType: function() {
var docs = docset.getDocsByPath('Shape');
assertEqual(docs.length, 1, 'All constructor doclets by that path name are found.');
var doc = docs[0].toObject(),
params = doc.param;
//print('>>> doc is '+doc.toSource());
//print('>>> params is '+params.toSource());
assertEqual(params[0].name, 'top', 'The found parameter has the correct name.');
assertEqual(typeof params[0].type, 'object', 'The found parameter has types.');
assertEqual(params[0].type.length, 1, 'The found parameter has the correct number of types.');
assertEqual(params[0].type[0], 'number', 'The found parameter has the correct type value.');
},
testParamWithNullableType: function() {
var docs = docset.getDocsByPath('Shape');
assertEqual(docs.length, 1, 'All constructor doclets by that path name are found.');
var doc = docs[0].toObject(),
params = doc.param;
assertEqual(params[1].name, 'left', 'The found parameter has the correct name.');
assertEqual(typeof params[1].type, 'object', 'The found parameter has types.');
assertEqual(params[1].type.length, 1, 'The found parameter has the correct number of types.');
assertEqual(params[1].type[0], 'number', 'The found parameter has the correct type value.');
assertEqual(params[1].nullable, false, 'The found parameter has the correct !nullable value.');
assertEqual(params[2].nullable, true, 'The found parameter has the correct ?nullable value.');
},
testParamWithOptionalType: function() {
var docs = docset.getDocsByPath('Shape');
assertEqual(docs.length, 1, 'All doclets by that path name are found.');
var doc = docs[0].toObject(),
params = doc.param;
assertEqual(params[3].name, 'fixed', 'The found parameter has the correct name.');
assertEqual(typeof params[1].type, 'object', 'The found parameter has types.');
assertEqual(params[3].type.length, 1, 'The found parameter has the correct number of types.');
assertEqual(params[3].type[0], 'boolean', 'The found parameter has the correct type value.');
assertEqual(params[3].nullable, undefined, 'The found parameter has the default nullable value.');
assertEqual(params[3].optional, true, 'The found parameter has the correct optional value.');
},
testParamWithMultipleType: function() {
var docs = docset.getDocsByPath('rotate');
assertEqual(docs.length, 1, 'All doclets by that path name are found.');
var doc = docs[0].toObject(),
params = doc.param;
assertEqual(params[0].name, 'deg', 'The found parameter has the correct name.');
assertEqual(typeof params[0].type, 'object', 'The found parameter has types.');
assertEqual(params[0].type.length, 2, 'The found parameter has the correct number of types.');
assertEqual(params[0].type[0], 'Degree', 'The found parameter has the correct type[0] value.');
assertEqual(params[0].type[1], 'number', 'The found parameter has the correct type[1] value.');
assertEqual(params[1].name, 'axis', 'The found parameter has the correct name.');
assertEqual(params[1].optional, true, 'The found parameter has the correct optional.');
}
};
testSuites.push(testSuite);
})();
function sample() {
/** @constructor
@param {number} top
@param {!number} left
@param {?number} sides
@param {boolean=} fixed
*/
function Shape(top, left, sides, fixed) {
}
/** @method
@param {Degree|number} deg
@param [axis]
*/
function rotate(deg, axis) {
}
}
(function() {
var jsdoc = { parser: require('jsdoc/parser') };
jsdoc.parser.parseFiles(BASEDIR + 'tests/tag_param.js');
var docset = jsdoc.parser.result;
var testSuite = {
suiteName: 'tag_param',
setUp: function() {
},
tearDown: function() {
},
testParamWithSimpleType: function() {
var docs = docset.getDocsByPath('Shape');
assertEqual(docs.length, 1, 'All constructor doclets by that path name are found.');
var doc = docs[0].toObject(),
params = doc.param;
//print('>>> doc is '+doc.toSource());
//print('>>> params is '+params.toSource());
assertEqual(params[0].name, 'top', 'The found parameter has the correct name.');
assertEqual(typeof params[0].type, 'object', 'The found parameter has types.');
assertEqual(params[0].type.length, 1, 'The found parameter has the correct number of types.');
assertEqual(params[0].type[0], 'number', 'The found parameter has the correct type value.');
},
testParamWithNullableType: function() {
var docs = docset.getDocsByPath('Shape');
assertEqual(docs.length, 1, 'All constructor doclets by that path name are found.');
var doc = docs[0].toObject(),
params = doc.param;
assertEqual(params[1].name, 'left', 'The found parameter has the correct name.');
assertEqual(typeof params[1].type, 'object', 'The found parameter has types.');
assertEqual(params[1].type.length, 1, 'The found parameter has the correct number of types.');
assertEqual(params[1].type[0], 'number', 'The found parameter has the correct type value.');
assertEqual(params[1].nullable, false, 'The found parameter has the correct !nullable value.');
assertEqual(params[2].nullable, true, 'The found parameter has the correct ?nullable value.');
},
testParamWithOptionalType: function() {
var docs = docset.getDocsByPath('Shape');
assertEqual(docs.length, 1, 'All doclets by that path name are found.');
var doc = docs[0].toObject(),
params = doc.param;
assertEqual(params[3].name, 'fixed', 'The found parameter has the correct name.');
assertEqual(typeof params[1].type, 'object', 'The found parameter has types.');
assertEqual(params[3].type.length, 1, 'The found parameter has the correct number of types.');
assertEqual(params[3].type[0], 'boolean', 'The found parameter has the correct type value.');
assertEqual(params[3].nullable, undefined, 'The found parameter has the default nullable value.');
assertEqual(params[3].optional, true, 'The found parameter has the correct optional value.');
},
testParamWithMultipleType: function() {
var docs = docset.getDocsByPath('rotate');
assertEqual(docs.length, 1, 'All doclets by that path name are found.');
var doc = docs[0].toObject(),
params = doc.param;
assertEqual(params[0].name, 'deg', 'The found parameter has the correct name.');
assertEqual(typeof params[0].type, 'object', 'The found parameter has types.');
assertEqual(params[0].type.length, 2, 'The found parameter has the correct number of types.');
assertEqual(params[0].type[0], 'Degree', 'The found parameter has the correct type[0] value.');
assertEqual(params[0].type[1], 'number', 'The found parameter has the correct type[1] value.');
assertEqual(params[1].name, 'axis', 'The found parameter has the correct name.');
assertEqual(params[1].optional, true, 'The found parameter has the correct optional.');
},
testParamDesc: function() {
var docs = docset.getDocsByPath('resize');
assertEqual(docs.length, 1, 'All doclets by that path name are found.');
var doc = docs[0].toObject(),
param = doc.param;
assertEqual(typeof param, 'object', 'The found parameter has the expected type.');
assertEqual(param.name, 'ratio', 'The found parameter has the correct name.');
assertEqual(typeof param.type, 'object', 'The found parameter has types.');
assertEqual(param.type.length, 2, 'The found parameter has the correct number of types.');
assertEqual(param.type[0], 'Function', 'The found parameter has the correct type[0] value.');
assertEqual(param.type[1], 'number', 'The found parameter has the correct type[1] value.');
assertEqual(param.desc, 'A number\n or a function.', 'The found parameter has the expected description.');
}
};
testSuites.push(testSuite);
})();
function sample() {
/** @constructor
@param {number} top
@param {!number} left
@param {?number} sides
@param {boolean=} fixed
*/
function Shape(top, left, sides, fixed) {
}
/** @method
@param {Degree|number} deg
@param [axis]
*/
function rotate(deg, axis) {
}
/** @method
@param {Function|number} ratio A number
or a function.
*/
function resize(ratio) {
}
}