diff --git a/modules/jsdoc/doclet.js b/modules/jsdoc/doclet.js index c5ef022b..bc1d44d2 100644 --- a/modules/jsdoc/doclet.js +++ b/modules/jsdoc/doclet.js @@ -271,7 +271,7 @@ } else if (tags[i].name === 'name') { if (name && name !== tags[i].value) { - throw new DocTagConflictError('Conflicting names in documentation: '+name+', '+tags[i].value); + throw new DocTagConflictError('Conflicting names in documentation: "'+name+'", and "'+tags[i].value+'"'); } taggedName = name = tags[i].value; } @@ -299,7 +299,7 @@ else { if (tags[i].value) { if (name && name !== tags[i].value) { - throw new DocTagConflictError('Conflicting names in documentation: '+name+', '+tags[i].value); + throw new DocTagConflictError('Conflicting names in documentation: "'+name+'", and "'+tags[i].value+'"'); } name = tags[i].value; } diff --git a/modules/jsdoc/tagdictionary.js b/modules/jsdoc/tagdictionary.js index ba1545e6..b6da7e68 100644 --- a/modules/jsdoc/tagdictionary.js +++ b/modules/jsdoc/tagdictionary.js @@ -19,7 +19,9 @@ 'member': 'memberof', 'overview': 'file', 'fileoverview':'file', - 'const': 'constant' + 'const': 'constant', + 'augments': 'extends', + 'throws': 'exception' }; TagDictionary.resolveSynonyms = function(name) { @@ -44,112 +46,136 @@ tagDefinitions['@'+title] = this; } -//// default properties of all tags + // default properties of all tags TagDefinition.prototype = { isExported : false, // this tag should appear as a top level property in the doclet? setsDocletIsa : false, // the name of this tag is used to define the doclet's isa property setsDocletName : false, // this tag can be used to name the doclet setsDocletAccess: false, // the name of this tag becomes the access of the doclet setsDocletType : false, // the type of this tag becomes th type of the doclet - setsDocletDocspace : false, // the name of this tag becomes the docspace for the doclet name, like "event:" + setsDocletDocspace: false, // the name of this tag becomes the docspace for the doclet name, like "event:" canHaveType : false, // this tag can have a {type} canHavePname : false, // this tag can have a parameter-type name canHavePdesc : false, // this tag can have a parameter-type desc keepsWhitespace: false // don't try to tidy up the whitespace in this tag? }; - -//// default event handlers? -// TagDefinition.prototype.onAddTagToDoclet = function(tag, doclet) { -// if (this.setsDocletIsa) { -// if (doclet.isa) { -// throw 'Overwriting existing isa in doclet: was "'+doclet.isa+'", now "'+this.title+'"'; -// } -// doclet.isa = this.title; -// } -// -// if (this.setsDocletName) { -// if (doclet.name) { -// throw 'Overwriting existing name in doclet: was "'+doclet.name+'", now "'+this.title+'"'; -// } -// doclet.name = this.title; -// } -// } - // @attribute - new TagDefinition('attribute', { + /** Syntax: @attribute + @property {TagDefinition} attribute + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('attribute', { isExported: true }); - // @desc - new TagDefinition('desc', { // t + /** Syntax: @desc + @property {TagDefinition} desc + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('desc', { // t isExported: true }); - // @isa - new TagDefinition('isa', { + /** Syntax: @isa + @property {TagDefinition} isa + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('isa', { isExported: true }); - // @name - new TagDefinition('name', { + /** Syntax: @name + @property {TagDefinition} name + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('name', { isExported: true }); - // @path - new TagDefinition('path', { + /** Syntax: @path + @property {TagDefinition} path + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('path', { isExported: true }); - // @memberof - new TagDefinition('memberof', { //t + /** Syntax: @memberOf + @property {TagDefinition} memberof + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('memberof', { //t isExported: true }); - // @namespace - new TagDefinition('namespace', { //t - setsDocletIsa: true, - setsDocletName: true - }); - - // @constructor - new TagDefinition('constructor', { //t - setsDocletIsa: true, - setsDocletName: true - }); - - // @constant - new TagDefinition('constant', { + /** Syntax: @namespace + @property {TagDefinition} namespace + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('namespace', { //t canHaveType: true, setsDocletType: true, setsDocletIsa: true, setsDocletName: true }); - // @enum - new TagDefinition('enum', { + /** Syntax: @constructor + @property {TagDefinition} constructor + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('constructor', { //t + setsDocletIsa: true, + setsDocletName: true + }); + + /** Syntax: @constant|const + @property {TagDefinition} constant + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('constant', { canHaveType: true, setsDocletType: true, setsDocletIsa: true, setsDocletName: true }); - // @file|overview|fileoverview - new TagDefinition('file', { //t + /** Syntax: @enum + @property {TagDefinition} enum + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('enum', { + canHaveType: true, + setsDocletType: true, + setsDocletIsa: true, + setsDocletName: true + }); + + /** Syntax: @file|overview|fileoverview + @property {TagDefinition} file + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('file', { //t setsDocletIsa: true, setsDocletName: true, setsDocletDocspace: true }); - // @method - new TagDefinition('method', { //t + /** Syntax: @method|function + @property {TagDefinition} method + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('method', { //t canHaveType: true, canHavePname: true, canHavePdesc: true, setsDocletName: true }); - // @property - new TagDefinition('property', { //t + /** Syntax: @property + @property {TagDefinition} property + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('property', { //t canHaveType: true, canHavePname: true, canHavePdesc: true, @@ -157,62 +183,110 @@ setsDocletType: true }); - // @event - new TagDefinition('event', { + /** Syntax: @event + @property {TagDefinition} event + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('event', { setsDocletIsa: true, setsDocletName: true, setsDocletDocspace: true }); - // @module - new TagDefinition('module', { + /** Syntax: @module + @property {TagDefinition} module + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('module', { setsDocletIsa: true, setsDocletName: true, setsDocletDocspace: true }); - // @example - new TagDefinition('example', { + /** Syntax: @example + @property {TagDefinition} example + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('example', { isExported: true, keepsWhitespace: true }); - // @param - new TagDefinition('param', { + /** Syntax: @param + @property {TagDefinition} param + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('param', { isExported: true, canHaveType: true, canHavePname: true, canHavePdesc: true }); - // @type - new TagDefinition('type', { + /** Syntax: @type + @property {TagDefinition} type + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('type', { //t isExported: true, canHaveType: true }); - // @returns|return - new TagDefinition('returns', { + /** Syntax: @returns|return + @property {TagDefinition} returns + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('returns', { //t isExported: true, canHaveType: true, canHavePdesc: true }); - // @private - new TagDefinition('private', { + /** Syntax: @private + @property {TagDefinition} private + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('private', { setsDocletAccess: true }); - // @protected - new TagDefinition('protected', { + /** Syntax: @protected + @property {TagDefinition} protected + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('protected', { setsDocletAccess: true }); - // @public - new TagDefinition('public', { + /** Syntax: @public + @property {TagDefinition} public + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('public', { setsDocletAccess: true }); + /** Syntax: @exception|throws + @property {TagDefinition} exception + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('exception', { + isExported: true + }); + /** Syntax: @fires + @property {TagDefinition} fires + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('fires', { //t + isExported: true + }); + /** Syntax: @extends|augments + @property {TagDefinition} extends + @memberOf module:jsdoc/tagdictionary.tagDefinitions + */ + new TagDefinition('extends', { + isExported: true + }); })(); \ No newline at end of file diff --git a/test/runall.js b/test/runall.js index 51e992f0..cc9fe4ad 100644 --- a/test/runall.js +++ b/test/runall.js @@ -19,6 +19,8 @@ load(BASEDIR + '/test/tests/17_tag_example.js'); load(BASEDIR + '/test/tests/20_tag_file.js'); load(BASEDIR + '/test/tests/21_tag_const.js'); load(BASEDIR + '/test/tests/22_tag_preserve.js'); +load(BASEDIR + '/test/tests/23_tag_fires.js'); +load(BASEDIR + '/test/tests/24_tag_exception.js'); // see http://visionmedia.github.com/jspec/ JSpec.run({ diff --git a/test/samples/tag_exception.js b/test/samples/tag_exception.js new file mode 100644 index 00000000..2e36ddff --- /dev/null +++ b/test/samples/tag_exception.js @@ -0,0 +1,12 @@ +/** + * @function divide + * @throws divideByZeroError + */ +function divide(a, b) {} + +/** + * @function read + * @throws fileNotFoundError + * @throws fileTooLargeError + */ +function read(filepath) {} \ No newline at end of file diff --git a/test/samples/tag_fires.js b/test/samples/tag_fires.js new file mode 100644 index 00000000..a649d58f --- /dev/null +++ b/test/samples/tag_fires.js @@ -0,0 +1,12 @@ +/** + * @constructor Widget + * @fires event:disable + */ +function Widget() {} + +/** + * @constructor Overlay + * @fires event:show + * @fires event:hide + */ +function Overlay() {} \ No newline at end of file diff --git a/test/tests/17_tag_example.js b/test/tests/17_tag_example.js index bf073faa..461551d4 100644 --- a/test/tests/17_tag_example.js +++ b/test/tests/17_tag_example.js @@ -29,7 +29,7 @@ }); }); - describe('A doclet with a2 @example tags', function() { + describe('A doclet with 2 @example tags', function() { it('should have an `example` property with length of 2', function() { var doclet = doclets[1]; expect(doclet).to(have_property, 'example'); diff --git a/test/tests/22_tag_preserve.js b/test/tests/22_tag_preserve.js index e1389a16..1231f72b 100644 --- a/test/tests/22_tag_preserve.js +++ b/test/tests/22_tag_preserve.js @@ -14,7 +14,7 @@ doclets = jsdoc.parser.result; }); - describe('A doclet with a only a @preserve tag tag', function() { + describe('A doclet with a only a @preserve tag', function() { it('should not appear in the output', function() { expect(doclets).to(have_length, 0); }); diff --git a/test/tests/23_tag_fires.js b/test/tests/23_tag_fires.js new file mode 100644 index 00000000..476e0856 --- /dev/null +++ b/test/tests/23_tag_fires.js @@ -0,0 +1,40 @@ +(function() { + var jsdoc, + doclets; + + JSpec.describe('@fires', function() { + + before(function() { + // docsets can only be created by parsers + jsdoc = { + tag: require('jsdoc/tag'), + parser: require('jsdoc/parser') + }; + jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_fires.js'); + + doclets = jsdoc.parser.result.map(function($){ return $.toObject(); }); + }); + + describe('A doclet with a a @fires tag', function() { + it('should have a `fires` property', function() { + var doclet = doclets[0]; + expect(doclet).to(have_property, 'fires'); + }); + }); + + describe('The value of the `fires` property', function() { + it('should be equal to the given tag value', function() { + var doclet = doclets[0]; + expect(doclet.fires).to(eql, 'event:disable'); + }); + }); + + describe('A doclet with a 2 @fires tags', function() { + it('should have a `fires` property set to an array of length 2', function() { + var doclet = doclets[1]; + expect(doclet).to(have_property, 'fires'); + expect(doclet.fires).to(have_length, 2); + }); + }); + }); +})(); diff --git a/test/tests/24_tag_exception.js b/test/tests/24_tag_exception.js new file mode 100644 index 00000000..3e9f638b --- /dev/null +++ b/test/tests/24_tag_exception.js @@ -0,0 +1,40 @@ +(function() { + var jsdoc, + doclets; + + JSpec.describe('@exception', function() { + + before(function() { + // docsets can only be created by parsers + jsdoc = { + tag: require('jsdoc/tag'), + parser: require('jsdoc/parser') + }; + jsdoc.parser.parseFiles(BASEDIR + 'test/samples/tag_exception.js'); + + doclets = jsdoc.parser.result.map(function($){ return $.toObject(); }); + }); + + describe('A doclet with a a @exception tag', function() { + it('should have a `exception` property', function() { + var doclet = doclets[0]; + expect(doclet).to(have_property, 'exception'); + }); + }); + + describe('The value of the `exception` property', function() { + it('should be equal to the given tag value', function() { + var doclet = doclets[0]; + expect(doclet.exception).to(eql, 'divideByZeroError'); + }); + }); + + describe('A doclet with a 2 @exception tags', function() { + it('should have a `exception` property set to an array of length 2', function() { + var doclet = doclets[1]; + expect(doclet).to(have_property, 'exception'); + expect(doclet.exception).to(have_length, 2); + }); + }); + }); +})();