comment-parser 0.2.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,78 +2,71 @@ var fs = require('fs');
2
2
  var expect = require('chai').expect;
3
3
  var parse = require('../index');
4
4
 
5
- describe('Single comment string parsing', function() {
5
+ describe('Comment string parsing', function() {
6
+
7
+ /**
8
+ * Source lines numeration:
9
+ *
10
+ * 0 function() {
11
+ * 1 // source with comments
12
+ * 2 }
13
+ *
14
+ */
6
15
 
7
16
  function parsed(func, opts) {
8
17
  var str = func.toString();
9
18
  return parse(str.slice(
10
19
  str.indexOf('{') + 1,
11
20
  str.lastIndexOf('}')
12
- ).trim(), opts);
21
+ ), opts);
13
22
  }
14
23
 
15
- it('should parse one-liner doc block', function() {
16
- expect(parsed(function(){
17
- /** Description */
18
- var a;
19
- })[0].description)
20
- .to.eq('Description');
21
- });
22
-
23
- it('should gracefully parse one-liner with tag', function() {
24
- var p = parsed(function(){
25
- /** @tag */
26
- var a;
27
- });
28
-
29
- expect(p[0].description)
30
- .to.eq('');
31
-
32
- expect(p[0].line)
33
- .to.eq(0);
34
-
35
- expect(p[0].tags.length)
36
- .to.eq(1);
37
-
38
- expect(p[0].tags[0].tag)
39
- .to.eq('tag');
40
-
41
- expect(p[0].tags[0].line)
42
- .to.eq(0);
43
- });
44
-
45
- it('should parse simple doc block with description', function() {
24
+ it('should parse doc block with description', function() {
46
25
  expect(parsed(function(){
47
26
  /**
48
27
  * Description
49
28
  */
50
- })[0].description)
51
- .to.eq('Description');
29
+ })[0])
30
+ .to.eql({
31
+ description : 'Description',
32
+ source : 'Description',
33
+ line : 1,
34
+ tags : []
35
+ });
52
36
  });
53
37
 
54
- it('should split the description', function() {
38
+ it('should skip surrounding empty lines while preserving line numbers', function() {
55
39
  expect(parsed(function(){
56
40
  /**
41
+ *
42
+ *
57
43
  * Description first line
58
44
  *
59
45
  * Description second line
46
+ *
60
47
  */
61
48
  var a;
62
- })[0].description)
63
- .to.eq('Description first line\n\nDescription second line');
49
+ })[0])
50
+ .eql({
51
+ description : 'Description first line\n\nDescription second line',
52
+ source : 'Description first line\n\nDescription second line',
53
+ line : 1,
54
+ tags : []
55
+ });
64
56
  });
65
57
 
66
- it('should keep description "" if omitted', function() {
58
+ it('should skip empty blocks', function() {
59
+
67
60
  expect(parsed(function(){
68
61
  /**
69
- *
62
+ *
70
63
  */
71
64
  var a;
72
- })[0].description)
73
- .to.eq('');
65
+ }).length)
66
+ .to.eq(0);
74
67
  });
75
68
 
