Skip to content

Commit

Permalink
More test cases and fixes for exports inference
Browse files Browse the repository at this point in the history
  • Loading branch information
jfirebaugh committed Oct 12, 2015
1 parent 9822f75 commit 5449757
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 47 deletions.
38 changes: 27 additions & 11 deletions lib/infer/membership.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,23 @@ function extractIdentifiers(path) {
}

/**
* Test whether some identifiers refer to a module export (`exports` or `module.exports`).
* Count leading identifiers that refer to a module export (`exports` or `module.exports`).
* @param {Object} comment parsed comment
* @param {Array<string>} identifiers array of identifier names
* @returns {boolean} true if identifiers refer to a module export
* @returns {number} number of identifiers referring to a module export (0, 1 or 2)
*/
function isModuleExport(identifiers) {
switch (identifiers.length) {
case 1: return identifiers[0] === 'exports';
case 2: return identifiers[0] === 'module' && identifiers[1] === 'exports';
default: return false;
function countModuleIdentifiers(comment, identifiers) {
if (identifiers.length >= 1 &&
(identifiers[0] === 'exports' || (identifiers[0] === 'module' && comment.name === 'exports'))) {
return 1;
}

if (identifiers.length >= 2 &&
(identifiers[0] === 'module' && identifiers[1] === 'exports')) {
return 2;
}

return 0;
}

/**
Expand All @@ -89,17 +96,26 @@ module.exports = function () {
* Set `memberof` and `instance`/`static` tags on `comment` based on the
* array of `identifiers`. If the last element of the `identifiers` is
* `"prototype"`, it is assumed to be an instance member; otherwise static.
* If the `identifiers` start with `exports` or `module.exports`, assign
* membership based on the last seen @module tag or name of the current file.
*
* @param {Object} comment comment for which to infer memberships
* @param {Array<string>} identifiers array of identifier names
* @returns {undefined} mutates `comment`
* @private
*/
function inferMembershipFromIdentifiers(comment, identifiers) {
if (isModuleExport(identifiers)) {
comment.memberof = inferModuleName(currentModule || comment);
comment.scope = 'static';
} else if (identifiers[identifiers.length - 1] === 'prototype') {
/*
* Test whether identifiers start with a module export (`exports` or `module.exports`),
* and if so replace those identifiers with the name of the current module.
*/
var moduleIdentifierCount = countModuleIdentifiers(comment, identifiers);
if (moduleIdentifierCount) {
identifiers = identifiers.slice(moduleIdentifierCount);
identifiers.unshift(inferModuleName(currentModule || comment));
}

if (identifiers[identifiers.length - 1] === 'prototype') {
comment.memberof = identifiers.slice(0, -1).join('.');
comment.scope = 'instance';
} else {
Expand Down
8 changes: 4 additions & 4 deletions test/fixture/_external-deps-included.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
},
"errors": [
{
"message": "memberof reference to module not found",
"message": "memberof reference to index not found",
"commentLineNumber": 0
}
],
Expand All @@ -54,7 +54,7 @@
],
"name": "exports",
"kind": "function",
"memberof": "module",
"memberof": "index",
"scope": "static",
"members": {
"instance": [],
Expand Down Expand Up @@ -103,7 +103,7 @@
},
"errors": [
{
"message": "memberof reference to module not found",
"message": "memberof reference to main not found",
"commentLineNumber": 0
}
],
Expand All @@ -120,7 +120,7 @@
],
"name": "exports",
"kind": "function",
"memberof": "module",
"memberof": "main",
"scope": "static",
"members": {
"instance": [],
Expand Down
4 changes: 2 additions & 2 deletions test/fixture/_multi-file-input.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
},
"errors": [
{
"message": "memberof reference to module not found",
"message": "memberof reference to simple.input not found",
"commentLineNumber": 0
}
],
Expand All @@ -54,7 +54,7 @@
],
"name": "exports",
"kind": "function",
"memberof": "module",
"memberof": "simple.input",
"scope": "static",
"members": {
"instance": [],
Expand Down
4 changes: 2 additions & 2 deletions test/fixture/inline-link.output.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
},
"errors": [
{
"message": "memberof reference to module not found",
"message": "memberof reference to inline-link.input not found",
"commentLineNumber": 0
}
],
Expand Down Expand Up @@ -157,7 +157,7 @@
],
"name": "exports",
"kind": "function",
"memberof": "module",
"memberof": "inline-link.input",
"scope": "static",
"members": {
"instance": [],
Expand Down
4 changes: 2 additions & 2 deletions test/fixture/jsx.output.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
},
"errors": [
{
"message": "memberof reference to module not found",
"message": "memberof reference to jsx.input not found",
"commentLineNumber": 0
}
],
Expand All @@ -53,7 +53,7 @@
}
],
"name": "exports",
"memberof": "module",
"memberof": "jsx.input",
"scope": "static",
"members": {
"instance": [],
Expand Down
4 changes: 2 additions & 2 deletions test/fixture/multiexample.output.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"errors": [
{
"message": "memberof reference to module not found",
"message": "memberof reference to multiexample.input not found",
"commentLineNumber": 0
}
],
Expand Down Expand Up @@ -136,7 +136,7 @@
],
"name": "exports",
"kind": "function",
"memberof": "module",
"memberof": "multiexample.input",
"scope": "static",
"members": {
"instance": [],
Expand Down
4 changes: 2 additions & 2 deletions test/fixture/simple-hashbang.output.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
},
"errors": [
{
"message": "memberof reference to module not found",
"message": "memberof reference to simple-hashbang.input not found",
"commentLineNumber": 0
}
],
Expand All @@ -54,7 +54,7 @@
],
"name": "exports",
"kind": "function",
"memberof": "module",
"memberof": "simple-hashbang.input",
"scope": "static",
"members": {
"instance": [],
Expand Down
4 changes: 2 additions & 2 deletions test/fixture/simple.output.github.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
},
"errors": [
{
"message": "memberof reference to module not found",
"message": "memberof reference to simple.input not found",
"commentLineNumber": 0
}
],
Expand All @@ -56,7 +56,7 @@
],
"name": "exports",
"kind": "function",
"memberof": "module",
"memberof": "simple.input",
"scope": "static",
"members": {
"instance": [],
Expand Down
4 changes: 2 additions & 2 deletions test/fixture/simple.output.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
},
"errors": [
{
"message": "memberof reference to module not found",
"message": "memberof reference to simple.input not found",
"commentLineNumber": 0
}
],
Expand All @@ -54,7 +54,7 @@
],
"name": "exports",
"kind": "function",
"memberof": "module",
"memberof": "simple.input",
"scope": "static",
"members": {
"instance": [],
Expand Down
134 changes: 116 additions & 18 deletions test/lib/infer/membership.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,30 +186,128 @@ test('inferMembership - explicit', function (t) {
});

test('inferMembership - exports', function (t) {
var result = evaluate(function () {
/**
* @module mod
*/
/** Test */
t.equal(evaluate(function () {
/** @module mod */
/** foo */
exports.foo = 1;
});
})[1].memberof, 'mod');

t.equal(evaluate(function () {
/** @module mod */
/** @returns {undefined} foo */
exports.foo = function () {};
})[1].memberof, 'mod');

t.equal(evaluate(function () {
/** @module mod */
/** bar */
exports.foo.bar = 1;
})[1].memberof, 'mod.foo');

t.equal(evaluate(function () {
/** @module mod */
exports.foo = {
/** bar */
bar: 1
};
})[1].memberof, 'mod.foo');

t.equal(evaluate(function () {
/** @module mod */
exports.foo = {
/** @returns {undefined} bar */
bar: function () {}
};
})[1].memberof, 'mod.foo');

t.equal(evaluate(function () {
/** @module mod */
/** @returns {undefined} bar */
exports.foo.prototype.bar = function () {};
})[1].memberof, 'mod.foo');

t.equal(evaluate(function () {
/** @module mod */
exports.foo.prototype = {
/** @returns {undefined} bar */
bar: function () {}
};
})[1].memberof, 'mod.foo');

t.equal(result.length, 2);
t.equal(result[1].memberof, 'mod');
t.end();
});

test('inferMembership - module.exports', function (t) {
var result = evaluate(function () {
/**
* @module mod
*/
/** Test */
t.equal(evaluate(function () {
/** @module mod */
/** foo */
module.exports.foo = 1;
});
})[1].memberof, 'mod');

t.equal(evaluate(function () {
/** @module mod */
/** @returns {undefined} foo */
module.exports.foo = function () {};
})[1].memberof, 'mod');

t.equal(evaluate(function () {
/** @module mod */
/** bar */
module.exports.foo.bar = 1;
})[1].memberof, 'mod.foo');

t.equal(evaluate(function () {
/** @module mod */
module.exports.foo = {
/** bar */
bar: 1
};
})[1].memberof, 'mod.foo');

t.equal(evaluate(function () {
/** @module mod */
module.exports.foo = {
/** @returns {undefined} bar */
bar: function () {}
};
})[1].memberof, 'mod.foo');

t.equal(evaluate(function () {
/** @module mod */
/** @returns {undefined} bar */
module.exports.prototype.bar = function () {};
})[1].memberof, 'mod');

t.equal(evaluate(function () {
/** @module mod */
module.exports.prototype = {
/** @returns {undefined} bar */
bar: function () {}
};
})[1].memberof, 'mod');

// https://github.com/documentationjs/documentation/issues/178
//
// t.equal(evaluate(function () {
// /** @module mod */
// /** foo */
// module.exports = 1;
// })[1].memberof, 'mod');
//
// t.equal(evaluate(function () {
// /** @module mod */
// /** @returns {undefined} foo */
// module.exports = function () {};
// })[1].memberof, 'mod');

t.equal(evaluate(function () {
/** @module mod */
module.exports = {
/** foo */
foo: 1
};
})[1].memberof, 'mod');

t.equal(result.length, 2);
t.equal(result[1].memberof, 'mod');
t.end();
});

Expand All @@ -227,7 +325,7 @@ test('inferMembership - not module exports', function (t) {
t.end();
});

test('inferMembership - anonymous module', function (t) {
test('inferMembership - anonymous @module', function (t) {
var result = evaluate(function () {
/**
* @module
Expand All @@ -241,7 +339,7 @@ test('inferMembership - anonymous module', function (t) {
t.end();
});

test('inferMembership - no module', function (t) {
test('inferMembership - no @module', function (t) {
var result = evaluate(function () {
/** Test */
exports.foo = 1;
Expand Down

0 comments on commit 5449757

Please sign in to comment.