parse.spec.js 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840
  1. const { parse } = require('../../lib/index.cjs');
  2. test('description only', () => {
  3. const parsed = parse(`
  4. /**
  5. * Description
  6. */`);
  7. expect(parsed).toEqual([
  8. {
  9. description: 'Description',
  10. tags: [],
  11. source: [
  12. {
  13. number: 1,
  14. source: ' /**',
  15. tokens: {
  16. start: ' ',
  17. delimiter: '/**',
  18. postDelimiter: '',
  19. tag: '',
  20. postTag: '',
  21. name: '',
  22. postName: '',
  23. type: '',
  24. postType: '',
  25. description: '',
  26. end: '',
  27. lineEnd: '',
  28. },
  29. },
  30. {
  31. number: 2,
  32. source: ' * Description',
  33. tokens: {
  34. start: ' ',
  35. delimiter: '*',
  36. postDelimiter: ' ',
  37. tag: '',
  38. postTag: '',
  39. name: '',
  40. postName: '',
  41. type: '',
  42. postType: '',
  43. description: 'Description',
  44. end: '',
  45. lineEnd: '',
  46. },
  47. },
  48. {
  49. number: 3,
  50. source: ' */',
  51. tokens: {
  52. start: ' ',
  53. delimiter: '',
  54. postDelimiter: '',
  55. tag: '',
  56. postTag: '',
  57. name: '',
  58. postName: '',
  59. type: '',
  60. postType: '',
  61. description: '',
  62. end: '*/',
  63. lineEnd: '',
  64. },
  65. },
  66. ],
  67. problems: [],
  68. },
  69. ]);
  70. });
  71. test('description one-liner', () => {
  72. const parsed = parse(`
  73. /** Description */
  74. var a`);
  75. expect(parsed).toEqual([
  76. {
  77. description: 'Description',
  78. tags: [],
  79. source: [
  80. {
  81. number: 1,
  82. source: ' /** Description */',
  83. tokens: {
  84. start: ' ',
  85. delimiter: '/**',
  86. postDelimiter: ' ',
  87. tag: '',
  88. postTag: '',
  89. name: '',
  90. postName: '',
  91. type: '',
  92. postType: '',
  93. description: 'Description ',
  94. end: '*/',
  95. lineEnd: '',
  96. },
  97. },
  98. ],
  99. problems: [],
  100. },
  101. ]);
  102. });
  103. test('block closed on same line', () => {
  104. const parsed = parse(`
  105. /**
  106. * Description */`);
  107. expect(parsed).toEqual([
  108. {
  109. description: 'Description',
  110. tags: [],
  111. source: [
  112. {
  113. number: 1,
  114. source: ' /**',
  115. tokens: {
  116. start: ' ',
  117. delimiter: '/**',
  118. postDelimiter: '',
  119. tag: '',
  120. postTag: '',
  121. name: '',
  122. postName: '',
  123. type: '',
  124. postType: '',
  125. description: '',
  126. end: '',
  127. lineEnd: '',
  128. },
  129. },
  130. {
  131. number: 2,
  132. source: ' * Description */',
  133. tokens: {
  134. start: ' ',
  135. delimiter: '*',
  136. postDelimiter: ' ',
  137. tag: '',
  138. postTag: '',
  139. name: '',
  140. postName: '',
  141. type: '',
  142. postType: '',
  143. description: 'Description ',
  144. end: '*/',
  145. lineEnd: '',
  146. },
  147. },
  148. ],
  149. problems: [],
  150. },
  151. ]);
  152. });
  153. test('no mid stars', () => {
  154. const parsed = parse(`
  155. /**
  156. Description
  157. */`);
  158. expect(parsed).toEqual([
  159. {
  160. description: 'Description',
  161. tags: [],
  162. source: [
  163. {
  164. number: 1,
  165. source: ' /**',
  166. tokens: {
  167. start: ' ',
  168. delimiter: '/**',
  169. postDelimiter: '',
  170. tag: '',
  171. postTag: '',
  172. name: '',
  173. postName: '',
  174. type: '',
  175. postType: '',
  176. description: '',
  177. end: '',
  178. lineEnd: '',
  179. },
  180. },
  181. {
  182. number: 2,
  183. source: ' Description',
  184. tokens: {
  185. start: ' ',
  186. delimiter: '',
  187. postDelimiter: '',
  188. tag: '',
  189. postTag: '',
  190. name: '',
  191. postName: '',
  192. type: '',
  193. postType: '',
  194. description: 'Description',
  195. end: '',
  196. lineEnd: '',
  197. },
  198. },
  199. {
  200. number: 3,
  201. source: ' */',
  202. tokens: {
  203. start: ' ',
  204. delimiter: '',
  205. postDelimiter: '',
  206. tag: '',
  207. postTag: '',
  208. name: '',
  209. postName: '',
  210. type: '',
  211. postType: '',
  212. description: '',
  213. end: '*/',
  214. lineEnd: '',
  215. },
  216. },
  217. ],
  218. problems: [],
  219. },
  220. ]);
  221. });
  222. test('skip surrounding empty lines while preserving line numbers', () => {
  223. const parsed = parse(`
  224. /**
  225. *
  226. *
  227. * Description first line
  228. *
  229. * Description second line
  230. *
  231. */
  232. var a`);
  233. expect(parsed).toEqual([
  234. {
  235. description: 'Description first line Description second line',
  236. tags: [],
  237. source: [
  238. {
  239. number: 1,
  240. source: ' /**',
  241. tokens: {
  242. start: ' ',
  243. delimiter: '/**',
  244. postDelimiter: '',
  245. tag: '',
  246. postTag: '',
  247. name: '',
  248. postName: '',
  249. type: '',
  250. postType: '',
  251. description: '',
  252. end: '',
  253. lineEnd: '',
  254. },
  255. },
  256. {
  257. number: 2,
  258. source: ' *',
  259. tokens: {
  260. start: ' ',
  261. delimiter: '*',
  262. postDelimiter: '',
  263. tag: '',
  264. postTag: '',
  265. name: '',
  266. postName: '',
  267. type: '',
  268. postType: '',
  269. description: '',
  270. end: '',
  271. lineEnd: '',
  272. },
  273. },
  274. {
  275. number: 3,
  276. source: ' *',
  277. tokens: {
  278. start: ' ',
  279. delimiter: '*',
  280. postDelimiter: '',
  281. tag: '',
  282. postTag: '',
  283. name: '',
  284. postName: '',
  285. type: '',
  286. postType: '',
  287. description: '',
  288. end: '',
  289. lineEnd: '',
  290. },
  291. },
  292. {
  293. number: 4,
  294. source: ' * Description first line',
  295. tokens: {
  296. start: ' ',
  297. delimiter: '*',
  298. postDelimiter: ' ',
  299. tag: '',
  300. postTag: '',
  301. name: '',
  302. postName: '',
  303. type: '',
  304. postType: '',
  305. description: 'Description first line',
  306. end: '',
  307. lineEnd: '',
  308. },
  309. },
  310. {
  311. number: 5,
  312. source: ' *',
  313. tokens: {
  314. start: ' ',
  315. delimiter: '*',
  316. postDelimiter: '',
  317. tag: '',
  318. postTag: '',
  319. name: '',
  320. postName: '',
  321. type: '',
  322. postType: '',
  323. description: '',
  324. end: '',
  325. lineEnd: '',
  326. },
  327. },
  328. {
  329. number: 6,
  330. source: ' * Description second line',
  331. tokens: {
  332. start: ' ',
  333. delimiter: '*',
  334. postDelimiter: ' ',
  335. tag: '',
  336. postTag: '',
  337. name: '',
  338. postName: '',
  339. type: '',
  340. postType: '',
  341. description: 'Description second line',
  342. end: '',
  343. lineEnd: '',
  344. },
  345. },
  346. {
  347. number: 7,
  348. source: ' *',
  349. tokens: {
  350. start: ' ',
  351. delimiter: '*',
  352. postDelimiter: '',
  353. tag: '',
  354. postTag: '',
  355. name: '',
  356. postName: '',
  357. type: '',
  358. postType: '',
  359. description: '',
  360. end: '',
  361. lineEnd: '',
  362. },
  363. },
  364. {
  365. number: 8,
  366. source: ' */',
  367. tokens: {
  368. start: ' ',
  369. delimiter: '',
  370. postDelimiter: '',
  371. tag: '',
  372. postTag: '',
  373. name: '',
  374. postName: '',
  375. type: '',
  376. postType: '',
  377. description: '',
  378. end: '*/',
  379. lineEnd: '',
  380. },
  381. },
  382. ],
  383. problems: [],
  384. },
  385. ]);
  386. });
  387. test('description on the first line', () => {
  388. const parsed = parse(`
  389. /** Description first line
  390. *
  391. * Description second line
  392. */
  393. var a`);
  394. expect(parsed).toEqual([
  395. {
  396. description: 'Description first line Description second line',
  397. tags: [],
  398. source: [
  399. {
  400. number: 1,
  401. source: ' /** Description first line',
  402. tokens: {
  403. start: ' ',
  404. delimiter: '/**',
  405. postDelimiter: ' ',
  406. tag: '',
  407. postTag: '',
  408. name: '',
  409. postName: '',
  410. type: '',
  411. postType: '',
  412. description: 'Description first line',
  413. end: '',
  414. lineEnd: '',
  415. },
  416. },
  417. {
  418. number: 2,
  419. source: ' *',
  420. tokens: {
  421. start: ' ',
  422. delimiter: '*',
  423. postDelimiter: '',
  424. tag: '',
  425. postTag: '',
  426. name: '',
  427. postName: '',
  428. type: '',
  429. postType: '',
  430. description: '',
  431. end: '',
  432. lineEnd: '',
  433. },
  434. },
  435. {
  436. number: 3,
  437. source: ' * Description second line',
  438. tokens: {
  439. start: ' ',
  440. delimiter: '*',
  441. postDelimiter: ' ',
  442. tag: '',
  443. postTag: '',
  444. name: '',
  445. postName: '',
  446. type: '',
  447. postType: '',
  448. description: 'Description second line',
  449. end: '',
  450. lineEnd: '',
  451. },
  452. },
  453. {
  454. number: 4,
  455. source: ' */',
  456. tokens: {
  457. start: ' ',
  458. delimiter: '',
  459. postDelimiter: '',
  460. tag: '',
  461. postTag: '',
  462. name: '',
  463. postName: '',
  464. type: '',
  465. postType: '',
  466. description: '',
  467. end: '*/',
  468. lineEnd: '',
  469. },
  470. },
  471. ],
  472. problems: [],
  473. },
  474. ]);
  475. });
  476. test('multiple blocks', () => {
  477. const parsed = parse(`
  478. /**
  479. * Description first line
  480. */
  481. var a
  482. /**
  483. * Description second line
  484. */
  485. var b`);
  486. expect(parsed).toHaveLength(2);
  487. expect(parsed).toEqual([
  488. {
  489. description: 'Description first line',
  490. tags: [],
  491. source: [
  492. {
  493. number: 1,
  494. source: ' /**',
  495. tokens: {
  496. start: ' ',
  497. delimiter: '/**',
  498. postDelimiter: '',
  499. tag: '',
  500. postTag: '',
  501. name: '',
  502. postName: '',
  503. type: '',
  504. postType: '',
  505. description: '',
  506. end: '',
  507. lineEnd: '',
  508. },
  509. },
  510. {
  511. number: 2,
  512. source: ' * Description first line',
  513. tokens: {
  514. start: ' ',
  515. delimiter: '*',
  516. postDelimiter: ' ',
  517. tag: '',
  518. postTag: '',
  519. name: '',
  520. postName: '',
  521. type: '',
  522. postType: '',
  523. description: 'Description first line',
  524. end: '',
  525. lineEnd: '',
  526. },
  527. },
  528. {
  529. number: 3,
  530. source: ' */',
  531. tokens: {
  532. start: ' ',
  533. delimiter: '',
  534. postDelimiter: '',
  535. tag: '',
  536. postTag: '',
  537. name: '',
  538. postName: '',
  539. type: '',
  540. postType: '',
  541. description: '',
  542. end: '*/',
  543. lineEnd: '',
  544. },
  545. },
  546. ],
  547. problems: [],
  548. },
  549. {
  550. description: 'Description second line',
  551. tags: [],
  552. source: [
  553. {
  554. number: 6,
  555. source: ' /**',
  556. tokens: {
  557. start: ' ',
  558. delimiter: '/**',
  559. postDelimiter: '',
  560. tag: '',
  561. postTag: '',
  562. name: '',
  563. postName: '',
  564. type: '',
  565. postType: '',
  566. description: '',
  567. end: '',
  568. lineEnd: '',
  569. },
  570. },
  571. {
  572. number: 7,
  573. source: ' * Description second line',
  574. tokens: {
  575. start: ' ',
  576. delimiter: '*',
  577. postDelimiter: ' ',
  578. tag: '',
  579. postTag: '',
  580. name: '',
  581. postName: '',
  582. type: '',
  583. postType: '',
  584. description: 'Description second line',
  585. end: '',
  586. lineEnd: '',
  587. },
  588. },
  589. {
  590. number: 8,
  591. source: ' */',
  592. tokens: {
  593. start: ' ',
  594. delimiter: '',
  595. postDelimiter: '',
  596. tag: '',
  597. postTag: '',
  598. name: '',
  599. postName: '',
  600. type: '',
  601. postType: '',
  602. description: '',
  603. end: '*/',
  604. lineEnd: '',
  605. },
  606. },
  607. ],
  608. problems: [],
  609. },
  610. ]);
  611. });
  612. test('skip `/* */` blocks', () => {
  613. const parsed = parse(`
  614. /*
  615. *
  616. */
  617. var a`);
  618. expect(parsed).toHaveLength(0);
  619. });
  620. test('skip `/*** */` blocks', () => {
  621. const parsed = parse(`
  622. /***
  623. *
  624. */
  625. var a`);
  626. expect(parsed).toHaveLength(0);
  627. });
  628. test('tag only one-liner', () => {
  629. const parsed = parse(`/** @my-tag */`);
  630. const source = [
  631. {
  632. number: 0,
  633. source: '/** @my-tag */',
  634. tokens: {
  635. start: '',
  636. delimiter: '/**',
  637. postDelimiter: ' ',
  638. tag: '@my-tag',
  639. postTag: ' ',
  640. name: '',
  641. postName: '',
  642. type: '',
  643. postType: '',
  644. description: '',
  645. end: '*/',
  646. lineEnd: '',
  647. },
  648. },
  649. ];
  650. expect(parsed).toEqual([
  651. {
  652. description: '',
  653. tags: [
  654. {
  655. tag: 'my-tag',
  656. name: '',
  657. type: '',
  658. optional: false,
  659. description: '',
  660. problems: [],
  661. source,
  662. },
  663. ],
  664. source,
  665. problems: [],
  666. },
  667. ]);
  668. });
  669. test('tag only', () => {
  670. const parsed = parse(`
  671. /**
  672. *
  673. * @my-tag
  674. */
  675. var a`);
  676. const source = [
  677. {
  678. number: 1,
  679. source: ' /**',
  680. tokens: {
  681. start: ' ',
  682. delimiter: '/**',
  683. postDelimiter: '',
  684. tag: '',
  685. postTag: '',
  686. name: '',
  687. postName: '',
  688. type: '',
  689. postType: '',
  690. description: '',
  691. end: '',
  692. lineEnd: '',
  693. },
  694. },
  695. {
  696. number: 2,
  697. source: ' *',
  698. tokens: {
  699. start: ' ',
  700. delimiter: '*',
  701. postDelimiter: '',
  702. tag: '',
  703. postTag: '',
  704. name: '',
  705. postName: '',
  706. type: '',
  707. postType: '',
  708. description: '',
  709. end: '',
  710. lineEnd: '',
  711. },
  712. },
  713. {
  714. number: 3,
  715. source: ' * @my-tag',
  716. tokens: {
  717. start: ' ',
  718. delimiter: '*',
  719. postDelimiter: ' ',
  720. tag: '@my-tag',
  721. postTag: '',
  722. name: '',
  723. postName: '',
  724. type: '',
  725. postType: '',
  726. description: '',
  727. end: '',
  728. lineEnd: '',
  729. },
  730. },
  731. {
  732. number: 4,
  733. source: ' */',
  734. tokens: {
  735. start: ' ',
  736. delimiter: '',
  737. postDelimiter: '',
  738. tag: '',
  739. postTag: '',
  740. name: '',
  741. postName: '',
  742. type: '',
  743. postType: '',
  744. description: '',
  745. end: '*/',
  746. lineEnd: '',
  747. },
  748. },
  749. ];
  750. expect(parsed).toEqual([
  751. {
  752. description: '',
  753. tags: [
  754. {
  755. tag: 'my-tag',
  756. name: '',
  757. type: '',
  758. optional: false,
  759. description: '',
  760. problems: [],
  761. source: source.slice(2),
  762. },
  763. ],
  764. source,
  765. problems: [],
  766. },
  767. ]);
  768. });
  769. test('tag and type only', () => {
  770. const parsed = parse(`
  771. /**
  772. *
  773. * @my-tag {my.type}
  774. */
  775. var a`);
  776. const source = [
  777. {
  778. number: 1,
  779. source: ' /**',
  780. tokens: {
  781. start: ' ',
  782. delimiter: '/**',
  783. postDelimiter: '',
  784. tag: '',
  785. postTag: '',
  786. name: '',
  787. postName: '',
  788. type: '',
  789. postType: '',
  790. description: '',
  791. end: '',
  792. lineEnd: '',
  793. },
  794. },
  795. {
  796. number: 2,
  797. source: ' *',
  798. tokens: {
  799. start: ' ',
  800. delimiter: '*',
  801. postDelimiter: '',
  802. tag: '',
  803. postTag: '',
  804. name: '',
  805. postName: '',
  806. type: '',
  807. postType: '',
  808. description: '',
  809. end: '',
  810. lineEnd: '',
  811. },
  812. },
  813. {
  814. number: 3,
  815. source: ' * @my-tag {my.type}',
  816. tokens: {
  817. start: ' ',
  818. delimiter: '*',
  819. postDelimiter: ' ',
  820. tag: '@my-tag',
  821. postTag: ' ',
  822. name: '',
  823. postName: '',
  824. type: '{my.type}',
  825. postType: '',
  826. description: '',
  827. end: '',
  828. lineEnd: '',
  829. },
  830. },
  831. {
  832. number: 4,
  833. source: ' */',
  834. tokens: {
  835. start: ' ',
  836. delimiter: '',
  837. postDelimiter: '',
  838. tag: '',
  839. postTag: '',
  840. name: '',
  841. postName: '',
  842. type: '',
  843. postType: '',
  844. description: '',
  845. end: '*/',
  846. lineEnd: '',
  847. },
  848. },
  849. ];
  850. expect(parsed).toEqual([
  851. {
  852. description: '',
  853. tags: [
  854. {
  855. tag: 'my-tag',
  856. name: '',
  857. type: 'my.type',
  858. optional: false,
  859. description: '',
  860. problems: [],
  861. source: source.slice(2),
  862. },
  863. ],
  864. source,
  865. problems: [],
  866. },
  867. ]);
  868. });
  869. test('tag and name only', () => {
  870. const parsed = parse(`
  871. /**
  872. *
  873. * @my-tag my-name
  874. */
  875. var a`);
  876. const source = [
  877. {
  878. number: 1,
  879. source: ' /**',
  880. tokens: {
  881. start: ' ',
  882. delimiter: '/**',
  883. postDelimiter: '',
  884. tag: '',
  885. postTag: '',
  886. name: '',
  887. postName: '',
  888. type: '',
  889. postType: '',
  890. description: '',
  891. end: '',
  892. lineEnd: '',
  893. },
  894. },
  895. {
  896. number: 2,
  897. source: ' *',
  898. tokens: {
  899. start: ' ',
  900. delimiter: '*',
  901. postDelimiter: '',
  902. tag: '',
  903. postTag: '',
  904. name: '',
  905. postName: '',
  906. type: '',
  907. postType: '',
  908. description: '',
  909. end: '',
  910. lineEnd: '',
  911. },
  912. },
  913. {
  914. number: 3,
  915. source: ' * @my-tag my-name',
  916. tokens: {
  917. start: ' ',
  918. delimiter: '*',
  919. postDelimiter: ' ',
  920. tag: '@my-tag',
  921. postTag: ' ',
  922. name: 'my-name',
  923. postName: '',
  924. type: '',
  925. postType: '',
  926. description: '',
  927. end: '',
  928. lineEnd: '',
  929. },
  930. },
  931. {
  932. number: 4,
  933. source: ' */',
  934. tokens: {
  935. start: ' ',
  936. delimiter: '',
  937. postDelimiter: '',
  938. tag: '',
  939. postTag: '',
  940. name: '',
  941. postName: '',
  942. type: '',
  943. postType: '',
  944. description: '',
  945. end: '*/',
  946. lineEnd: '',
  947. },
  948. },
  949. ];
  950. expect(parsed).toEqual([
  951. {
  952. description: '',
  953. tags: [
  954. {
  955. tag: 'my-tag',
  956. name: 'my-name',
  957. type: '',
  958. optional: false,
  959. description: '',
  960. problems: [],
  961. source: source.slice(2),
  962. },
  963. ],
  964. source,
  965. problems: [],
  966. },
  967. ]);
  968. });
  969. test('tag, type, and name', () => {
  970. const parsed = parse(`
  971. /**
  972. *
  973. * @my-tag {my.type} my-name
  974. */
  975. var a`);
  976. const source = [
  977. {
  978. number: 1,
  979. source: ' /**',
  980. tokens: {
  981. start: ' ',
  982. delimiter: '/**',
  983. postDelimiter: '',
  984. tag: '',
  985. postTag: '',
  986. name: '',
  987. postName: '',
  988. type: '',
  989. postType: '',
  990. description: '',
  991. end: '',
  992. lineEnd: '',
  993. },
  994. },
  995. {
  996. number: 2,
  997. source: ' *',
  998. tokens: {
  999. start: ' ',
  1000. delimiter: '*',
  1001. postDelimiter: '',
  1002. tag: '',
  1003. postTag: '',
  1004. name: '',
  1005. postName: '',
  1006. type: '',
  1007. postType: '',
  1008. description: '',
  1009. end: '',
  1010. lineEnd: '',
  1011. },
  1012. },
  1013. {
  1014. number: 3,
  1015. source: ' * @my-tag {my.type} my-name',
  1016. tokens: {
  1017. start: ' ',
  1018. delimiter: '*',
  1019. postDelimiter: ' ',
  1020. tag: '@my-tag',
  1021. postTag: ' ',
  1022. name: 'my-name',
  1023. postName: '',
  1024. type: '{my.type}',
  1025. postType: ' ',
  1026. description: '',
  1027. end: '',
  1028. lineEnd: '',
  1029. },
  1030. },
  1031. {
  1032. number: 4,
  1033. source: ' */',
  1034. tokens: {
  1035. start: ' ',
  1036. delimiter: '',
  1037. postDelimiter: '',
  1038. tag: '',
  1039. postTag: '',
  1040. name: '',
  1041. postName: '',
  1042. type: '',
  1043. postType: '',
  1044. description: '',
  1045. end: '*/',
  1046. lineEnd: '',
  1047. },
  1048. },
  1049. ];
  1050. expect(parsed).toEqual([
  1051. {
  1052. description: '',
  1053. tags: [
  1054. {
  1055. tag: 'my-tag',
  1056. name: 'my-name',
  1057. type: 'my.type',
  1058. optional: false,
  1059. description: '',
  1060. problems: [],
  1061. source: source.slice(2),
  1062. },
  1063. ],
  1064. source,
  1065. problems: [],
  1066. },
  1067. ]);
  1068. });
  1069. test('tag, type, name, and description', () => {
  1070. const parsed = parse(`
  1071. /**
  1072. *
  1073. * @my-tag {my.type} my-name description text
  1074. */
  1075. var a`);
  1076. const source = [
  1077. {
  1078. number: 1,
  1079. source: ' /**',
  1080. tokens: {
  1081. start: ' ',
  1082. delimiter: '/**',
  1083. postDelimiter: '',
  1084. tag: '',
  1085. postTag: '',
  1086. name: '',
  1087. postName: '',
  1088. type: '',
  1089. postType: '',
  1090. description: '',
  1091. end: '',
  1092. lineEnd: '',
  1093. },
  1094. },
  1095. {
  1096. number: 2,
  1097. source: ' *',
  1098. tokens: {
  1099. start: ' ',
  1100. delimiter: '*',
  1101. postDelimiter: '',
  1102. tag: '',
  1103. postTag: '',
  1104. name: '',
  1105. postName: '',
  1106. type: '',
  1107. postType: '',
  1108. description: '',
  1109. end: '',
  1110. lineEnd: '',
  1111. },
  1112. },
  1113. {
  1114. number: 3,
  1115. source: ' * @my-tag {my.type} my-name description text',
  1116. tokens: {
  1117. start: ' ',
  1118. delimiter: '*',
  1119. postDelimiter: ' ',
  1120. tag: '@my-tag',
  1121. postTag: ' ',
  1122. name: 'my-name',
  1123. postName: ' ',
  1124. type: '{my.type}',
  1125. postType: ' ',
  1126. description: 'description text',
  1127. end: '',
  1128. lineEnd: '',
  1129. },
  1130. },
  1131. {
  1132. number: 4,
  1133. source: ' */',
  1134. tokens: {
  1135. start: ' ',
  1136. delimiter: '',
  1137. postDelimiter: '',
  1138. tag: '',
  1139. postTag: '',
  1140. name: '',
  1141. postName: '',
  1142. type: '',
  1143. postType: '',
  1144. description: '',
  1145. end: '*/',
  1146. lineEnd: '',
  1147. },
  1148. },
  1149. ];
  1150. expect(parsed).toEqual([
  1151. {
  1152. description: '',
  1153. tags: [
  1154. {
  1155. tag: 'my-tag',
  1156. name: 'my-name',
  1157. type: 'my.type',
  1158. optional: false,
  1159. description: 'description text',
  1160. problems: [],
  1161. source: source.slice(2),
  1162. },
  1163. ],
  1164. source,
  1165. problems: [],
  1166. },
  1167. ]);
  1168. });
  1169. test('description contains /**', () => {
  1170. const parsed = parse(`
  1171. /**
  1172. *
  1173. * @my-tag {my.type} my-name description text /**
  1174. */
  1175. var a`);
  1176. const source = [
  1177. {
  1178. number: 1,
  1179. source: ' /**',
  1180. tokens: {
  1181. start: ' ',
  1182. delimiter: '/**',
  1183. postDelimiter: '',
  1184. tag: '',
  1185. postTag: '',
  1186. name: '',
  1187. postName: '',
  1188. type: '',
  1189. postType: '',
  1190. description: '',
  1191. end: '',
  1192. lineEnd: '',
  1193. },
  1194. },
  1195. {
  1196. number: 2,
  1197. source: ' *',
  1198. tokens: {
  1199. start: ' ',
  1200. delimiter: '*',
  1201. postDelimiter: '',
  1202. tag: '',
  1203. postTag: '',
  1204. name: '',
  1205. postName: '',
  1206. type: '',
  1207. postType: '',
  1208. description: '',
  1209. end: '',
  1210. lineEnd: '',
  1211. },
  1212. },
  1213. {
  1214. number: 3,
  1215. source: ' * @my-tag {my.type} my-name description text /**',
  1216. tokens: {
  1217. start: ' ',
  1218. delimiter: '*',
  1219. postDelimiter: ' ',
  1220. tag: '@my-tag',
  1221. postTag: ' ',
  1222. name: 'my-name',
  1223. postName: ' ',
  1224. type: '{my.type}',
  1225. postType: ' ',
  1226. description: 'description text /**',
  1227. end: '',
  1228. lineEnd: '',
  1229. },
  1230. },
  1231. {
  1232. number: 4,
  1233. source: ' */',
  1234. tokens: {
  1235. start: ' ',
  1236. delimiter: '',
  1237. postDelimiter: '',
  1238. tag: '',
  1239. postTag: '',
  1240. name: '',
  1241. postName: '',
  1242. type: '',
  1243. postType: '',
  1244. description: '',
  1245. end: '*/',
  1246. lineEnd: '',
  1247. },
  1248. },
  1249. ];
  1250. expect(parsed).toEqual([
  1251. {
  1252. description: '',
  1253. tags: [
  1254. {
  1255. tag: 'my-tag',
  1256. name: 'my-name',
  1257. type: 'my.type',
  1258. optional: false,
  1259. description: 'description text /**',
  1260. problems: [],
  1261. source: source.slice(2),
  1262. },
  1263. ],
  1264. source,
  1265. problems: [],
  1266. },
  1267. ]);
  1268. });
  1269. test('tag, type, name, and description separated by mixed spaces', () => {
  1270. const parsed = parse(`
  1271. /**
  1272. *
  1273. * @my-tag\t {my.type}\t my-name\t description text
  1274. */
  1275. var a`);
  1276. const source = [
  1277. {
  1278. number: 1,
  1279. source: ' /**',
  1280. tokens: {
  1281. start: ' ',
  1282. delimiter: '/**',
  1283. postDelimiter: '',
  1284. tag: '',
  1285. postTag: '',
  1286. name: '',
  1287. postName: '',
  1288. type: '',
  1289. postType: '',
  1290. description: '',
  1291. end: '',
  1292. lineEnd: '',
  1293. },
  1294. },
  1295. {
  1296. number: 2,
  1297. source: ' *',
  1298. tokens: {
  1299. start: ' ',
  1300. delimiter: '*',
  1301. postDelimiter: '',
  1302. tag: '',
  1303. postTag: '',
  1304. name: '',
  1305. postName: '',
  1306. type: '',
  1307. postType: '',
  1308. description: '',
  1309. end: '',
  1310. lineEnd: '',
  1311. },
  1312. },
  1313. {
  1314. number: 3,
  1315. source: ' * @my-tag\t {my.type}\t my-name\t description text',
  1316. tokens: {
  1317. start: ' ',
  1318. delimiter: '*',
  1319. postDelimiter: ' ',
  1320. tag: '@my-tag',
  1321. postTag: '\t ',
  1322. name: 'my-name',
  1323. postName: '\t ',
  1324. type: '{my.type}',
  1325. postType: '\t ',
  1326. description: 'description text',
  1327. end: '',
  1328. lineEnd: '',
  1329. },
  1330. },
  1331. {
  1332. number: 4,
  1333. source: ' */',
  1334. tokens: {
  1335. start: ' ',
  1336. delimiter: '',
  1337. postDelimiter: '',
  1338. tag: '',
  1339. postTag: '',
  1340. name: '',
  1341. postName: '',
  1342. type: '',
  1343. postType: '',
  1344. description: '',
  1345. end: '*/',
  1346. lineEnd: '',
  1347. },
  1348. },
  1349. ];
  1350. expect(parsed).toEqual([
  1351. {
  1352. description: '',
  1353. tags: [
  1354. {
  1355. tag: 'my-tag',
  1356. name: 'my-name',
  1357. type: 'my.type',
  1358. optional: false,
  1359. description: 'description text',
  1360. problems: [],
  1361. source: source.slice(2),
  1362. },
  1363. ],
  1364. source,
  1365. problems: [],
  1366. },
  1367. ]);
  1368. });
  1369. test('tag with multiline description', () => {
  1370. const parsed = parse(`
  1371. /**
  1372. * @my-tag {my.type} my-name description line 1
  1373. * description line 2
  1374. * description line 3
  1375. */
  1376. var a`);
  1377. const source = [
  1378. {
  1379. number: 1,
  1380. source: ' /**',
  1381. tokens: {
  1382. start: ' ',
  1383. delimiter: '/**',
  1384. postDelimiter: '',
  1385. tag: '',
  1386. postTag: '',
  1387. name: '',
  1388. postName: '',
  1389. type: '',
  1390. postType: '',
  1391. description: '',
  1392. end: '',
  1393. lineEnd: '',
  1394. },
  1395. },
  1396. {
  1397. number: 2,
  1398. source: ' * @my-tag {my.type} my-name description line 1',
  1399. tokens: {
  1400. start: ' ',
  1401. delimiter: '*',
  1402. postDelimiter: ' ',
  1403. tag: '@my-tag',
  1404. postTag: ' ',
  1405. name: 'my-name',
  1406. postName: ' ',
  1407. type: '{my.type}',
  1408. postType: ' ',
  1409. description: 'description line 1',
  1410. end: '',
  1411. lineEnd: '',
  1412. },
  1413. },
  1414. {
  1415. number: 3,
  1416. source: ' * description line 2',
  1417. tokens: {
  1418. start: ' ',
  1419. delimiter: '*',
  1420. postDelimiter: ' ',
  1421. tag: '',
  1422. postTag: '',
  1423. name: '',
  1424. postName: '',
  1425. type: '',
  1426. postType: '',
  1427. description: 'description line 2',
  1428. end: '',
  1429. lineEnd: '',
  1430. },
  1431. },
  1432. {
  1433. number: 4,
  1434. source: ' * description line 3',
  1435. tokens: {
  1436. start: ' ',
  1437. delimiter: '*',
  1438. postDelimiter: ' ',
  1439. tag: '',
  1440. postTag: '',
  1441. name: '',
  1442. postName: '',
  1443. type: '',
  1444. postType: '',
  1445. description: 'description line 3',
  1446. end: '',
  1447. lineEnd: '',
  1448. },
  1449. },
  1450. {
  1451. number: 5,
  1452. source: ' */',
  1453. tokens: {
  1454. start: ' ',
  1455. delimiter: '',
  1456. postDelimiter: '',
  1457. tag: '',
  1458. postTag: '',
  1459. name: '',
  1460. postName: '',
  1461. type: '',
  1462. postType: '',
  1463. description: '',
  1464. end: '*/',
  1465. lineEnd: '',
  1466. },
  1467. },
  1468. ];
  1469. expect(parsed).toEqual([
  1470. {
  1471. description: '',
  1472. tags: [
  1473. {
  1474. tag: 'my-tag',
  1475. name: 'my-name',
  1476. type: 'my.type',
  1477. optional: false,
  1478. description:
  1479. 'description line 1 description line 2 description line 3',
  1480. problems: [],
  1481. source: source.slice(1),
  1482. },
  1483. ],
  1484. source,
  1485. problems: [],
  1486. },
  1487. ]);
  1488. });
  1489. test('optional name', () => {
  1490. const parsed = parse(`
  1491. /**
  1492. *
  1493. * @my-tag {my.type} [my-name] description text
  1494. */
  1495. var a`);
  1496. const source = [
  1497. {
  1498. number: 1,
  1499. source: ' /**',
  1500. tokens: {
  1501. start: ' ',
  1502. delimiter: '/**',
  1503. postDelimiter: '',
  1504. tag: '',
  1505. postTag: '',
  1506. name: '',
  1507. postName: '',
  1508. type: '',
  1509. postType: '',
  1510. description: '',
  1511. end: '',
  1512. lineEnd: '',
  1513. },
  1514. },
  1515. {
  1516. number: 2,
  1517. source: ' *',
  1518. tokens: {
  1519. start: ' ',
  1520. delimiter: '*',
  1521. postDelimiter: '',
  1522. tag: '',
  1523. postTag: '',
  1524. name: '',
  1525. postName: '',
  1526. type: '',
  1527. postType: '',
  1528. description: '',
  1529. end: '',
  1530. lineEnd: '',
  1531. },
  1532. },
  1533. {
  1534. number: 3,
  1535. source: ' * @my-tag {my.type} [my-name] description text',
  1536. tokens: {
  1537. start: ' ',
  1538. delimiter: '*',
  1539. postDelimiter: ' ',
  1540. tag: '@my-tag',
  1541. postTag: ' ',
  1542. name: '[my-name]',
  1543. postName: ' ',
  1544. type: '{my.type}',
  1545. postType: ' ',
  1546. description: 'description text',
  1547. end: '',
  1548. lineEnd: '',
  1549. },
  1550. },
  1551. {
  1552. number: 4,
  1553. source: ' */',
  1554. tokens: {
  1555. start: ' ',
  1556. delimiter: '',
  1557. postDelimiter: '',
  1558. tag: '',
  1559. postTag: '',
  1560. name: '',
  1561. postName: '',
  1562. type: '',
  1563. postType: '',
  1564. description: '',
  1565. end: '*/',
  1566. lineEnd: '',
  1567. },
  1568. },
  1569. ];
  1570. expect(parsed).toEqual([
  1571. {
  1572. description: '',
  1573. tags: [
  1574. {
  1575. tag: 'my-tag',
  1576. name: 'my-name',
  1577. type: 'my.type',
  1578. optional: true,
  1579. description: 'description text',
  1580. problems: [],
  1581. source: source.slice(2),
  1582. },
  1583. ],
  1584. source,
  1585. problems: [],
  1586. },
  1587. ]);
  1588. });
  1589. test('report name errors', () => {
  1590. const parsed = parse(`
  1591. /**
  1592. *
  1593. * @my-tag {my.type} [my-name description text
  1594. */
  1595. var a`);
  1596. const source = [
  1597. {
  1598. number: 1,
  1599. source: ' /**',
  1600. tokens: {
  1601. start: ' ',
  1602. delimiter: '/**',
  1603. postDelimiter: '',
  1604. tag: '',
  1605. postTag: '',
  1606. name: '',
  1607. postName: '',
  1608. type: '',
  1609. postType: '',
  1610. description: '',
  1611. end: '',
  1612. lineEnd: '',
  1613. },
  1614. },
  1615. {
  1616. number: 2,
  1617. source: ' *',
  1618. tokens: {
  1619. start: ' ',
  1620. delimiter: '*',
  1621. postDelimiter: '',
  1622. tag: '',
  1623. postTag: '',
  1624. name: '',
  1625. postName: '',
  1626. type: '',
  1627. postType: '',
  1628. description: '',
  1629. end: '',
  1630. lineEnd: '',
  1631. },
  1632. },
  1633. {
  1634. number: 3,
  1635. source: ' * @my-tag {my.type} [my-name description text',
  1636. tokens: {
  1637. start: ' ',
  1638. delimiter: '*',
  1639. postDelimiter: ' ',
  1640. tag: '@my-tag',
  1641. postTag: ' ',
  1642. name: '',
  1643. postName: '',
  1644. type: '{my.type}',
  1645. postType: ' ',
  1646. description: '[my-name description text',
  1647. end: '',
  1648. lineEnd: '',
  1649. },
  1650. },
  1651. {
  1652. number: 4,
  1653. source: ' */',
  1654. tokens: {
  1655. start: ' ',
  1656. delimiter: '',
  1657. postDelimiter: '',
  1658. tag: '',
  1659. postTag: '',
  1660. name: '',
  1661. postName: '',
  1662. type: '',
  1663. postType: '',
  1664. description: '',
  1665. end: '*/',
  1666. lineEnd: '',
  1667. },
  1668. },
  1669. ];
  1670. const problems = [
  1671. {
  1672. code: 'spec:name:unpaired-brackets',
  1673. critical: true,
  1674. message: 'unpaired brackets',
  1675. line: 3,
  1676. },
  1677. ];
  1678. expect(parsed).toEqual([
  1679. {
  1680. description: '',
  1681. tags: [
  1682. {
  1683. tag: 'my-tag',
  1684. name: '',
  1685. type: 'my.type',
  1686. optional: false,
  1687. description: '',
  1688. source: source.slice(2),
  1689. problems,
  1690. },
  1691. ],
  1692. source,
  1693. problems,
  1694. },
  1695. ]);
  1696. });
  1697. test('misaligned block', () => {
  1698. const parsed = parse(`
  1699. /**
  1700. * @my-tag {my.type} my-name description line 1
  1701. description line 2
  1702. * description line 3
  1703. */
  1704. var a`);
  1705. const source = [
  1706. {
  1707. number: 1,
  1708. source: ' /**',
  1709. tokens: {
  1710. start: ' ',
  1711. delimiter: '/**',
  1712. postDelimiter: '',
  1713. tag: '',
  1714. postTag: '',
  1715. name: '',
  1716. postName: '',
  1717. type: '',
  1718. postType: '',
  1719. description: '',
  1720. end: '',
  1721. lineEnd: '',
  1722. },
  1723. },
  1724. {
  1725. number: 2,
  1726. source: '* @my-tag {my.type} my-name description line 1',
  1727. tokens: {
  1728. start: '',
  1729. delimiter: '*',
  1730. postDelimiter: ' ',
  1731. tag: '@my-tag',
  1732. postTag: ' ',
  1733. name: 'my-name',
  1734. postName: ' ',
  1735. type: '{my.type}',
  1736. postType: ' ',
  1737. description: 'description line 1',
  1738. end: '',
  1739. lineEnd: '',
  1740. },
  1741. },
  1742. {
  1743. number: 3,
  1744. source: ' description line 2',
  1745. tokens: {
  1746. start: ' ',
  1747. delimiter: '',
  1748. postDelimiter: '',
  1749. tag: '',
  1750. postTag: '',
  1751. name: '',
  1752. postName: '',
  1753. type: '',
  1754. postType: '',
  1755. description: 'description line 2',
  1756. end: '',
  1757. lineEnd: '',
  1758. },
  1759. },
  1760. {
  1761. number: 4,
  1762. source: ' * description line 3',
  1763. tokens: {
  1764. start: ' ',
  1765. delimiter: '*',
  1766. postDelimiter: ' ',
  1767. tag: '',
  1768. postTag: '',
  1769. name: '',
  1770. postName: '',
  1771. type: '',
  1772. postType: '',
  1773. description: 'description line 3',
  1774. end: '',
  1775. lineEnd: '',
  1776. },
  1777. },
  1778. {
  1779. number: 5,
  1780. source: ' */',
  1781. tokens: {
  1782. start: ' ',
  1783. delimiter: '',
  1784. postDelimiter: '',
  1785. tag: '',
  1786. postTag: '',
  1787. name: '',
  1788. postName: '',
  1789. type: '',
  1790. postType: '',
  1791. description: '',
  1792. end: '*/',
  1793. lineEnd: '',
  1794. },
  1795. },
  1796. ];
  1797. expect(parsed).toEqual([
  1798. {
  1799. description: '',
  1800. tags: [
  1801. {
  1802. tag: 'my-tag',
  1803. name: 'my-name',
  1804. type: 'my.type',
  1805. optional: false,
  1806. description:
  1807. 'description line 1 description line 2 description line 3',
  1808. problems: [],
  1809. source: source.slice(1),
  1810. },
  1811. ],
  1812. source,
  1813. problems: [],
  1814. },
  1815. ]);
  1816. });