76
- it('should parse multiple comments', function() {
69
+ it('should parse multiple doc blocks', function() {
77
70
  var p = parsed(function(){
78
71
  /**
79
72
  * Description first line
@@ -89,14 +82,37 @@ describe('Single comment string parsing', function() {
89
82
  expect(p.length)
90
83
  .to.eq(2);
91
84
 
92
- expect(p[0].description)
93
- .to.eq('Description first line');
85
+ expect(p[0])
86
+ .to.eql({
87
+ description : 'Description first line',
88
+ source : 'Description first line',
89
+ line : 1,
90
+ tags : []
91
+ });
92
+
93
+ expect(p[1])
94
+ .to.eql({
95
+ description : 'Description second line',
96
+ source : 'Description second line',
97
+ line : 6,
98
+ tags : []
99
+ });
100
+ });
94
101
 
95
- expect(p[1].description)
96
- .to.eq('Description second line');
102
+ it('should parse one line block', function() {
103
+ expect(parsed(function(){
104
+ /** Description */
105
+ var a;
106
+ })[0])
107
+ .to.eql({
108
+ description : 'Description',
109
+ source : 'Description',
110
+ line : 1,
111
+ tags : []
112
+ });
97
113
  });
98
114
 
99
- it('should return `null` for `/* */` comments', function() {
115
+ it('should skip `/* */` comments', function() {
100
116
  expect(parsed(function(){
101
117
  /*
102
118
  *
@@ -106,7 +122,7 @@ describe('Single comment string parsing', function() {
106
122
  .to.eq(0);
107
123
  });
108
124
 
109
- it('should return `null` for `/*** */` comments', function() {
125
+ it('should skip `/*** */` comments', function() {
110
126
  expect(parsed(function(){
111
127
  /*
112
128
  *
@@ -116,21 +132,68 @@ describe('Single comment string parsing', function() {
116
132
  .to.eq(0);
117
133
  });
118
134
 
135
+ it('should preserve empty lines and indentation with `opts.trim = false`', function() {
136
+ expect(parsed(function(){
137
+ /**
138
+ *
139
+ *
140
+ * Description first line
141
+ * second line
142
+ *
143
+ * third line
144
+ */
145
+ var a;
146
+ }, {
147
+ trim: false
148
+ })[0])
149
+ .eql({
150
+ description : '\n\n\n Description first line\n second line\n\n third line\n',
151
+ source : '\n\n\n Description first line\n second line\n\n third line\n',
152
+ line : 1,
153
+ tags : []
154
+ });
155
+ });
156
+
157
+ it('should parse one line block with tag', function() {
158
+ expect(parsed(function(){
159
+ /** @tag */
160
+ var a;
161
+ })[0])
162
+ .to.eql({
163
+ description : '',
164
+ line : 1,
165
+ source : '@tag',
166
+ tags : [{
167
+ tag : 'tag',
168
+ type : '',
169
+ name : '',
170
+ description : '',
171
+ line : 1,
172
+ optional : false,
173
+ source : '@tag'
174
+ }]
175
+ });
176
+ });
177
+
119
178
  it('should parse `@tag`', function() {
120
179
  expect(parsed(function(){
121
180
  /**
181
+ *
122
182
  * @my-tag
123
183
  */
124
184
  var a;
125
185
  })[0])
126
186
  .to.eql({
127
- line : 0,
187
+ line : 1,
188
+ source : '@my-tag',
128
189
  description : '',
129
190
  tags: [{
130
- line : 1,
191
+ line : 3,
131
192
  tag : 'my-tag',
193
+ source : '@my-tag',
132
194
  type : '',
133
195
  name : '',
196
+ optional : false,
134
197
  description : ''
135
198
  }]
136
199
  });
@@ -144,164 +207,218 @@ describe('Single comment string parsing', function() {
144
207
  var a;
145
208
  })[0])
146
209
  .to.eql({
147
- line : 0,
210
+ line : 1,
211
+ source : '@my-tag {my.type}',
148
212
  description : '',
149
213
  tags: [{
150
- line : 1,
214
+ line : 2,
151
215
  tag : 'my-tag',
152
216
  type : 'my.type',
153
217
  name : '',
218
+ source : '@my-tag {my.type}',
219
+ optional : false,
154
220
  description : ''
155
221
  }]
156
222
  });
157
223
  });
158
224
 
159
- it('should parse `@tag {my.type} name`', function() {
225
+ it('should parse tag with name only `@tag name`', function() {
160
226
  expect(parsed(function(){
161
227
  /**
162
- * @my-tag {my.type} name
228
+ * @my-tag name
163
229
  */
164
- var a;
165
230
  })[0])
166
231
  .to.eql({
167
- line : 0,
232
+ line : 1,
168
233
  description : '',
234
+ source : '@my-tag name',
169
235
  tags: [{
236
+ line : 2,
170
237
  tag : 'my-tag',
171
- line : 1,
172
- type : 'my.type',
238
+ type : '',
173
239
  name : 'name',
240
+ source : '@my-tag name',
241
+ optional : false,
174
242
  description : ''
175
243
  }]
176
244
  });
177
245
  });
178
246
 
179
- it('should parse `@tag name`', function() {
247
+ it('should parse tag with type and name `@tag {my.type} name`', function() {
180
248
  expect(parsed(function(){
181
249
  /**
182
- * @my-tag name
250
+ * @my-tag {my.type} name
183
251
  */
184
252
  })[0])
185
253
  .to.eql({
186
- line : 0,
254
+ line : 1,
255
+ source : '@my-tag {my.type} name',
187
256
  description : '',
188
257
  tags: [{
189
- line : 1,
190
258
  tag : 'my-tag',
191
- type : '',
259
+ line : 2,
260
+ type : 'my.type',
192
261
  name : 'name',
193
- description : ''
262
+ source : '@my-tag {my.type} name',
263
+ description : '',
264
+ optional : false
194
265
  }]
195
266
  });
196
267
  });
197
268
 
198
- it('should parse multiline tags', function() {
199
- var p = parsed(function(){
200
- /**
201
- * @example
202
- * // here is example
203
- * call('value');
204
- */
205
- var a;
206
- });
207
-
208
- expect(p[0].line)
209
- .to.eq(0);
210
-
211
- expect(p[0].tags.length)
212
- .to.eq(1);
213
-
214
- expect(p[0].tags[0].tag)
215
- .to.eq('example');
216
-
217
- expect(p[0].tags[0].line)
218
- .to.eq(1);
219
-
220
- expect(p[0].tags[0].name)
221
- .to.eq('');
269
+ it('should parse tag with type, name and description `@tag {my.type} name description`', function() {
270
+ expect(parsed(function(){
271
+ /**
272
+ * @my-tag {my.type} name description
273
+ */
274
+ })[0])
275
+ .to.eql({
276
+ line : 1,
277
+ source : '@my-tag {my.type} name description',
278
+ description : '',
279
+ tags: [{
280
+ tag : 'my-tag',
281
+ line : 2,
282
+ type : 'my.type',
283
+ name : 'name',
284
+ source : '@my-tag {my.type} name description',
285
+ description : 'description',
286
+ optional : false
287
+ }]
288
+ });
289
+ });
222
290
 
223
- expect(p[0].tags[0].description)
224
- .to.eq('// here is example\ncall(\'value\');');
291
+ it('should parse tag with multiline description', function() {
292
+ expect(parsed(function(){
293
+ /**
294
+ * @my-tag {my.type} name description line 1
295
+ * description line 2
296
+ * description line 3
297
+ */
298
+ })[0])
299
+ .to.eql({
300
+ line : 1,
301
+ source : '@my-tag {my.type} name description line 1\ndescription line 2\ndescription line 3',
302
+ description : '',
303
+ tags: [{
304
+ tag : 'my-tag',
305
+ line : 2,
306
+ type : 'my.type',
307
+ name : 'name',
308
+ source : '@my-tag {my.type} name description line 1\ndescription line 2\ndescription line 3',
309
+ description : 'description line 1\ndescription line 2\ndescription line 3',
310
+ optional : false
311
+ }]
312
+ });
225
313
  });
226
314
 
227
- it('should parse `@tag {my.type} [name]`', function() {
315
+ it('should parse tag with type and optional name `@tag {my.type} [name]`', function() {
228
316
  expect(parsed(function(){
229
317
  /**
230
318
  * @my-tag {my.type} [name]
231
319
  */
232
320
  })[0])
233
321
  .to.eql({
234
- line : 0,
322
+ line : 1,
235
323
  description : '',
324
+ source : '@my-tag {my.type} [name]',
236
325
  tags: [{
237
326
  tag : 'my-tag',
238
- line : 1,
327
+ line : 2,
328
+ type : 'my.type',
329
+ name : 'name',
330
+ description : '',
331
+ source : '@my-tag {my.type} [name]',
332
+ optional : true
333
+ }]
334
+ });
335
+ });
336
+
337
+ it('should parse tag with type and optional name with default value `@tag {my.type} [name=value]`', function() {
338
+ expect(parsed(function(){
339
+ /**
340
+ * @my-tag {my.type} [name=value]
341
+ */
342
+ })[0])
343
+ .to.eql({
344
+ line : 1,
345
+ description : '',
346
+ source : '@my-tag {my.type} [name=value]',
347
+ tags: [{
348
+ tag : 'my-tag',
349
+ line : 2,
239
350
  type : 'my.type',
240
351
  name : 'name',
352
+ default : 'value',
353
+ source : '@my-tag {my.type} [name=value]',
241
354
  description : '',
242
355
  optional : true
243
356
  }]
244
357
  });
245
358
  });
246
359
 
247
- // http://usejsdoc.org/tags-param.html
248
- it('should parse `@tag {my.type} [name=John Doe]`', function() {
360
+ it('should tolerate default value with whitespces `@tag {my.type} [name=John Doe]`', function() {
249
361
  expect(parsed(function(){
250
362
  /**
251
363
  * @my-tag {my.type} [name=John Doe]
252
364
  */
253
365
  })[0])
254
366
  .to.eql({
255
- line : 0,
367
+ line : 1,
256
368
  description : '',
369
+ source : '@my-tag {my.type} [name=John Doe]',
257
370
  tags: [{
258
371
  tag : 'my-tag',
259
- line : 1,
372
+ line : 2,
260
373
  type : 'my.type',
261
374
  name : 'name',
262
375
  description : '',
376
+ source : '@my-tag {my.type} [name=John Doe]',
263
377
  optional : true,
264
378
  default : 'John Doe'
265
379
  }]
266
380
  });
267
381
  });
268
382
 
269
- // https://github.com/senchalabs/jsduck/wiki/@param
270
- it('should parse quoted optionals like `@tag [name="yay"] desc`', function() {
383
+ it('should tolerate quoted default value `@tag [name="yay!"]`', function() {
271
384
  expect(parsed(function(){
272
385
  /**
273
- * @tag {t} [name="yay!"] desc
386
+ * @tag {t} [name="yay!"]
274
387
  */
275
388
  })[0])
276
389
  .to.eql({
277
- line: 0,
390
+ line: 1,
391
+ source: '@tag {t} [name="yay!"]',
278
392
  description: '',
279
393
  tags: [{
280
394
  tag : 'tag',
281
- line : 1,
395
+ line : 2,
282
396
  type : 't',
283
397
  name : 'name',
398
+ source : '@tag {t} [name="yay!"]',
284
399
  default : 'yay!',
285
400
  optional : true,
286
- description : 'desc'
401
+ description : ''
287
402
  }]
288
403
  });
289
404
  });
290
405
 
291
- it('shouldn\'t strip different quotes in `@tag [name="yay\'] desc`', function() {
406
+ it('should keep value as is if quotes are mismatched `@tag [name="yay\']`', function() {
292
407
  expect(parsed(function(){
293
408
  /**
294
409
  * @tag {t} [name="yay!'] desc
295
410
  */
296
411
  })[0])
297
412
  .to.eql({
298
- line: 0,
413
+ line: 1,
299
414
  description: '',
415
+ source : '@tag {t} [name="yay!\'] desc',
300
416
  tags: [{
301
417
  tag : 'tag',
302
- line : 1,
418
+ line : 2,
303
419
  type : 't',
304
420
  name : 'name',
421
+ source : '@tag {t} [name="yay!\'] desc',
305
422
  default : '"yay!\'',
306
423
  optional : true,
307
424
  description : 'desc'
@@ -309,21 +426,45 @@ describe('Single comment string parsing', function() {
309
426
  });
310
427
  });
311
428
 
312
- it('should parse optional names like `@tag [...name] desc`', function() {
429
+ it('should parse rest names `@tag ...name desc`', function() {
430
+ expect(parsed(function(){
431
+ /**
432
+ * @tag {t} ...name desc
433
+ */
434
+ })[0])
435
+ .to.eql({
436
+ line : 1,
437
+ description : '',
438
+ source : '@tag {t} ...name desc',
439
+ tags: [{
440
+ tag : 'tag',
441
+ line : 2,
442
+ type : 't',
443
+ name : '...name',
444
+ optional : false,
445
+ source : '@tag {t} ...name desc',
446
+ description : 'desc'
447
+ }]
448
+ });
449
+ });
450
+
451
+ it('should parse optional rest names `@tag [...name] desc`', function() {
313
452
  expect(parsed(function(){
314
453
  /**
315
454
  * @tag {t} [...name] desc
316
455
  */
317
456
  })[0])
318
457
  .to.eql({
319
- line: 0,
320
- description: '',
458
+ line : 1,
459
+ description : '',
460
+ source : '@tag {t} [...name] desc',
321
461
  tags: [{
322
462
  tag : 'tag',
323
- line : 1,
463
+ line : 2,
324
464
  type : 't',
325
465
  name : '...name',
326
466
  optional : true,
467
+ source : '@tag {t} [...name] desc',
327
468
  description : 'desc'
328
469
  }]
329
470
  });
@@ -340,17 +481,22 @@ describe('Single comment string parsing', function() {
340
481
  .to.eql({
341
482
  line : 1,
342
483
  description : 'Description',
484
+ source : 'Description\n@my-tag1\n@my-tag2',
343
485
  tags : [{
344
486
  tag : 'my-tag1',
345
- line : 2,
487
+ line : 3,
346
488
  type : '',
347
489
  name : '',
490
+ optional : false,
491
+ source : '@my-tag1',
348
492
  description : ''
349
493
  }, {
350
494
  tag : 'my-tag2',
351
- line : 3,
495
+ line : 4,
352
496
  type : '',
353
497
  name : '',
498
+ optional : false,
499
+ source : '@my-tag2',
354
500
  description : ''
355
501
  }]
356
502
  });
@@ -368,23 +514,30 @@ describe('Single comment string parsing', function() {
368
514
  .to.eql({
369
515
  line : 1,
370
516
  description : 'Description',
517
+ source : "Description\n@my-tag name\n@my-tag name.sub-name\n@my-tag name.sub-name.sub-sub-name",
371
518
  tags : [{
372
519
  tag : 'my-tag',
373
- line : 2,
520
+ line : 3,
374
521
  type : '',
375
522
  name : 'name',
523
+ source : '@my-tag name',
524
+ optional : false,
376
525
  description : '',
377
526
  tags : [{
378
527
  tag : 'my-tag',
379
- line : 3,
528
+ line : 4,
380
529
  type : '',
381
530
  name : 'sub-name',
531
+ optional : false,
532
+ source : '@my-tag name.sub-name',
382
533
  description : '',
383
534
  tags : [{
384
535
  tag : 'my-tag',
385
- line : 4,
536
+ line : 5,
386
537
  type : '',
387
538
  name : 'sub-sub-name',
539
+ optional : false,
540
+ source : '@my-tag name.sub-name.sub-sub-name',
388
541
  description : ''
389
542
  }]
390
543
  }]
@@ -399,13 +552,16 @@ describe('Single comment string parsing', function() {
399
552
  */
400
553
  })[0])
401
554
  .to.eql({
402
- line: 0,
403
- description: '',
555
+ line : 1,
556
+ source : '@my-tag {{a: number}} name',
557
+ description : '',
404
558
  tags: [{
405
559
  tag : 'my-tag',
406
- line : 1,
560
+ line : 2,
407
561
  type : '{a: number}',
408
562
  name : 'name',
563
+ source : '@my-tag {{a: number}} name',
564
+ optional : false,
409
565
  description : ''
410
566
  }]
411
567
  });
@@ -418,15 +574,18 @@ describe('Single comment string parsing', function() {
418
574
  */
419
575
  })[0])
420
576
  .to.eql({
421
- line: 0,
422
- description: '',
577
+ line : 1,
578
+ description : '',
579
+ source : '@my-tag {{a: number} name',
423
580
  tags: [{
424
581
  tag : 'my-tag',
425
- line : 1,
582
+ line : 2,
426
583
  type : '',
427
584
  name : '',
428
- description : '{{a: number} name',
429
- error : 'Unpaired curly in type doc'
585
+ description : '',
586
+ source : '@my-tag {{a: number} name',
587
+ optional : false,
588
+ errors : ['parse_type: Invalid `{type}`, unpaired curlies']
430
589
  }]
431
590
  });
432
591
  });