Skip to content

Commit 5449757

Browse files
committed
More test cases and fixes for exports inference
1 parent 9822f75 commit 5449757

10 files changed

+161
-47
lines changed

lib/infer/membership.js

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,23 @@ function extractIdentifiers(path) {
5757
}
5858

5959
/**
60-
* Test whether some identifiers refer to a module export (`exports` or `module.exports`).
60+
* Count leading identifiers that refer to a module export (`exports` or `module.exports`).
61+
* @param {Object} comment parsed comment
6162
* @param {Array<string>} identifiers array of identifier names
62-
* @returns {boolean} true if identifiers refer to a module export
63+
* @returns {number} number of identifiers referring to a module export (0, 1 or 2)
6364
*/
64-
function isModuleExport(identifiers) {
65-
switch (identifiers.length) {
66-
case 1: return identifiers[0] === 'exports';
67-
case 2: return identifiers[0] === 'module' && identifiers[1] === 'exports';
68-
default: return false;
65+
function countModuleIdentifiers(comment, identifiers) {
66+
if (identifiers.length >= 1 &&
67+
(identifiers[0] === 'exports' || (identifiers[0] === 'module' && comment.name === 'exports'))) {
68+
return 1;
69+
}
70+
71+
if (identifiers.length >= 2 &&
72+
(identifiers[0] === 'module' && identifiers[1] === 'exports')) {
73+
return 2;
6974
}
75+
76+
return 0;
7077
}
7178

7279
/**
@@ -89,17 +96,26 @@ module.exports = function () {
8996
* Set `memberof` and `instance`/`static` tags on `comment` based on the
9097
* array of `identifiers`. If the last element of the `identifiers` is
9198
* `"prototype"`, it is assumed to be an instance member; otherwise static.
99+
* If the `identifiers` start with `exports` or `module.exports`, assign
100+
* membership based on the last seen @module tag or name of the current file.
92101
*
93102
* @param {Object} comment comment for which to infer memberships
94103
* @param {Array<string>} identifiers array of identifier names
95104
* @returns {undefined} mutates `comment`
96105
* @private
97106
*/
98107
function inferMembershipFromIdentifiers(comment, identifiers) {
99-
if (isModuleExport(identifiers)) {
100-
comment.memberof = inferModuleName(currentModule || comment);
101-
comment.scope = 'static';
102-
} else if (identifiers[identifiers.length - 1] === 'prototype') {
108+
/*
109+
* Test whether identifiers start with a module export (`exports` or `module.exports`),
110+
* and if so replace those identifiers with the name of the current module.
111+
*/
112+
var moduleIdentifierCount = countModuleIdentifiers(comment, identifiers);
113+
if (moduleIdentifierCount) {
114+
identifiers = identifiers.slice(moduleIdentifierCount);
115+
identifiers.unshift(inferModuleName(currentModule || comment));
116+
}
117+
118+
if (identifiers[identifiers.length - 1] === 'prototype') {
103119
comment.memberof = identifiers.slice(0, -1).join('.');
104120
comment.scope = 'instance';
105121
} else {

test/fixture/_external-deps-included.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
},
3838
"errors": [
3939
{
40-
"message": "memberof reference to module not found",
40+
"message": "memberof reference to index not found",
4141
"commentLineNumber": 0
4242
}
4343
],
@@ -54,7 +54,7 @@
5454
],
5555
"name": "exports",
5656
"kind": "function",
57-
"memberof": "module",
57+
"memberof": "index",
5858
"scope": "static",
5959
"members": {
6060
"instance": [],
@@ -103,7 +103,7 @@
103103
},
104104
"errors": [
105105
{
106-
"message": "memberof reference to module not found",
106+
"message": "memberof reference to main not found",
107107
"commentLineNumber": 0
108108
}
109109
],
@@ -120,7 +120,7 @@
120120
],
121121
"name": "exports",
122122
"kind": "function",
123-
"memberof": "module",
123+
"memberof": "main",
124124
"scope": "static",
125125
"members": {
126126
"instance": [],

test/fixture/_multi-file-input.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
},
3838
"errors": [
3939
{
40-
"message": "memberof reference to module not found",
40+
"message": "memberof reference to simple.input not found",
4141
"commentLineNumber": 0
4242
}
4343
],
@@ -54,7 +54,7 @@
5454
],
5555
"name": "exports",
5656
"kind": "function",
57-
"memberof": "module",
57+
"memberof": "simple.input",
5858
"scope": "static",
5959
"members": {
6060
"instance": [],

test/fixture/inline-link.output.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@
128128
},
129129
"errors": [
130130
{
131-
"message": "memberof reference to module not found",
131+
"message": "memberof reference to inline-link.input not found",
132132
"commentLineNumber": 0
133133
}
134134
],
@@ -157,7 +157,7 @@
157157
],
158158
"name": "exports",
159159
"kind": "function",
160-
"memberof": "module",
160+
"memberof": "inline-link.input",
161161
"scope": "static",
162162
"members": {
163163
"instance": [],

test/fixture/jsx.output.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
},
3838
"errors": [
3939
{
40-
"message": "memberof reference to module not found",
40+
"message": "memberof reference to jsx.input not found",
4141
"commentLineNumber": 0
4242
}
4343
],
@@ -53,7 +53,7 @@
5353
}
5454
],
5555
"name": "exports",
56-
"memberof": "module",
56+
"memberof": "jsx.input",
5757
"scope": "static",
5858
"members": {
5959
"instance": [],

test/fixture/multiexample.output.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
},
8080
"errors": [
8181
{
82-
"message": "memberof reference to module not found",
82+
"message": "memberof reference to multiexample.input not found",
8383
"commentLineNumber": 0
8484
}
8585
],
@@ -136,7 +136,7 @@
136136
],
137137
"name": "exports",
138138
"kind": "function",
139-
"memberof": "module",
139+
"memberof": "multiexample.input",
140140
"scope": "static",
141141
"members": {
142142
"instance": [],

test/fixture/simple-hashbang.output.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
},
3838
"errors": [
3939
{
40-
"message": "memberof reference to module not found",
40+
"message": "memberof reference to simple-hashbang.input not found",
4141
"commentLineNumber": 0
4242
}
4343
],
@@ -54,7 +54,7 @@
5454
],
5555
"name": "exports",
5656
"kind": "function",
57-
"memberof": "module",
57+
"memberof": "simple-hashbang.input",
5858
"scope": "static",
5959
"members": {
6060
"instance": [],

test/fixture/simple.output.github.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
},
4040
"errors": [
4141
{
42-
"message": "memberof reference to module not found",
42+
"message": "memberof reference to simple.input not found",
4343
"commentLineNumber": 0
4444
}
4545
],
@@ -56,7 +56,7 @@
5656
],
5757
"name": "exports",
5858
"kind": "function",
59-
"memberof": "module",
59+
"memberof": "simple.input",
6060
"scope": "static",
6161
"members": {
6262
"instance": [],

test/fixture/simple.output.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
},
3838
"errors": [
3939
{
40-
"message": "memberof reference to module not found",
40+
"message": "memberof reference to simple.input not found",
4141
"commentLineNumber": 0
4242
}
4343
],
@@ -54,7 +54,7 @@
5454
],
5555
"name": "exports",
5656
"kind": "function",
57-
"memberof": "module",
57+
"memberof": "simple.input",
5858
"scope": "static",
5959
"members": {
6060
"instance": [],

test/lib/infer/membership.js

Lines changed: 116 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -186,30 +186,128 @@ test('inferMembership - explicit', function (t) {
186186
});
187187

188188
test('inferMembership - exports', function (t) {
189-
var result = evaluate(function () {
190-
/**
191-
* @module mod
192-
*/
193-
/** Test */
189+
t.equal(evaluate(function () {
190+
/** @module mod */
191+
/** foo */
194192
exports.foo = 1;
195-
});
193+
})[1].memberof, 'mod');
194+
195+
t.equal(evaluate(function () {
196+
/** @module mod */
197+
/** @returns {undefined} foo */
198+
exports.foo = function () {};
199+
})[1].memberof, 'mod');
200+
201+
t.equal(evaluate(function () {
202+
/** @module mod */
203+
/** bar */
204+
exports.foo.bar = 1;
205+
})[1].memberof, 'mod.foo');
206+
207+
t.equal(evaluate(function () {
208+
/** @module mod */
209+
exports.foo = {
210+
/** bar */
211+
bar: 1
212+
};
213+
})[1].memberof, 'mod.foo');
214+
215+
t.equal(evaluate(function () {
216+
/** @module mod */
217+
exports.foo = {
218+
/** @returns {undefined} bar */
219+
bar: function () {}
220+
};
221+
})[1].memberof, 'mod.foo');
222+
223+
t.equal(evaluate(function () {
224+
/** @module mod */
225+
/** @returns {undefined} bar */
226+
exports.foo.prototype.bar = function () {};
227+
})[1].memberof, 'mod.foo');
228+
229+
t.equal(evaluate(function () {
230+
/** @module mod */
231+
exports.foo.prototype = {
232+
/** @returns {undefined} bar */
233+
bar: function () {}
234+
};
235+
})[1].memberof, 'mod.foo');
196236

197-
t.equal(result.length, 2);
198-
t.equal(result[1].memberof, 'mod');
199237
t.end();
200238
});
201239

202240
test('inferMembership - module.exports', function (t) {
203-
var result = evaluate(function () {
204-
/**
205-
* @module mod
206-
*/
207-
/** Test */
241+
t.equal(evaluate(function () {
242+
/** @module mod */
243+
/** foo */
208244
module.exports.foo = 1;
209-
});
245+
})[1].memberof, 'mod');
246+
247+
t.equal(evaluate(function () {
248+
/** @module mod */
249+
/** @returns {undefined} foo */
250+
module.exports.foo = function () {};
251+
})[1].memberof, 'mod');
252+
253+
t.equal(evaluate(function () {
254+
/** @module mod */
255+
/** bar */
256+
module.exports.foo.bar = 1;
257+
})[1].memberof, 'mod.foo');
258+
259+
t.equal(evaluate(function () {
260+
/** @module mod */
261+
module.exports.foo = {
262+
/** bar */
263+
bar: 1
264+
};
265+
})[1].memberof, 'mod.foo');
266+
267+
t.equal(evaluate(function () {
268+
/** @module mod */
269+
module.exports.foo = {
270+
/** @returns {undefined} bar */
271+
bar: function () {}
272+
};
273+
})[1].memberof, 'mod.foo');
274+
275+
t.equal(evaluate(function () {
276+
/** @module mod */
277+
/** @returns {undefined} bar */
278+
module.exports.prototype.bar = function () {};
279+
})[1].memberof, 'mod');
280+
281+
t.equal(evaluate(function () {
282+
/** @module mod */
283+
module.exports.prototype = {
284+
/** @returns {undefined} bar */
285+
bar: function () {}
286+
};
287+
})[1].memberof, 'mod');
288+
289+
// https://github.com/documentationjs/documentation/issues/178
290+
//
291+
// t.equal(evaluate(function () {
292+
// /** @module mod */
293+
// /** foo */
294+
// module.exports = 1;
295+
// })[1].memberof, 'mod');
296+
//
297+
// t.equal(evaluate(function () {
298+
// /** @module mod */
299+
// /** @returns {undefined} foo */
300+
// module.exports = function () {};
301+
// })[1].memberof, 'mod');
302+
303+
t.equal(evaluate(function () {
304+
/** @module mod */
305+
module.exports = {
306+
/** foo */
307+
foo: 1
308+
};
309+
})[1].memberof, 'mod');
210310

211-
t.equal(result.length, 2);
212-
t.equal(result[1].memberof, 'mod');
213311
t.end();
214312
});
215313

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

230-
test('inferMembership - anonymous module', function (t) {
328+
test('inferMembership - anonymous @module', function (t) {
231329
var result = evaluate(function () {
232330
/**
233331
* @module
@@ -241,7 +339,7 @@ test('inferMembership - anonymous module', function (t) {
241339
t.end();
242340
});
243341

244-
test('inferMembership - no module', function (t) {
342+
test('inferMembership - no @module', function (t) {
245343
var result = evaluate(function () {
246344
/** Test */
247345
exports.foo = 1;

0 commit comments

Comments
 (0)