document new properties on module.exports (#500)

This commit is contained in:
Jeff Williams 2014-02-01 20:12:24 -08:00
parent c96a1215bd
commit 43b6920085
3 changed files with 38 additions and 12 deletions

View File

@ -5,6 +5,8 @@
var currentModule = null; var currentModule = null;
var moduleRegExp = /^((?:module.)?exports|this)(\.|$)/;
function getNewDoclet(comment, e) { function getNewDoclet(comment, e) {
var Doclet = require('jsdoc/doclet').Doclet; var Doclet = require('jsdoc/doclet').Doclet;
var util = require('util'); var util = require('util');
@ -90,13 +92,20 @@ exports.attachTo = function(parser) {
if (!newDoclet.memberof && e.astnode) { if (!newDoclet.memberof && e.astnode) {
var basename = null, var basename = null,
scope = ''; scope = '';
if ( /^((module.)?exports|this)(\.|$)/.test(newDoclet.name) ) { if ( moduleRegExp.test(newDoclet.name) ) {
var nameStartsWith = RegExp.$1; var nameStartsWith = RegExp.$1;
newDoclet.name = newDoclet.name.replace(/^(exports|this)(\.|$)/, ''); // remove stuff that indicates module membership (but don't touch the name
// `module.exports`, which identifies the module object itself)
if (newDoclet.name !== 'module.exports') {
newDoclet.name = newDoclet.name.replace(moduleRegExp, '');
}
// like /** @module foo */ exports.bar = 1; // like /** @module foo */ exports.bar = 1;
if (nameStartsWith === 'exports' && currentModule) { // or /** @module foo */ module.exports.bar = 1;
// but not /** @module foo */ module.exports = 1;
if ( (nameStartsWith === 'exports' || nameStartsWith === 'module.exports') &&
newDoclet.name !== 'module.exports' && currentModule ) {
memberofName = currentModule; memberofName = currentModule;
scope = 'static'; scope = 'static';
} }

View File

@ -7,9 +7,18 @@
/** /**
* Generate a greeting. * Generate a greeting.
* @param {string} [subject="world"] To whom we greet. * @param {string} [subject="world"] To whom we say hello.
* @returns {string} * @returns {string}
*/ */
exports.sayHello = function(subject) { exports.sayHello = function(subject) {
return 'Hello ' + (subject || 'World'); return 'Hello ' + (subject || 'World');
}; };
/**
* Generate a morose farewell.
* @param {string} [subject="world"] To whom we say goodbye.
* @returns {string}
*/
module.exports.sayGoodbye = function(subject) {
return 'Goodbye Cruel ' + (subject || 'World');
};

View File

@ -1,12 +1,20 @@
/*global describe: true, expect: true, it: true, jasmine: true */ /*global describe, expect, it, jasmine */
describe("'exports' symbol in modules", function() { describe("'exports' symbol in modules", function() {
var docSet = jasmine.getDocSetFromFile('test/fixtures/exports.js'); var docSet = jasmine.getDocSetFromFile('test/fixtures/exports.js');
var helloworld = docSet.getByLongname('module:hello/world')[0]; var sayHello = docSet.getByLongname('module:hello/world.sayHello')[0];
var sayhello = docSet.getByLongname('module:hello/world.sayHello')[0]; var sayGoodbye = docSet.getByLongname('module:hello/world.sayGoodbye')[0];
it('When a symbol starts with the special name "exports" and is in a file with a @module tag, the symbol is documented as a member of that module.', function() { it('When a symbol starts with the special name "exports" and is in a file with a ' +
expect(typeof sayhello).toEqual('object'); '@module tag, the symbol is documented as a member of that module.', function() {
expect(sayhello.kind).toEqual('function'); expect(typeof sayHello).toBe('object');
expect(sayhello.memberof).toEqual('module:hello/world'); expect(sayHello.kind).toBe('function');
expect(sayHello.memberof).toBe('module:hello/world');
});
it('When a symbol starts with the special name "module.exports" and is in a file with a ' +
'@module tag, the symbol is documented as a member of that module.', function() {
expect(typeof sayGoodbye).toBe('object');
expect(sayGoodbye.kind).toBe('function');
expect(sayGoodbye.memberof).toBe('module:hello/world');
}); });
}); });