parse.spec.js 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082
  1. /* eslint no-unused-vars:off */
  2. var expect = require('chai').expect
  3. var parse = require('./parse')
  4. describe('Comment string parsing', function () {
  5. it('should parse doc block with description', function () {
  6. expect(parse(function () {
  7. /**
  8. * Description
  9. */
  10. })[0])
  11. .to.eql({
  12. description: 'Description',
  13. source: 'Description',
  14. line: 1,
  15. tags: []
  16. })
  17. })
  18. it('should parse doc block with no mid stars', function () {
  19. expect(parse(function () {
  20. /**
  21. Description
  22. */
  23. })[0])
  24. .to.eql({
  25. description: 'Description',
  26. source: 'Description',
  27. line: 1,
  28. tags: []
  29. })
  30. })
  31. it('should skip surrounding empty lines while preserving line numbers', function () {
  32. expect(parse(function () {
  33. /**
  34. *
  35. *
  36. * Description first line
  37. *
  38. * Description second line
  39. *
  40. */
  41. var a
  42. })[0])
  43. .eql({
  44. description: 'Description first line\n\nDescription second line',
  45. source: 'Description first line\n\nDescription second line',
  46. line: 1,
  47. tags: []
  48. })
  49. })
  50. it('should accept a description on the first line', function () {
  51. expect(parse(function () {
  52. /** Description first line
  53. *
  54. * Description second line
  55. */
  56. var a
  57. })[0])
  58. .eql({
  59. description: 'Description first line\n\nDescription second line',
  60. source: 'Description first line\n\nDescription second line',
  61. line: 1,
  62. tags: []
  63. })
  64. })
  65. it('should parse not starred middle lines with `opts.trim = true`', function () {
  66. expect(parse(function () {
  67. /**
  68. Description text
  69. @tag tagname Tag description
  70. */
  71. }, {
  72. trim: true
  73. })[0])
  74. .eql({
  75. description: 'Description text',
  76. source: 'Description text\n@tag tagname Tag description',
  77. line: 1,
  78. tags: [{
  79. tag: 'tag',
  80. name: 'tagname',
  81. optional: false,
  82. description: 'Tag description',
  83. type: '',
  84. line: 3,
  85. source: '@tag tagname Tag description'
  86. }]
  87. })
  88. })
  89. it('should parse not starred middle lines with `opts.trim = false`', function () {
  90. expect(parse(function () {
  91. /**
  92. Description text
  93. @tag tagname Tag description
  94. */
  95. }, {
  96. trim: false
  97. })[0])
  98. .eql({
  99. description: '\nDescription text',
  100. source: '\nDescription text\n@tag tagname Tag description\n',
  101. line: 1,
  102. tags: [{
  103. tag: 'tag',
  104. name: 'tagname',
  105. optional: false,
  106. description: 'Tag description\n',
  107. type: '',
  108. line: 3,
  109. source: '@tag tagname Tag description\n'
  110. }]
  111. })
  112. })
  113. it('should accept comment close on a non-empty', function () {
  114. expect(parse(function () {
  115. /**
  116. * Description first line
  117. *
  118. * Description second line */
  119. var a
  120. })[0])
  121. .eql({
  122. description: 'Description first line\n\nDescription second line',
  123. source: 'Description first line\n\nDescription second line',
  124. line: 1,
  125. tags: []
  126. })
  127. })
  128. it('should skip empty blocks', function () {
  129. expect(parse(function () {
  130. /**
  131. *
  132. */
  133. var a
  134. }).length)
  135. .to.eq(0)
  136. })
  137. it('should parse multiple doc blocks', function () {
  138. var p = parse(function () {
  139. /**
  140. * Description first line
  141. */
  142. var a
  143. /**
  144. * Description second line
  145. */
  146. var b
  147. })
  148. expect(p.length)
  149. .to.eq(2)
  150. expect(p[0])
  151. .to.eql({
  152. description: 'Description first line',
  153. source: 'Description first line',
  154. line: 1,
  155. tags: []
  156. })
  157. expect(p[1])
  158. .to.eql({
  159. description: 'Description second line',
  160. source: 'Description second line',
  161. line: 6,
  162. tags: []
  163. })
  164. })
  165. it('should parse one line block', function () {
  166. expect(parse(function () {
  167. /** Description */
  168. var a
  169. })[0])
  170. .to.eql({
  171. description: 'Description',
  172. source: 'Description',
  173. line: 1,
  174. tags: []
  175. })
  176. })
  177. it('should skip `/* */` comments', function () {
  178. expect(parse(function () {
  179. /*
  180. *
  181. */
  182. var a
  183. }).length)
  184. .to.eq(0)
  185. })
  186. it('should skip `/*** */` comments', function () {
  187. expect(parse(function () {
  188. /***
  189. *
  190. */
  191. var a
  192. }).length)
  193. .to.eq(0)
  194. })
  195. it('should preserve empty lines and indentation with `opts.trim = false`', function () {
  196. expect(parse(function () {
  197. /**
  198. *
  199. *
  200. * Description first line
  201. * second line
  202. *
  203. * third line
  204. */
  205. var a
  206. }, {
  207. trim: false
  208. })[0])
  209. .eql({
  210. description: '\n\n\n Description first line\n second line\n\n third line\n',
  211. source: '\n\n\n Description first line\n second line\n\n third line\n',
  212. line: 1,
  213. tags: []
  214. })
  215. })
  216. it('should parse one line block with tag', function () {
  217. expect(parse(function () {
  218. /** @tag */
  219. var a
  220. })[0])
  221. .to.eql({
  222. description: '',
  223. line: 1,
  224. source: '@tag',
  225. tags: [{
  226. tag: 'tag',
  227. type: '',
  228. name: '',
  229. description: '',
  230. line: 1,
  231. optional: false,
  232. source: '@tag'
  233. }]
  234. })
  235. })
  236. it('should parse `@tag`', function () {
  237. expect(parse(function () {
  238. /**
  239. *
  240. * @my-tag
  241. */
  242. var a
  243. })[0])
  244. .to.eql({
  245. line: 1,
  246. source: '@my-tag',
  247. description: '',
  248. tags: [{
  249. line: 3,
  250. tag: 'my-tag',
  251. source: '@my-tag',
  252. type: '',
  253. name: '',
  254. optional: false,
  255. description: ''
  256. }]
  257. })
  258. })
  259. it('should parse `@tag {my.type}`', function () {
  260. expect(parse(function () {
  261. /**
  262. * @my-tag {my.type}
  263. */
  264. var a
  265. })[0])
  266. .to.eql({
  267. line: 1,
  268. source: '@my-tag {my.type}',
  269. description: '',
  270. tags: [{
  271. line: 2,
  272. tag: 'my-tag',
  273. type: 'my.type',
  274. name: '',
  275. source: '@my-tag {my.type}',
  276. optional: false,
  277. description: ''
  278. }]
  279. })
  280. })
  281. it('should parse tag with name only `@tag name`', function () {
  282. expect(parse(function () {
  283. /**
  284. * @my-tag name
  285. */
  286. })[0])
  287. .to.eql({
  288. line: 1,
  289. description: '',
  290. source: '@my-tag name',
  291. tags: [{
  292. line: 2,
  293. tag: 'my-tag',
  294. type: '',
  295. name: 'name',
  296. source: '@my-tag name',
  297. optional: false,
  298. description: ''
  299. }]
  300. })
  301. })
  302. it('should parse tag with type and name `@tag {my.type} name`', function () {
  303. expect(parse(function () {
  304. /**
  305. * @my-tag {my.type} name
  306. */
  307. })[0])
  308. .to.eql({
  309. line: 1,
  310. source: '@my-tag {my.type} name',
  311. description: '',
  312. tags: [{
  313. tag: 'my-tag',
  314. line: 2,
  315. type: 'my.type',
  316. name: 'name',
  317. source: '@my-tag {my.type} name',
  318. description: '',
  319. optional: false
  320. }]
  321. })
  322. })
  323. it('should parse tag with type, name and description `@tag {my.type} name description`', function () {
  324. expect(parse(function () {
  325. /**
  326. * @my-tag {my.type} name description
  327. */
  328. })[0])
  329. .to.eql({
  330. line: 1,
  331. source: '@my-tag {my.type} name description',
  332. description: '',
  333. tags: [{
  334. tag: 'my-tag',
  335. line: 2,
  336. type: 'my.type',
  337. name: 'name',
  338. source: '@my-tag {my.type} name description',
  339. description: 'description',
  340. optional: false
  341. }]
  342. })
  343. })
  344. /* eslint-disable no-tabs */
  345. it('should parse tag with type, name and description `@tag {my.type} name description separated by tab`', function () {
  346. expect(parse(function () {
  347. /**
  348. * @my-tag {my.type} name description
  349. */
  350. })[0])
  351. .to.eql({
  352. line: 1,
  353. source: '@my-tag\t{my.type}\tname\tdescription',
  354. description: '',
  355. tags: [{
  356. tag: 'my-tag',
  357. line: 2,
  358. type: 'my.type',
  359. name: 'name',
  360. source: '@my-tag\t{my.type}\tname\tdescription',
  361. description: 'description',
  362. optional: false
  363. }]
  364. })
  365. })
  366. /* eslint-enable no-tabs */
  367. it('should parse tag with multiline description', function () {
  368. expect(parse(function () {
  369. /**
  370. * @my-tag {my.type} name description line 1
  371. * description line 2
  372. * description line 3
  373. */
  374. })[0])
  375. .to.eql({
  376. line: 1,
  377. source: '@my-tag {my.type} name description line 1\ndescription line 2\ndescription line 3',
  378. description: '',
  379. tags: [{
  380. tag: 'my-tag',
  381. line: 2,
  382. type: 'my.type',
  383. name: 'name',
  384. source: '@my-tag {my.type} name description line 1\ndescription line 2\ndescription line 3',
  385. description: 'description line 1\ndescription line 2\ndescription line 3',
  386. optional: false
  387. }]
  388. })
  389. })
  390. it('should parse tag with type and optional name `@tag {my.type} [name]`', function () {
  391. expect(parse(function () {
  392. /**
  393. * @my-tag {my.type} [name]
  394. */
  395. })[0])
  396. .to.eql({
  397. line: 1,
  398. description: '',
  399. source: '@my-tag {my.type} [name]',
  400. tags: [{
  401. tag: 'my-tag',
  402. line: 2,
  403. type: 'my.type',
  404. name: 'name',
  405. description: '',
  406. source: '@my-tag {my.type} [name]',
  407. optional: true
  408. }]
  409. })
  410. })
  411. it('should parse tag with type and optional name with default value `@tag {my.type} [name=value]`', function () {
  412. expect(parse(function () {
  413. /**
  414. * @my-tag {my.type} [name=value]
  415. */
  416. })[0])
  417. .to.eql({
  418. line: 1,
  419. description: '',
  420. source: '@my-tag {my.type} [name=value]',
  421. tags: [{
  422. tag: 'my-tag',
  423. line: 2,
  424. type: 'my.type',
  425. name: 'name',
  426. default: 'value',
  427. source: '@my-tag {my.type} [name=value]',
  428. description: '',
  429. optional: true
  430. }]
  431. })
  432. })
  433. it('should tolerate loose tag names', function () {
  434. expect(parse(function () {
  435. /**
  436. Description text
  437. @.tag0 tagname Tag 0 description
  438. @-tag1 tagname Tag 1 description
  439. @+tag2 tagname Tag 2 description
  440. */
  441. })[0])
  442. .eql({
  443. description: 'Description text',
  444. source: 'Description text\n@.tag0 tagname Tag 0 description\n@-tag1 tagname Tag 1 description\n@+tag2 tagname Tag 2 description',
  445. line: 1,
  446. tags: [{
  447. tag: '.tag0',
  448. name: 'tagname',
  449. optional: false,
  450. description: 'Tag 0 description',
  451. type: '',
  452. line: 3,
  453. source: '@.tag0 tagname Tag 0 description'
  454. }, {
  455. tag: '-tag1',
  456. name: 'tagname',
  457. optional: false,
  458. description: 'Tag 1 description',
  459. type: '',
  460. line: 4,
  461. source: '@-tag1 tagname Tag 1 description'
  462. }, {
  463. tag: '+tag2',
  464. name: 'tagname',
  465. optional: false,
  466. description: 'Tag 2 description',
  467. type: '',
  468. line: 5,
  469. source: '@+tag2 tagname Tag 2 description'
  470. }]
  471. })
  472. })
  473. it('should tolerate default value with whitespces `@tag {my.type} [name=John Doe]`', function () {
  474. expect(parse(function () {
  475. /**
  476. * @my-tag {my.type} [name=John Doe]
  477. */
  478. })[0])
  479. .to.eql({
  480. line: 1,
  481. description: '',
  482. source: '@my-tag {my.type} [name=John Doe]',
  483. tags: [{
  484. tag: 'my-tag',
  485. line: 2,
  486. type: 'my.type',
  487. name: 'name',
  488. description: '',
  489. source: '@my-tag {my.type} [name=John Doe]',
  490. optional: true,
  491. default: 'John Doe'
  492. }]
  493. })
  494. })
  495. it('should tolerate quoted default value `@tag [name="yay!"]`', function () {
  496. expect(parse(function () {
  497. /**
  498. * @tag {t} [name="yay!"]
  499. */
  500. })[0])
  501. .to.eql({
  502. line: 1,
  503. source: '@tag {t} [name="yay!"]',
  504. description: '',
  505. tags: [{
  506. tag: 'tag',
  507. line: 2,
  508. type: 't',
  509. name: 'name',
  510. source: '@tag {t} [name="yay!"]',
  511. default: 'yay!',
  512. optional: true,
  513. description: ''
  514. }]
  515. })
  516. })
  517. it('should keep value as is if quotes are mismatched `@tag [name="yay\']`', function () {
  518. expect(parse(function () {
  519. /**
  520. * @tag {t} [name="yay!'] desc
  521. */
  522. })[0])
  523. .to.eql({
  524. line: 1,
  525. description: '',
  526. source: '@tag {t} [name="yay!\'] desc',
  527. tags: [{
  528. tag: 'tag',
  529. line: 2,
  530. type: 't',
  531. name: 'name',
  532. source: '@tag {t} [name="yay!\'] desc',
  533. default: '"yay!\'',
  534. optional: true,
  535. description: 'desc'
  536. }]
  537. })
  538. })
  539. it('should parse rest names `@tag ...name desc`', function () {
  540. expect(parse(function () {
  541. /**
  542. * @tag {t} ...name desc
  543. */
  544. })[0])
  545. .to.eql({
  546. line: 1,
  547. description: '',
  548. source: '@tag {t} ...name desc',
  549. tags: [{
  550. tag: 'tag',
  551. line: 2,
  552. type: 't',
  553. name: '...name',
  554. optional: false,
  555. source: '@tag {t} ...name desc',
  556. description: 'desc'
  557. }]
  558. })
  559. })
  560. it('should parse optional rest names `@tag [...name] desc`', function () {
  561. expect(parse(function () {
  562. /**
  563. * @tag {t} [...name] desc
  564. */
  565. })[0])
  566. .to.eql({
  567. line: 1,
  568. description: '',
  569. source: '@tag {t} [...name] desc',
  570. tags: [{
  571. tag: 'tag',
  572. line: 2,
  573. type: 't',
  574. name: '...name',
  575. optional: true,
  576. source: '@tag {t} [...name] desc',
  577. description: 'desc'
  578. }]
  579. })
  580. })
  581. it('should parse multiple tags', function () {
  582. expect(parse(function () {
  583. /**
  584. * Description
  585. * @my-tag1
  586. * @my-tag2
  587. */
  588. })[0])
  589. .to.eql({
  590. line: 1,
  591. description: 'Description',
  592. source: 'Description\n@my-tag1\n@my-tag2',
  593. tags: [{
  594. tag: 'my-tag1',
  595. line: 3,
  596. type: '',
  597. name: '',
  598. optional: false,
  599. source: '@my-tag1',
  600. description: ''
  601. }, {
  602. tag: 'my-tag2',
  603. line: 4,
  604. type: '',
  605. name: '',
  606. optional: false,
  607. source: '@my-tag2',
  608. description: ''
  609. }]
  610. })
  611. })
  612. it('should parse nested tags', function () {
  613. expect(parse(function () {
  614. /**
  615. * Description
  616. * @my-tag name
  617. * @my-tag name.sub-name
  618. * @my-tag name.sub-name.sub-sub-name
  619. */
  620. }, { dotted_names: true })[0])
  621. .to.eql({
  622. line: 1,
  623. description: 'Description',
  624. source: 'Description\n@my-tag name\n@my-tag name.sub-name\n@my-tag name.sub-name.sub-sub-name',
  625. tags: [{
  626. tag: 'my-tag',
  627. line: 3,
  628. type: '',
  629. name: 'name',
  630. source: '@my-tag name',
  631. optional: false,
  632. description: '',
  633. tags: [{
  634. tag: 'my-tag',
  635. line: 4,
  636. type: '',
  637. name: 'sub-name',
  638. optional: false,
  639. source: '@my-tag name.sub-name',
  640. description: '',
  641. tags: [{
  642. tag: 'my-tag',
  643. line: 5,
  644. type: '',
  645. name: 'sub-sub-name',
  646. optional: false,
  647. source: '@my-tag name.sub-name.sub-sub-name',
  648. description: ''
  649. }]
  650. }]
  651. }]
  652. })
  653. })
  654. it('should parse complex types `@tag {{a: type}} name`', function () {
  655. expect(parse(function () {
  656. /**
  657. * @my-tag {{a: number}} name
  658. */
  659. })[0])
  660. .to.eql({
  661. line: 1,
  662. source: '@my-tag {{a: number}} name',
  663. description: '',
  664. tags: [{
  665. tag: 'my-tag',
  666. line: 2,
  667. type: '{a: number}',
  668. name: 'name',
  669. source: '@my-tag {{a: number}} name',
  670. optional: false,
  671. description: ''
  672. }]
  673. })
  674. })
  675. it('should gracefully fail on syntax errors `@tag {{a: type} name`', function () {
  676. expect(parse(function () {
  677. /**
  678. * @my-tag {{a: number} name
  679. */
  680. })[0])
  681. .to.eql({
  682. line: 1,
  683. description: '',
  684. source: '@my-tag {{a: number} name',
  685. tags: [{
  686. tag: 'my-tag',
  687. line: 2,
  688. type: '',
  689. name: '',
  690. description: '',
  691. source: '@my-tag {{a: number} name',
  692. optional: false,
  693. errors: ['parse_type: Invalid `{type}`, unpaired curlies']
  694. }]
  695. })
  696. })
  697. it('should parse $ in description`', function () {
  698. expect(parse(function () {
  699. /**
  700. * @my-tag {String} name description with $ char
  701. */
  702. })[0])
  703. .to.eql({
  704. line: 1,
  705. source: '@my-tag {String} name description with $ char',
  706. description: '',
  707. tags: [{
  708. tag: 'my-tag',
  709. line: 2,
  710. type: 'String',
  711. name: 'name',
  712. source: '@my-tag {String} name description with $ char',
  713. optional: false,
  714. description: 'description with $ char'
  715. }]
  716. })
  717. })
  718. it('should parse doc block with bound forced to the left', function () {
  719. expect(parse(function () {
  720. /**
  721. * Description text
  722. * @tag tagname Tag description
  723. */
  724. })[0])
  725. .to.eql({
  726. description: 'Description text',
  727. source: 'Description text\n@tag tagname Tag description',
  728. line: 1,
  729. tags: [{
  730. tag: 'tag',
  731. name: 'tagname',
  732. optional: false,
  733. description: 'Tag description',
  734. type: '',
  735. line: 3,
  736. source: '@tag tagname Tag description'
  737. }]
  738. })
  739. })
  740. it('should parse doc block with bound forced to the right', function () {
  741. expect(parse(function () {
  742. /**
  743. * Description text
  744. * @tag tagname Tag description
  745. */
  746. })[0])
  747. .to.eql({
  748. description: 'Description text',
  749. source: 'Description text\n@tag tagname Tag description',
  750. line: 1,
  751. tags: [{
  752. tag: 'tag',
  753. name: 'tagname',
  754. optional: false,
  755. description: 'Tag description',
  756. type: '',
  757. line: 3,
  758. source: '@tag tagname Tag description'
  759. }]
  760. })
  761. })
  762. it('should parse doc block with soft bound', function () {
  763. expect(parse(function () {
  764. /**
  765. Description text
  766. another line
  767. @tag tagname Tag description
  768. */
  769. })[0])
  770. .to.eql({
  771. description: 'Description text\nanother line',
  772. source: 'Description text\nanother line\n@tag tagname Tag description',
  773. line: 1,
  774. tags: [{
  775. tag: 'tag',
  776. name: 'tagname',
  777. optional: false,
  778. description: 'Tag description',
  779. type: '',
  780. line: 4,
  781. source: '@tag tagname Tag description'
  782. }]
  783. })
  784. })
  785. it('should parse doc block with soft bound respecting `opts.trim = false`', function () {
  786. expect(parse(function () {
  787. /**
  788. Description text
  789. another line
  790. @tag tagname Tag description
  791. */
  792. }, {
  793. trim: false
  794. })[0])
  795. .to.eql({
  796. description: '\nDescription text\n another line',
  797. source: '\nDescription text\n another line\n@tag tagname Tag description\n',
  798. line: 1,
  799. tags: [{
  800. tag: 'tag',
  801. name: 'tagname',
  802. optional: false,
  803. description: 'Tag description\n',
  804. type: '',
  805. line: 4,
  806. source: '@tag tagname Tag description\n'
  807. }]
  808. })
  809. })
  810. it('should parse multiline without star as same line respecting `opts.join = true`', function () {
  811. expect(parse(function () {
  812. /**
  813. * @tag name
  814. * description
  815. same line
  816. */
  817. }, {
  818. join: true
  819. })[0])
  820. .to.eql({
  821. line: 1,
  822. description: '',
  823. source: '@tag name\ndescription\nsame line',
  824. tags: [{
  825. tag: 'tag',
  826. line: 2,
  827. type: '',
  828. name: 'name',
  829. description: 'description same line',
  830. source: '@tag name\ndescription same line',
  831. optional: false
  832. }]
  833. })
  834. })
  835. it('should parse multiline without star as same line respecting `opts.join = "\\t"`', function () {
  836. expect(parse(function () {
  837. /**
  838. * @tag name
  839. * description
  840. same line
  841. */
  842. }, {
  843. join: '\t'
  844. })[0])
  845. .to.eql({
  846. line: 1,
  847. description: '',
  848. source: '@tag name\ndescription\nsame line',
  849. tags: [{
  850. tag: 'tag',
  851. line: 2,
  852. type: '',
  853. name: 'name',
  854. description: 'description\tsame line',
  855. source: '@tag name\ndescription\tsame line',
  856. optional: false
  857. }]
  858. })
  859. })
  860. it('should parse multiline without star as same line with intent respecting `opts.join = 1` and `opts.trim = false`', function () {
  861. expect(parse(function () {
  862. /**
  863. * @tag name
  864. * description
  865. intent same line
  866. */
  867. }, {
  868. join: 1,
  869. trim: false
  870. })[0])
  871. .to.eql({
  872. line: 1,
  873. description: '',
  874. source: '\n@tag name\ndescription\n intent same line\n',
  875. tags: [{
  876. tag: 'tag',
  877. line: 2,
  878. type: '',
  879. name: 'name',
  880. description: 'description intent same line\n',
  881. source: '@tag name\ndescription intent same line\n',
  882. optional: false
  883. }]
  884. })
  885. })
  886. it('should parse same line closing section (issue #22)', function () {
  887. expect(parse(function () {
  888. /**
  889. * Start here
  890. * Here is more stuff */
  891. var a
  892. })[0])
  893. .to.eql({
  894. description: 'Start here\nHere is more stuff',
  895. line: 1,
  896. source: 'Start here\nHere is more stuff',
  897. tags: []
  898. })
  899. })
  900. it('should tolerate inconsistent formatting (issue #29)', function () {
  901. expect(parse(function () {
  902. /**
  903. * @param {Object} options 配置
  904. * @return {Any} obj 组件返回的对象
  905. * @example
  906. * var widget = XX.showWidget('searchlist', {
  907. * onComplete: function() {
  908. * todoSomething();
  909. * }
  910. * });
  911. */
  912. }, {
  913. join: 1,
  914. trim: false
  915. })[0]).to.eql({
  916. description: '',
  917. line: 1,
  918. source: "\n@param {Object} options 配置\n@return {Any} obj 组件返回的对象\n@example\nvar widget = XX.showWidget('searchlist', {\n onComplete: function() {\n todoSomething();\n }\n});\n",
  919. tags: [{
  920. description: '配置',
  921. line: 2,
  922. name: 'options',
  923. optional: false,
  924. source: '@param {Object} options 配置',
  925. tag: 'param',
  926. type: 'Object'
  927. }, {
  928. description: '组件返回的对象',
  929. line: 3,
  930. name: 'obj',
  931. optional: false,
  932. source: '@return {Any} obj 组件返回的对象',
  933. tag: 'return',
  934. type: 'Any'
  935. }, {
  936. description: "widget = XX.showWidget('searchlist', {\n onComplete: function() {\n todoSomething();\n }\n});\n",
  937. line: 4,
  938. name: '\nvar',
  939. optional: false,
  940. source: "@example\nvar widget = XX.showWidget('searchlist', {\n onComplete: function() {\n todoSomething();\n }\n});\n",
  941. tag: 'example',
  942. type: ''
  943. }]
  944. })
  945. })
  946. it('should keep optional names spaces (issue #41)`', function () {
  947. expect(parse(function () {
  948. /**
  949. * @section [Brand Colors] Here you can find all the brand colors
  950. */
  951. })[0])
  952. .to.eql({
  953. line: 1,
  954. source: '@section [Brand Colors] Here you can find all the brand colors',
  955. description: '',
  956. tags: [{
  957. tag: 'section',
  958. line: 2,
  959. type: '',
  960. name: 'Brand Colors',
  961. source: '@section [Brand Colors] Here you can find all the brand colors',
  962. optional: true,
  963. description: 'Here you can find all the brand colors'
  964. }]
  965. })
  966. })
  967. it('should keep quotes in description (issue #41)`', function () {
  968. expect(parse(function () {
  969. /**
  970. * @section "Brand Colors" Here you can find all the brand colors
  971. */
  972. })[0])
  973. .to.eql({
  974. line: 1,
  975. source: '@section "Brand Colors" Here you can find all the brand colors',
  976. description: '',
  977. tags: [{
  978. tag: 'section',
  979. line: 2,
  980. type: '',
  981. name: 'Brand Colors',
  982. source: '@section "Brand Colors" Here you can find all the brand colors',
  983. optional: false,
  984. description: 'Here you can find all the brand colors'
  985. }]
  986. })
  987. })
  988. it('should use only quoted name (issue #41)`', function () {
  989. expect(parse(function () {
  990. /**
  991. * @section "Brand Colors" Here you can find "all" the brand colors
  992. */
  993. })[0])
  994. .to.eql({
  995. line: 1,
  996. source: '@section "Brand Colors" Here you can find "all" the brand colors',
  997. description: '',
  998. tags: [{
  999. tag: 'section',
  1000. line: 2,
  1001. type: '',
  1002. name: 'Brand Colors',
  1003. source: '@section "Brand Colors" Here you can find "all" the brand colors',
  1004. optional: false,
  1005. description: 'Here you can find "all" the brand colors'
  1006. }]
  1007. })
  1008. })
  1009. it('should ignore inconsitent quoted groups (issue #41)`', function () {
  1010. expect(parse(function () {
  1011. /**
  1012. * @section "Brand Colors Here you can find all the brand colors
  1013. */
  1014. })[0])
  1015. .to.eql({
  1016. line: 1,
  1017. source: '@section "Brand Colors Here you can find all the brand colors',
  1018. description: '',
  1019. tags: [{
  1020. tag: 'section',
  1021. line: 2,
  1022. type: '',
  1023. name: '"Brand',
  1024. source: '@section "Brand Colors Here you can find all the brand colors',
  1025. optional: false,
  1026. description: 'Colors Here you can find all the brand colors'
  1027. }]
  1028. })
  1029. })
  1030. })