diff --git a/lib/jsdoc/src/handlers.js b/lib/jsdoc/src/handlers.js index 66218e1e..4bd2eacc 100644 --- a/lib/jsdoc/src/handlers.js +++ b/lib/jsdoc/src/handlers.js @@ -5,6 +5,8 @@ var currentModule = null; +var moduleRegExp = /^((?:module.)?exports|this)(\.|$)/; + function getNewDoclet(comment, e) { var Doclet = require('jsdoc/doclet').Doclet; var util = require('util'); @@ -90,13 +92,20 @@ exports.attachTo = function(parser) { if (!newDoclet.memberof && e.astnode) { var basename = null, scope = ''; - if ( /^((module.)?exports|this)(\.|$)/.test(newDoclet.name) ) { + if ( moduleRegExp.test(newDoclet.name) ) { 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; - 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; scope = 'static'; } diff --git a/test/fixtures/exports.js b/test/fixtures/exports.js index 9c132478..21d11e76 100644 --- a/test/fixtures/exports.js +++ b/test/fixtures/exports.js @@ -7,9 +7,18 @@ /** * Generate a greeting. - * @param {string} [subject="world"] To whom we greet. + * @param {string} [subject="world"] To whom we say hello. * @returns {string} */ exports.sayHello = function(subject) { 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'); +}; diff --git a/test/specs/documentation/exports.js b/test/specs/documentation/exports.js index d5ce8c39..eec64597 100644 --- a/test/specs/documentation/exports.js +++ b/test/specs/documentation/exports.js @@ -1,12 +1,20 @@ -/*global describe: true, expect: true, it: true, jasmine: true */ +/*global describe, expect, it, jasmine */ describe("'exports' symbol in modules", function() { 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() { - expect(typeof sayhello).toEqual('object'); - expect(sayhello.kind).toEqual('function'); - expect(sayhello.memberof).toEqual('module:hello/world'); + 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() { + expect(typeof sayHello).toBe('object'); + expect(sayHello.kind).toBe('function'); + expect(sayHello.memberof).toBe('module:hello/world'); }); -}); \ No newline at end of file + + 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'); + }); +});