1 |
|
2 | const _ = require('underscore');
|
3 | const path = require('path');
|
4 | const assert = require('assert');
|
5 | const parser = require('../lib/docparser');
|
6 | const builder = require('../lib/builder');
|
7 | const Firedoc = require('../lib/firedoc').Firedoc;
|
8 |
|
9 | describe('firedoc.parser', function () {
|
10 |
|
11 | describe('basic', function () {
|
12 | var src = path.join(__dirname, './targets/basic');
|
13 | var doc = new Firedoc({'paths': [src], cwd: src, withSrc: true});
|
14 | var ast, ctx;
|
15 | before(function (next) {
|
16 | doc.walk(next);
|
17 | });
|
18 | before(function () {
|
19 | ast = parser.parse('js', doc.filemap, doc.dirmap);
|
20 | });
|
21 | it('should check project', function () {
|
22 | assert.deepEqual(ast.project, {
|
23 | 'name': 'test',
|
24 | 'description': 'test',
|
25 | 'logo': 'https://github.com/fireball-x/firedoc'
|
26 | });
|
27 | assert.equal('js', ast.syntaxType);
|
28 | });
|
29 | it('should check files', function () {
|
30 | _.each(ast.files, function (file, name) {
|
31 | assert.equal('test/targets/basic/index.js', name);
|
32 | assert.equal('test/targets/basic/index.js', file.name);
|
33 | assert.ok(file.code);
|
34 | });
|
35 | });
|
36 | it('should check modules', function () {
|
37 | _.each(ast.modules, function (mod, name) {
|
38 | assert.equal('exampleModule', name);
|
39 | assert.equal('exampleModule', mod.name);
|
40 | assert.equal('module', mod.tag);
|
41 | assert.equal('test/targets/basic/index.js', mod.file);
|
42 | assert.equal(2, mod.line);
|
43 | assert.equal('modules', mod.type);
|
44 | assert.equal('yorkiefixer@gmail.com', mod.author);
|
45 | });
|
46 | });
|
47 | it('should check classes', function () {
|
48 | _.each(ast.classes, function (clazz, name) {
|
49 | assert.equal('ExampleClass', name);
|
50 | assert.equal('ExampleClass', clazz.name);
|
51 | assert.equal('test/targets/basic/index.js', clazz.file);
|
52 | assert.equal(2, clazz.line);
|
53 | assert.equal('classes', clazz.type);
|
54 | });
|
55 | });
|
56 | it('should check members', function () {
|
57 | _.each(ast.members, function (member) {
|
58 | assert.equal('test/targets/basic/index.js', member.file);
|
59 | assert.equal(12, member.line);
|
60 | assert.equal('method', member.itemtype);
|
61 | assert.equal('method1', member.name);
|
62 | assert.equal('ExampleClass', member.clazz);
|
63 | assert.equal('exampleModule', member.module);
|
64 | assert.equal(false, member.isGlobal);
|
65 | assert.deepEqual([
|
66 | {
|
67 | name: 'num',
|
68 | description: 'The Number',
|
69 | type: 'Number'
|
70 | }
|
71 | ], member.params);
|
72 | });
|
73 | });
|
74 | it('should check inherited members', function () {
|
75 | assert.deepEqual([], ast.inheritedMembers);
|
76 | });
|
77 | it('should compile the ast', function (next) {
|
78 | ctx = builder.compile(ast, doc.options, next);
|
79 | ctx.on('index', function (locals, html) {
|
80 | assert.equal(locals.project, require('./targets/basic/package.json'));
|
81 | assert.equal(locals.layout, 'main');
|
82 | assert.ok(locals.i18n);
|
83 | var class1 = locals.classes[0];
|
84 | assert.ok(class1.globals);
|
85 | assert.ok(class1.i18n);
|
86 | assert.equal(class1.description, '<p>Module Description</p>\n');
|
87 | assert.equal(class1.foundAt, '../files/test_targets_basic_index.js.html#l2');
|
88 | assert.equal(class1.namespace, 'exampleModule.ExampleClass');
|
89 | assert.deepEqual(class1.project, {
|
90 | name: 'test',
|
91 | description: 'test',
|
92 | logo: 'https://github.com/fireball-x/firedoc',
|
93 | root: path.join(__dirname, '../out'),
|
94 | base: path.join(__dirname, '../out'),
|
95 | assets: path.join(__dirname, '../out/assets'),
|
96 | });
|
97 | var mod1 = locals.modules[0];
|
98 | assert.ok(mod1.globals);
|
99 | assert.ok(mod1.i18n);
|
100 | assert.equal(mod1.description, '<p>Module Description</p>\n');
|
101 | assert.equal(mod1.foundAt, '../files/test_targets_basic_index.js.html#l2');
|
102 | assert.equal(mod1.namespace, 'exampleModule');
|
103 | assert.deepEqual(mod1.classes, [class1]);
|
104 | assert.deepEqual(mod1.properties, []);
|
105 | assert.deepEqual(mod1.attributes, []);
|
106 | assert.deepEqual(mod1.methods, []);
|
107 | assert.deepEqual(mod1.events, []);
|
108 | });
|
109 | ctx.on('apimeta', function (apimeta) {
|
110 | assert.ok(apimeta.enums);
|
111 | assert.ok(apimeta.classes);
|
112 | assert.ok(apimeta.modules);
|
113 | });
|
114 | ctx.on('file', function (locals) {
|
115 | assert.ok(locals.name);
|
116 | assert.ok(locals.code);
|
117 | assert.ok(locals.path);
|
118 | assert.ok(locals.i18n);
|
119 | assert.ok(locals.globals);
|
120 | });
|
121 | ctx.on('module', function (locals) {
|
122 | assert.ok(locals.name);
|
123 | assert.ok(locals.assets);
|
124 | assert.ok(locals.classes);
|
125 | assert.ok(locals.submodules);
|
126 | assert.ok(locals.fors);
|
127 | assert.ok(locals.file);
|
128 | assert.ok(locals.line);
|
129 | assert.ok(locals.description);
|
130 | assert.ok(locals.foundAt);
|
131 | assert.ok(locals.members);
|
132 | assert.ok(locals.project);
|
133 | assert.ok(locals.i18n);
|
134 | assert.ok(locals.namespace);
|
135 | assert.ok(locals.properties);
|
136 | assert.ok(locals.attributes);
|
137 | assert.ok(locals.methods);
|
138 | assert.ok(locals.events);
|
139 | assert.ok(locals.globals);
|
140 | assert.equal(locals.type, 'modules');
|
141 | });
|
142 | ctx.on('class', function (locals) {
|
143 | assert.ok(locals.assets);
|
144 | assert.ok(locals.cwd);
|
145 | assert.ok(locals.name);
|
146 | assert.ok(locals.shortname);
|
147 | assert.ok(locals.members);
|
148 | assert.ok(locals.members.inherited);
|
149 | assert.ok(locals.members.methods);
|
150 | assert.ok(locals.plugins);
|
151 | assert.ok(locals.pluginFor);
|
152 | assert.ok(locals.module === 'exampleModule');
|
153 | assert.ok(locals.submodule === null);
|
154 | assert.ok(locals.namespace);
|
155 | assert.ok(locals.isEnum === false);
|
156 | assert.ok(locals.type === 'classes');
|
157 | assert.ok(locals.file);
|
158 | assert.ok(locals.line);
|
159 | assert.ok(locals.description);
|
160 | assert.ok(locals.foundAt);
|
161 | assert.ok(locals.project);
|
162 | assert.ok(locals.globals);
|
163 | assert.ok(locals.i18n);
|
164 | assert.ok(locals.inheritance);
|
165 | });
|
166 | });
|
167 | });
|
168 |
|
169 | describe('modules', function () {
|
170 | var src = path.join(__dirname, './targets/module');
|
171 | var doc = new Firedoc({'paths': [src]});
|
172 | var ast;
|
173 | before(function (next) {
|
174 | doc.walk(next);
|
175 | });
|
176 | before(function () {
|
177 | ast = parser.parse('js', doc.filemap, doc.dirmap);
|
178 | });
|
179 | var submodule1, submodule2;
|
180 | it('should check files and codes', function () {
|
181 | assert.equal(6, _.keys(ast.files).length);
|
182 | assert.equal(6, _.keys(ast.codes).length);
|
183 | });
|
184 | it('should check mod1', function () {
|
185 | var mod1 = ast.modules.mod1;
|
186 | assert.equal('class1', mod1.classes.class1.name);
|
187 | assert.equal('test/targets/module/mod1.js', mod1.file);
|
188 | assert.equal(2, mod1.line);
|
189 | assert.equal('mod1', mod1.name);
|
190 | assert.equal('mod1', mod1.mainName);
|
191 | assert.equal('main', mod1.tag);
|
192 | assert.equal('main', mod1.itemtype);
|
193 | assert.equal('Module Description 1', mod1.description);
|
194 | assert.ok(mod1.submodules.submod1);
|
195 | assert.ok(mod1.submodules.submod2);
|
196 | submodule1 = mod1.submodules.submod1;
|
197 | submodule2 = mod1.submodules.submod2;
|
198 | });
|
199 | it('should check mod2', function () {
|
200 | var mod2 = ast.modules.mod2;
|
201 | assert.equal('mod2', mod2.name);
|
202 | assert.equal('mod2', mod2.mainName);
|
203 | assert.equal('main', mod2.tag);
|
204 | assert.equal('main', mod2.itemtype);
|
205 | assert.equal('Module Description 2', mod2.description);
|
206 | });
|
207 | it('should check submodules', function () {
|
208 | assert.deepEqual(submodule1, ast.modules.submod1);
|
209 | assert.deepEqual(submodule2, ast.modules.submod2);
|
210 | assert.equal('test/targets/module/submod1.js', ast.modules.submod1.file);
|
211 | });
|
212 | it('should check direct methods', function () {
|
213 | assert.equal('Direct method', ast.members[0].description);
|
214 | assert.equal('method', ast.members[0].itemtype);
|
215 | assert.equal('directMethod', ast.members[0].name);
|
216 | assert.equal('', ast.members[0].clazz);
|
217 | assert.equal('mod1', ast.members[0].module);
|
218 | assert.equal(true, ast.members[0].isGlobal);
|
219 | assert.deepEqual(
|
220 | {
|
221 | description: '',
|
222 | type: 'String'
|
223 | },
|
224 | ast.members[0].return
|
225 | );
|
226 | });
|
227 | it('should compile the ast', function (next) {
|
228 | builder.compile(ast, doc.options, next);
|
229 | });
|
230 | });
|
231 |
|
232 | describe('classes', function () {
|
233 | var src = path.join(__dirname, './targets/class');
|
234 | var doc = new Firedoc({'paths': [src]});
|
235 | var ast;
|
236 | before(function (next) {
|
237 | doc.walk(next);
|
238 | });
|
239 | before(function () {
|
240 | ast = parser.parse('js', doc.filemap, doc.dirmap);
|
241 | });
|
242 | it('should check undefined module', function () {
|
243 | assert.ok(ast.modules.undefinedmodule);
|
244 | });
|
245 | it('should check class1', function () {
|
246 | var class1 = ast.classes.ClazzExample;
|
247 | assert.equal('ClazzExample', class1.name);
|
248 | assert.equal('undefinedmodule', class1.module);
|
249 | assert.equal(false, class1.isEnum);
|
250 | assert.equal('classes', class1.type);
|
251 | assert.equal('Class description', class1.description);
|
252 | });
|
253 | it('should check class2', function () {
|
254 | var class2 = ast.classes.SecondClazz;
|
255 | assert.equal('SecondClazz', class2.name);
|
256 | assert.equal('undefinedmodule', class2.module);
|
257 | assert.equal(false, class2.isEnum);
|
258 | assert.equal('classes', class2.type);
|
259 | assert.equal('The second class', class2.description);
|
260 | });
|
261 | it('should check enum', function () {
|
262 | var enumEx = ast.classes.EnumEx;
|
263 | assert.equal('EnumEx', enumEx.name);
|
264 | assert.equal(true, enumEx.isEnum);
|
265 | assert.equal('enums', enumEx.type);
|
266 | assert.equal('The enum description [example](undefinedmodule.ClazzExample.method1)', enumEx.description);
|
267 | });
|
268 | it('should check members', function () {
|
269 | var members = ast.members;
|
270 | assert.equal('property', members[0].itemtype);
|
271 | assert.equal('ClazzExample', members[0].clazz);
|
272 | assert.equal('undefinedmodule', members[0].module);
|
273 | assert.equal('The prop 1', members[0].description);
|
274 | assert.equal('property', members[1].itemtype);
|
275 | assert.equal('ClazzExample', members[1].clazz);
|
276 | assert.equal('undefinedmodule', members[1].module);
|
277 | assert.equal('The name2', members[1].description);
|
278 | assert.equal('method1 description', members[2].description);
|
279 | assert.equal('method1', members[2].name);
|
280 | assert.deepEqual(
|
281 | [
|
282 | {
|
283 | name: 'name',
|
284 | description: '',
|
285 | type: 'String'
|
286 | }
|
287 | ],
|
288 | members[2].params
|
289 | );
|
290 | assert.deepEqual(
|
291 | {
|
292 | description: '',
|
293 | type: 'String|Number'
|
294 | },
|
295 | members[2].return
|
296 | );
|
297 | assert.equal('method2 description 2', members[4].description);
|
298 | assert.equal('method2_with_description', members[4].name);
|
299 | assert.deepEqual(
|
300 | [
|
301 | {
|
302 | name: 'name',
|
303 | description: 'The name description',
|
304 | type: 'String'
|
305 | }
|
306 | ],
|
307 | members[4].params
|
308 | );
|
309 | assert.deepEqual(
|
310 | {
|
311 | description: 'The return value',
|
312 | type: 'String'
|
313 | },
|
314 | members[4].return
|
315 | );
|
316 | });
|
317 | it('should check inheritedMembers', function () {
|
318 | assert.deepEqual([
|
319 | [
|
320 | 'ClazzExample',
|
321 | 'SecondClazz'
|
322 | ],
|
323 | [
|
324 | 'ClazzExample',
|
325 | 'ThirdClazz'
|
326 | ]
|
327 | ], ast.inheritedMembers);
|
328 | });
|
329 | it('should compile the ast', function (next) {
|
330 | var ctx = builder.compile(ast, doc.options, next);
|
331 | ctx.on('class', function (locals) {
|
332 | if (locals.name === 'SecondClazz') {
|
333 | var method1 = _.findWhere(locals.members, {'name': 'method1'});
|
334 | assert.ok(method1.overwrittenFrom);
|
335 | var method2 = _.findWhere(locals.members, {'name': 'method2'});
|
336 | assert.ok(method2.extendedFrom);
|
337 | }
|
338 | });
|
339 | ctx.on('enum', function (locals) {
|
340 | assert.equal(locals.name, 'EnumEx');
|
341 | assert.equal(locals.namespace, 'undefinedmodule.EnumEx');
|
342 | assert.equal(locals.description, '<p>The enum description <a href="classes/ClazzExample.html#method_method1">example</a></p>\n');
|
343 | });
|
344 | });
|
345 | });
|
346 |
|
347 | describe('members', function () {
|
348 | var src = path.join(__dirname, './targets/members');
|
349 | var doc = new Firedoc({'paths': [src]});
|
350 | var ast;
|
351 | before(function (next) {
|
352 | doc.walk(next);
|
353 | });
|
354 | before(function () {
|
355 | ast = parser.parse('js', doc.filemap, doc.dirmap);
|
356 | });
|
357 | it('should check members', function () {
|
358 | var example1 = ast.members[0];
|
359 | assert.equal(15, example1.line);
|
360 | assert.equal('example_optional', example1.name);
|
361 | assert.equal(true, example1.isConstructor);
|
362 | assert.deepEqual([
|
363 | '```js\nexample\n\n```'
|
364 | ], example1.example);
|
365 | assert.deepEqual([
|
366 | {
|
367 | name: 'x',
|
368 | description: 'The default value is 10(test)',
|
369 | type: 'Number',
|
370 | optional: true,
|
371 | optdefault: '10'
|
372 | },
|
373 | {
|
374 | name: 'y',
|
375 | description: '',
|
376 | type: 'Object',
|
377 | optional: true,
|
378 | optdefault: '{}'
|
379 | },
|
380 | {
|
381 | name: 'z',
|
382 | description: '',
|
383 | type: 'Array',
|
384 | optional: true,
|
385 | optdefault: '[]'
|
386 | },
|
387 | {
|
388 | name: 'callback',
|
389 | description: 'common callback',
|
390 | type: 'commoncall',
|
391 | props: [
|
392 | {
|
393 | 'description': 'The error as first argument',
|
394 | 'type': 'Error',
|
395 | 'name': 'err'
|
396 | },
|
397 | {
|
398 | 'description': 'The returned object',
|
399 | 'type': 'Object',
|
400 | 'name': 'obj'
|
401 | }
|
402 | ]
|
403 | }
|
404 | ], example1.params);
|
405 |
|
406 | var example2 = ast.members[1];
|
407 | assert.equal(example2.access, 'public');
|
408 | assert.deepEqual([
|
409 | '```Not found for the example path: test/examples/ex0.js',
|
410 | '```js\n// this is an example js for test\nvar foo = bar;\n```'
|
411 | ], example2.example);
|
412 | assert.deepEqual([
|
413 | {
|
414 | name: 'o',
|
415 | description: '',
|
416 | type: 'Object',
|
417 | props: [
|
418 | {
|
419 | name: 'x',
|
420 | description: '',
|
421 | type: 'Number'
|
422 | },
|
423 | {
|
424 | name: 'y',
|
425 | description: '',
|
426 | type: 'Object',
|
427 | optional: true,
|
428 | optdefault: '{}',
|
429 | props: [
|
430 | {
|
431 | name: 'a',
|
432 | description: '',
|
433 | type: 'Boolean'
|
434 | }
|
435 | ]
|
436 | }
|
437 | ]
|
438 | }
|
439 | ], example2.params);
|
440 |
|
441 | var example3 = ast.members[2];
|
442 | assert.equal(example3.final, '');
|
443 | assert.equal(example3.deprecated, true);
|
444 | assert.equal(example3.deprecationMessage, 'this is just deprecated');
|
445 |
|
446 | var example4 = ast.members[3];
|
447 | assert.equal(example4.name, 'md_link_in_method_params_desc');
|
448 | assert.equal(example4.params[0].type, 'Object');
|
449 | assert.equal(example4.params[0].optional, true);
|
450 | assert.equal(example4.params[0].name, 'webContents');
|
451 | assert.equal(example4.params[0].description, 'A [WebContents](https://github.com/atom/electron/blob/master/docs/api/browser-window.md#class-webcontents) object');
|
452 |
|
453 | var example5 = ast.members[4];
|
454 | assert.ok(example5.example);
|
455 | });
|
456 | it('should compile the ast', function (next) {
|
457 | var ctx = builder.compile(ast, doc.options, next);
|
458 | ctx.on('module', function (locals) {
|
459 | var example4 = locals.members[3];
|
460 | assert.equal(example4.methodDisplay, 'md_link_in_method_params_desc(webContents)');
|
461 | assert.equal(example4.name, 'md_link_in_method_params_desc');
|
462 | assert.equal(example4.params[0].description, '<p>A <a href="https://github.com/atom/electron/blob/master/docs/api/browser-window.md#class-webcontents">WebContents</a> object</p>\n');
|
463 | var example5 = locals.members[4];
|
464 | assert.ok(/('|&|");/.test(example5.example) === false);
|
465 | });
|
466 | });
|
467 | });
|
468 |
|
469 | describe('process', function () {
|
470 | var src = path.join(__dirname, './targets/process');
|
471 | var doc = new Firedoc({'paths': [src]});
|
472 | var ast;
|
473 | before(function (next) {
|
474 | doc.walk(next);
|
475 | });
|
476 | before(function () {
|
477 | ast = parser.parse('js', doc.filemap, doc.dirmap);
|
478 | });
|
479 | it('should check module', function () {
|
480 | var mod1 = ast.modules.mod1;
|
481 | assert.deepEqual(mod1.process, ['core']);
|
482 | });
|
483 | it('should check class', function () {
|
484 | var cls1 = ast.classes.cls1;
|
485 | assert.deepEqual(cls1.process, ['page']);
|
486 | var cls2 = ast.classes.cls2;
|
487 | assert.deepEqual(cls2.process, ['core']);
|
488 | });
|
489 | it('should check members', function () {
|
490 | var dm1 = _.findWhere(ast.members, {'name': 'dm1'});
|
491 | assert.deepEqual(dm1.process, ['core']);
|
492 | var dm2 = _.findWhere(ast.members, {'name': 'dm2'});
|
493 | assert.deepEqual(dm2.process, ['page']);
|
494 | var md1InCls1 = _.findWhere(ast.members, {'name': 'md1', 'clazz': 'cls1'});
|
495 | assert.deepEqual(md1InCls1.process, ['page']);
|
496 | var md2InCls1 = _.findWhere(ast.members, {'name': 'md2', 'clazz': 'cls1'});
|
497 | assert.deepEqual(md2InCls1.process, ['core']);
|
498 | var md1InCls2 = _.findWhere(ast.members, {'name': 'md1', 'clazz': 'cls2'});
|
499 | assert.deepEqual(md1InCls2.process, ['core']);
|
500 | });
|
501 | });
|
502 |
|
503 | });
|