Added support for @property tag, with tests.

This commit is contained in:
Michael Mathews 2010-07-01 22:54:50 +01:00
parent f5b2ef38f2
commit e3f6d5a3e5
3 changed files with 108 additions and 20 deletions

View File

@ -217,9 +217,9 @@
}
// other tags that can provide the memberof
var memberofs = {methodof: 'method', eventof: 'event'};
var memberofs = {methodof: 'method', propertyof: 'property', eventof: 'event'};
// other tags that can provide the symbol name
var nameables = ['constructor', 'const', 'module', 'event', 'namespace', 'method', 'member', 'function', 'variable', 'enum'];
var nameables = ['constructor', 'const', 'module', 'event', 'namespace', 'method', 'property', 'function', 'variable', 'enum'];
/**
Expand some shortcut tags. Modifies the tags argument in-place.
@ -236,8 +236,7 @@
memberof = '',
taggedMemberof = '';
var i = tags.length;
while(i--) {
for (var i = 0, leni = tags.length; i < leni; i++) {
if (tags[i].name === 'private') {
tags[tags.length] = parse_tag.fromTagText('access private');
@ -274,26 +273,31 @@
}
if ( nameables.indexOf(tags[i].name) > -1 ) {
if (tags[i].text) {
if (name && name !== tags[i].text) {
throw new DocTagConflictError('Conflicting names in documentation: '+name+', '+tags[i].text);
if (tags[i].name === 'property' && (isa === 'constructor')) {
// for backwards compatability we ignore a @property in a doclet after a @constructor
}
else {
if (tags[i].text) {
if (name && name !== tags[i].text) {
throw new DocTagConflictError('Conflicting names in documentation: '+name+', '+tags[i].text);
}
name = tags[i].text;
}
name = tags[i].text;
}
if (tags[i].pdesc) {
tags[tags.length] = parse_tag.fromTagText('desc ' + tags[i].pdesc);
}
if (tags[i].pdesc) {
tags[tags.length] = parse_tag.fromTagText('desc ' + tags[i].pdesc);
}
if (tags[i].type) {
tags[tags.length] = parse_tag.fromTagText('type ' + tags[i].type.join('|'));
}
if (tags[i].type) {
tags[tags.length] = parse_tag.fromTagText('type ' + tags[i].type.join('|'));
}
if (isa && isa !== tags[i].name) {
throw new DocTagConflictError('Symbol has too many denominations, cannot be both: ' + isa + ' and ' + tags[i].name);
if (isa && isa !== tags[i].name) {
throw new DocTagConflictError('Symbol has too many denominations, cannot be both: ' + isa + ' and ' + tags[i].name);
}
isa = tags[i].name;
if (isa === 'const') { isa = 'property'; } // an exception to the namebale rule
}
isa = tags[i].name;
if (isa === 'const') { isa = 'member'; } // an exception to the namebale rule
}
if ( memberofs.hasOwnProperty(tags[i].name) ) {
@ -341,7 +345,7 @@
if ( doclet.hasTag('const')) {
if (!doclet.hasTag('isa')) {
doclet.tags[doclet.tags.length] = parse_tag.fromTagText('isa member');
doclet.tags[doclet.tags.length] = parse_tag.fromTagText('isa property');
}
if (!doclet.hasTag('readonly') && !doclet.hasTag('const')) {

View File

@ -7,6 +7,7 @@ load(BASEDIR + '/test/tests/06_jsdoc_tag.js');
load(BASEDIR + '/test/tests/10_tag_constructor.js');
load(BASEDIR + '/test/tests/11_tag_namespace.js');
load(BASEDIR + '/test/tests/12_tag_property.js');
// see http://visionmedia.github.com/jspec/
JSpec.run({

View File

@ -0,0 +1,83 @@
(function() {
var jsdoc,
doclets;
JSpec.describe('@property', function() {
before_each(function() {
// docsets can only be created by parsers
jsdoc = {
tag: require('jsdoc/tag'),
parser: require('jsdoc/parser')
};
jsdoc.parser.parseFiles(BASEDIR + 'test/tests/12_tag_property.js');
doclets = jsdoc.parser.result;
});
describe('A doclet with a named property tag attached to a namespace', function() {
it('should have an `isa` property set to "property"', function() {
var doclet = doclets[2].toObject();
expect(doclet).to(have_property, 'isa');
expect(doclet.isa).to(eql, 'property');
});
it('should have a `name` property set to the given name"', function() {
var doclet = doclets[2].toObject();
expect(doclet).to(have_property, 'name');
expect(doclet.name).to(eql, 'fah');
});
it('should have a `memberof` property set to the parent object name', function() {
var doclet = doclets[2].toObject();
expect(doclet).to(have_property, 'memberof');
expect(doclet.memberof).to(eql, 'foo');
});
});
describe('A doclet with a named property tag attached to a constructor', function() {
it('should have an `isa` property set to "property"', function() {
var doclet = doclets[3].toObject();
expect(doclet).to(have_property, 'isa');
expect(doclet.isa).to(eql, 'property');
});
it('should have a `name` property set to the given name"', function() {
var doclet = doclets[3].toObject();
expect(doclet).to(have_property, 'name');
expect(doclet.name).to(eql, 'bah');
});
it('should have a `memberof` property set to the parent object name', function() {
var doclet = doclets[3].toObject();
expect(doclet).to(have_property, 'memberof');
expect(doclet.memberof).to(eql, 'bar');
});
});
describe('A doclet with a named property tag after to a constructor tag', function() {
it('should be a constructor', function() {
var doclet = doclets[4].toObject();
expect(doclet).to(have_property, 'isa');
expect(doclet.isa).to(eql, 'constructor');
});
});
});
})();
(function testarea() {
/** @namespace foo */
/** @constructor bar */
/** @property foo.fah */
/** @property bar.bah */
/** @constructor Zub
@property {string} zip
*/
})();