clarinet.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. if (!clarinet) { // node
  2. var clarinet = require('../clarinet.js')
  3. , _ = require('underscore')
  4. ;
  5. }
  6. function assert(expr, msg) {
  7. if (!expr) {
  8. throw new Error(msg || 'failed');
  9. }
  10. }
  11. var seps = [undefined, /\t|\n|\r/, '']
  12. , sep
  13. , docs =
  14. { empty_array :
  15. { text : '[]'
  16. , events :
  17. [ ['openarray' , undefined]
  18. , ['closearray' , undefined]
  19. , ['end' , undefined]
  20. , ['ready' , undefined]
  21. ]
  22. }
  23. , just_slash :
  24. { text : '["\\\\"]'
  25. , events :
  26. [ ['openarray' , undefined]
  27. , ["value" , "\\"]
  28. , ['closearray' , undefined]
  29. , ['end' , undefined]
  30. , ['ready' , undefined]
  31. ]
  32. }
  33. , zero_byte :
  34. { text : '{"foo": "\\u0000"}'
  35. , events :
  36. [ ["openobject" , "foo"]
  37. , ["value" , "\u0000"]
  38. , ["closeobject" , undefined]
  39. , ['end' , undefined]
  40. , ['ready' , undefined]
  41. ]
  42. }
  43. , empty_value :
  44. { text : '{"foo": ""}'
  45. , events :
  46. [ ["openobject" , "foo"]
  47. , ["value" , ""]
  48. , ["closeobject" , undefined]
  49. , ['end' , undefined]
  50. , ['ready' , undefined]
  51. ]
  52. }
  53. , three_byte_utf8 :
  54. { text : '{"matzue": "松江", "asakusa": "浅草"}'
  55. , events :
  56. [ ["openobject" , "matzue"]
  57. , ["value" , "松江"]
  58. , ["key" , "asakusa"]
  59. , ["value" , "浅草"]
  60. , ["closeobject" , undefined]
  61. , ['end' , undefined]
  62. , ['ready' , undefined]
  63. ]
  64. }
  65. , four_byte_utf8 :
  66. { text : '{ "U+10ABCD": "" }'
  67. , events :
  68. [ ["openobject" , "U+10ABCD"]
  69. , ["value" , ""]
  70. , ["closeobject" , undefined]
  71. , ['end' , undefined]
  72. , ['ready' , undefined]
  73. ]
  74. }
  75. , bulgarian :
  76. { text : '["Да Му Еба Майката"]'
  77. , events :
  78. [ ["openarray" , undefined]
  79. , ["value" , "Да Му Еба Майката"]
  80. , ["closearray" , undefined]
  81. , ['end' , undefined]
  82. , ['ready' , undefined]
  83. ]
  84. }
  85. , codepoints_from_unicodes :
  86. { text : '["\\u004d\\u0430\\u4e8c\\ud800\\udf02"]'
  87. , events :
  88. [ ["openarray" , undefined]
  89. , ["value" , "\u004d\u0430\u4e8c\ud800\udf02"]
  90. , ["closearray" , undefined]
  91. , ['end' , undefined]
  92. , ['ready' , undefined]
  93. ]
  94. }
  95. , empty_object :
  96. { text : '{}'
  97. , events :
  98. [ ["openobject" , undefined]
  99. , ["closeobject" , undefined]
  100. , ['end' , undefined]
  101. , ['ready' , undefined]
  102. ]
  103. }
  104. , foobar :
  105. { text : '{"foo": "bar"}'
  106. , events :
  107. [ ["openobject" , "foo"]
  108. , ["value" , "bar"]
  109. , ["closeobject" , undefined]
  110. , ['end' , undefined]
  111. , ['ready' , undefined]
  112. ]
  113. }
  114. , as_is :
  115. { text : "{\"foo\": \"its \\\"as is\\\", \\\"yeah\", \"bar\": false}"
  116. , events :
  117. [ ["openobject" , "foo"]
  118. , ["value" , 'its "as is", "yeah']
  119. , ["key" , "bar"]
  120. , ["value" , false]
  121. , ["closeobject" , undefined]
  122. , ['end' , undefined]
  123. , ['ready' , undefined]
  124. ]
  125. }
  126. , array :
  127. { text : '["one", "two"]'
  128. , events :
  129. [ ['openarray' , undefined]
  130. , ['value' , 'one']
  131. , ['value' , 'two']
  132. , ['closearray' , undefined]
  133. , ['end' , undefined]
  134. , ['ready' , undefined]
  135. ]
  136. }
  137. , array_fu :
  138. { text : '["foo", "bar", "baz",true,false,null,{"key":"value"},' +
  139. '[null,null,null,[]]," \\\\ "]'
  140. , events :
  141. [ ['openarray' , undefined]
  142. , ['value' , 'foo']
  143. , ['value' , 'bar']
  144. , ['value' , 'baz']
  145. , ['value' , true]
  146. , ['value' , false]
  147. , ['value' , null]
  148. , ['openobject' , 'key']
  149. , ['value' , "value"]
  150. , ["closeobject" , undefined]
  151. , ['openarray' , undefined]
  152. , ['value' , null]
  153. , ['value' , null]
  154. , ['value' , null]
  155. , ['openarray' , undefined]
  156. , ['closearray' , undefined]
  157. , ['closearray' , undefined]
  158. , ['value' , " \\ "]
  159. , ['closearray' , undefined]
  160. , ['end' , undefined]
  161. , ['ready' , undefined]
  162. ]
  163. }
  164. , simple_exp :
  165. { text : '[10e-01]'
  166. , events :
  167. [ ['openarray' , undefined]
  168. , ['value' , 10e-01]
  169. , ['closearray' , undefined]
  170. , ['end' , undefined]
  171. , ['ready' , undefined]
  172. ]
  173. }
  174. , nested :
  175. { text : '{"a":{"b":"c"}}'
  176. , events :
  177. [ ["openobject" , "a"]
  178. , ["openobject" , "b"]
  179. , ["value" , "c"]
  180. , ["closeobject" , undefined]
  181. , ["closeobject" , undefined]
  182. , ['end' , undefined]
  183. , ['ready' , undefined]
  184. ]
  185. }
  186. , nested_array :
  187. { text : '{"a":["b", "c"]}'
  188. , events :
  189. [ ["openobject" , "a"]
  190. , ['openarray' , undefined]
  191. , ['value' , 'b']
  192. , ['value' , 'c']
  193. , ['closearray' , undefined]
  194. , ["closeobject" , undefined]
  195. , ['end' , undefined]
  196. , ['ready' , undefined]
  197. ]
  198. }
  199. , array_of_objs :
  200. { text : '[{"a":"b"}, {"c":"d"}]'
  201. , events :
  202. [ ['openarray' , undefined]
  203. , ["openobject" , 'a']
  204. , ['value' , 'b']
  205. , ["closeobject" , undefined]
  206. , ["openobject" , 'c']
  207. , ['value' , 'd']
  208. , ["closeobject" , undefined]
  209. , ['closearray' , undefined]
  210. , ['end' , undefined]
  211. , ['ready' , undefined]
  212. ]
  213. }
  214. , two_keys :
  215. { text : '{"a": "b", "c": "d"}'
  216. , events :
  217. [ ["openobject" , "a"]
  218. , ["value" , "b"]
  219. , ["key" , "c"]
  220. , ["value" , "d"]
  221. , ["closeobject" , undefined]
  222. , ['end' , undefined]
  223. , ['ready' , undefined]
  224. ]
  225. }
  226. , key_true :
  227. { text : '{"foo": true, "bar": false, "baz": null}'
  228. , events :
  229. [ ["openobject" , "foo"]
  230. , ["value" , true]
  231. , ["key" , "bar"]
  232. , ["value" , false]
  233. , ["key" , "baz"]
  234. , ["value" , null]
  235. , ["closeobject" , undefined]
  236. , ['end' , undefined]
  237. , ['ready' , undefined]
  238. ]
  239. }
  240. , obj_strange_strings :
  241. { text :
  242. '{"foo": "bar and all\\\"", "bar": "its \\\"nice\\\""}'
  243. , events :
  244. [ ["openobject" , "foo"]
  245. , ["value" , 'bar and all"']
  246. , ["key" , "bar"]
  247. , ["value" , 'its "nice"']
  248. , ["closeobject" , undefined]
  249. , ['end' , undefined]
  250. , ['ready' , undefined]
  251. ]
  252. }
  253. , bad_foo_bar :
  254. { text :
  255. '["foo", "bar"'
  256. , events :
  257. [ ["openarray" , undefined]
  258. , ["value" , 'foo']
  259. , ["value" , 'bar']
  260. , ['error' , undefined]
  261. , ['end' , undefined]
  262. , ['ready' , undefined]
  263. ]
  264. }
  265. , string_invalid_escape:
  266. { text :
  267. '["and you can\'t escape thi\s"]'
  268. , events :
  269. [ ["openarray" , undefined]
  270. , ["value" , 'and you can\'t escape this']
  271. , ["closearray" , undefined]
  272. , ['end' , undefined]
  273. , ['ready' , undefined]
  274. ]
  275. }
  276. , nuts_and_bolts :
  277. { text : '{"boolean, true": true' +
  278. ', "boolean, false": false' +
  279. ', "null": null }'
  280. , events :
  281. [ ["openobject" , "boolean, true"]
  282. , ["value" , true]
  283. , ["key" , "boolean, false"]
  284. , ["value" , false]
  285. , ["key" , "null"]
  286. , ["value" , null]
  287. , ["closeobject" , undefined]
  288. , ['end' , undefined]
  289. , ['ready' , undefined]
  290. ]
  291. }
  292. , frekin_string:
  293. { text : '["\\\\\\"\\"a\\""]'
  294. , events :
  295. [ ["openarray" , undefined]
  296. , ["value" , '\\\"\"a\"']
  297. , ["closearray" , undefined]
  298. , ['end' , undefined]
  299. , ['ready' , undefined]
  300. ]
  301. }
  302. , array_of_string_insanity :
  303. { text : '["\\\"and this string has an escape at the beginning",' +
  304. '"and this string has no escapes"]'
  305. , events :
  306. [ ["openarray" , undefined]
  307. , ["value" , "\"and this string has an escape at the beginning"]
  308. , ["value" , "and this string has no escapes"]
  309. , ["closearray" , undefined]
  310. , ['end' , undefined]
  311. , ['ready' , undefined]
  312. ]
  313. }
  314. , non_utf8 :
  315. { text :
  316. '{"CoreletAPIVersion":2,"CoreletType":"standalone",' +
  317. '"documentation":"A corelet that provides the capability to upload' +
  318. ' a folder’s contents into a user’s locker.","functions":[' +
  319. '{"documentation":"Displays a dialog box that allows user to ' +
  320. 'select a folder on the local system.","name":' +
  321. '"ShowBrowseDialog","parameters":[{"documentation":"The ' +
  322. 'callback function for results.","name":"callback","required":' +
  323. 'true,"type":"callback"}]},{"documentation":"Uploads all mp3 files' +
  324. ' in the folder provided.","name":"UploadFolder","parameters":' +
  325. '[{"documentation":"The path to upload mp3 files from."' +
  326. ',"name":"path","required":true,"type":"string"},{"documentation":' +
  327. ' "The callback function for progress.","name":"callback",' +
  328. '"required":true,"type":"callback"}]},{"documentation":"Returns' +
  329. ' the server name to the current locker service.",' +
  330. '"name":"GetLockerService","parameters":[]},{"documentation":' +
  331. '"Changes the name of the locker service.","name":"SetLockerSer' +
  332. 'vice","parameters":[{"documentation":"The value of the locker' +
  333. ' service to set active.","name":"LockerService","required":true' +
  334. ',"type":"string"}]},{"documentation":"Downloads locker files to' +
  335. ' the suggested folder.","name":"DownloadFile","parameters":[{"' +
  336. 'documentation":"The origin path of the locker file.",' +
  337. '"name":"path","required":true,"type":"string"},{"documentation"' +
  338. ':"The Window destination path of the locker file.",' +
  339. '"name":"destination","required":true,"type":"integer"},{"docum' +
  340. 'entation":"The callback function for progress.","name":' +
  341. '"callback","required":true,"type":"callback"}]}],' +
  342. '"name":"LockerUploader","version":{"major":0,' +
  343. '"micro":1,"minor":0},"versionString":"0.0.1"}'
  344. , events :
  345. [ [ "openobject" , "CoreletAPIVersion"]
  346. , [ "value" , 2 ]
  347. , [ "key" , "CoreletType"]
  348. , [ "value" , "standalone" ]
  349. , [ "key" , "documentation"]
  350. , [ "value" , "A corelet that provides the capability to upload a folder’s contents into a user’s locker."]
  351. , ["key" , "functions"]
  352. , [ "openarray" , undefined]
  353. , [ "openobject" , "documentation"]
  354. , [ "value" , "Displays a dialog box that allows user to select a folder on the local system."]
  355. , [ "key" , "name"]
  356. , [ "value" , "ShowBrowseDialog"]
  357. , [ "key" , "parameters"]
  358. , [ "openarray" , undefined]
  359. , [ "openobject" , "documentation"]
  360. , [ "value" , "The callback function for results."]
  361. , [ "key" , "name"]
  362. , [ "value" , "callback"]
  363. , [ "key" , "required"]
  364. , [ "value" , true]
  365. , [ "key" , "type"]
  366. , [ "value" , "callback"]
  367. , [ "closeobject" , undefined]
  368. , [ "closearray" , undefined]
  369. , [ "closeobject" , undefined]
  370. , [ "openobject" , "documentation"]
  371. , [ "value" , "Uploads all mp3 files in the folder provided."]
  372. , [ "key" , "name"]
  373. , [ "value" , "UploadFolder"]
  374. , [ "key" , "parameters"]
  375. , [ "openarray" , undefined]
  376. , [ "openobject" , "documentation"]
  377. , [ "value" , "The path to upload mp3 files from."]
  378. , [ "key" , "name"]
  379. , [ "value" , "path"]
  380. , [ "key" , "required"]
  381. , [ "value" , true]
  382. , [ "key" , "type"]
  383. , [ "value" , "string"]
  384. , [ "closeobject" , undefined]
  385. , [ "openobject" , "documentation"]
  386. , [ "value" , "The callback function for progress."]
  387. , [ "key" , "name"]
  388. , [ "value" , "callback"]
  389. , [ "key" , "required"]
  390. , [ "value" , true ]
  391. , [ "key" , "type"]
  392. , [ "value" , "callback"]
  393. , [ "closeobject" , undefined]
  394. , [ "closearray" , undefined]
  395. , [ "closeobject" , undefined]
  396. , [ "openobject" , "documentation"]
  397. , [ "value" , "Returns the server name to the current locker service."]
  398. , [ "key" , "name"]
  399. , [ "value" , "GetLockerService"]
  400. , [ "key" , "parameters"]
  401. , [ "openarray" , undefined]
  402. , [ "closearray" , undefined]
  403. , [ "closeobject" , undefined]
  404. , [ "openobject" , "documentation"]
  405. , [ "value" , "Changes the name of the locker service."]
  406. , [ "key" , "name"]
  407. , [ "value" , "SetLockerService"]
  408. , [ "key" , "parameters"]
  409. , [ "openarray" , undefined]
  410. , [ "openobject" , "documentation"]
  411. , [ "value" , "The value of the locker service to set active."]
  412. , [ "key" , "name"]
  413. , [ "value" , "LockerService" ]
  414. , [ "key" , "required" ]
  415. , [ "value" , true]
  416. , [ "key" , "type"]
  417. , [ "value" , "string"]
  418. , [ "closeobject" , undefined]
  419. , [ "closearray" , undefined]
  420. , [ "closeobject" , undefined]
  421. , [ "openobject" , "documentation"]
  422. , [ "value" , "Downloads locker files to the suggested folder."]
  423. , [ "key" , "name"]
  424. , [ "value" , "DownloadFile"]
  425. , [ "key" , "parameters"]
  426. , [ "openarray" , undefined]
  427. , [ "openobject" , "documentation"]
  428. , [ "value" , "The origin path of the locker file."]
  429. , [ "key" , "name"]
  430. , [ "value" , "path"]
  431. , [ "key" , "required"]
  432. , [ "value" , true]
  433. , [ "key" , "type"]
  434. , [ "value" , "string"]
  435. , [ "closeobject" , undefined]
  436. , [ "openobject" , "documentation"]
  437. , [ "value" , "The Window destination path of the locker file."]
  438. , [ "key" , "name"]
  439. , [ "value" , "destination"]
  440. , [ "key" , "required"]
  441. , [ "value" , true]
  442. , [ "key" , "type"]
  443. , [ "value" , "integer"]
  444. , [ "closeobject" , undefined]
  445. , [ "openobject" , "documentation"]
  446. , [ "value" , "The callback function for progress."]
  447. , [ "key" , "name"]
  448. , [ "value" , "callback"]
  449. , [ "key" , "required"]
  450. , [ "value" , true]
  451. , [ "key" , "type"]
  452. , [ "value" , "callback"]
  453. , [ "closeobject" , undefined]
  454. , [ "closearray" , undefined]
  455. , [ "closeobject" , undefined]
  456. , [ "closearray" , undefined]
  457. , [ "key" , "name"]
  458. , [ "value" , "LockerUploader"]
  459. , [ "key" , "version"]
  460. , [ "openobject" , "major"]
  461. , [ "value" , 0]
  462. , [ "key" , "micro"]
  463. , [ "value" , 1]
  464. , [ "key" , "minor"]
  465. , [ "value" , 0]
  466. , [ "closeobject" , undefined]
  467. , [ "key" , "versionString"]
  468. , [ "value" , "0.0.1"]
  469. , [ "closeobject" , undefined]
  470. , [ "end" , undefined]
  471. , [ "ready" , undefined]
  472. ]
  473. }
  474. , array_of_arrays :
  475. { text : '[[[["foo"]]]]'
  476. , events :
  477. [ ['openarray' , undefined]
  478. , ['openarray' , undefined]
  479. , ['openarray' , undefined]
  480. , ['openarray' , undefined]
  481. , ["value" , "foo"]
  482. , ['closearray' , undefined]
  483. , ['closearray' , undefined]
  484. , ['closearray' , undefined]
  485. , ['closearray' , undefined]
  486. , ['end' , undefined]
  487. , ['ready' , undefined]
  488. ]
  489. }
  490. , low_overflow :
  491. { text : '[-9223372036854775808]',
  492. chunks: [
  493. '[-92233720', '36854775808]'
  494. ]
  495. , events :
  496. [ ['openarray' , undefined]
  497. , ["value" , -9223372036854775808]
  498. , ['closearray' , undefined]
  499. , ['end' , undefined]
  500. , ['ready' , undefined]
  501. ]
  502. }
  503. , high_overflow :
  504. { text : '[9223372036854775808]'
  505. , events :
  506. [ ['openarray' , undefined]
  507. , ["value" , 9223372036854775808]
  508. , ['closearray' , undefined]
  509. , ['end' , undefined]
  510. , ['ready' , undefined]
  511. ]
  512. }
  513. , floats :
  514. { text : '[0.1e2, 1e1, 3.141569, 10000000000000e-10]'
  515. , events :
  516. [ ['openarray' , undefined]
  517. , ["value" , 0.1e2]
  518. , ["value" , 1e1]
  519. , ["value" , 3.141569]
  520. , ["value" , 10000000000000e-10]
  521. , ['closearray' , undefined]
  522. , ['end' , undefined]
  523. , ['ready' , undefined]
  524. ]
  525. }
  526. , numbers_game :
  527. { text : '[1,0,-1,-0.3,0.3,1343.32,3345,3.1e124,'+
  528. ' 9223372036854775807,-9223372036854775807,0.1e2, ' +
  529. '1e1, 3.141569, 10000000000000e-10,' +
  530. '0.00011999999999999999, 6E-06, 6E-06, 1E-06, 1E-06,'+
  531. '"2009-10-20@20:38:21.539575", 9223372036854775808,' +
  532. '123456789,-123456789,' +
  533. '2147483647, -2147483647]'
  534. , events :
  535. [ ['openarray' , undefined]
  536. , ["value" , 1]
  537. , ["value" , 0]
  538. , ["value" , -1]
  539. , ["value" , -0.3]
  540. , ["value" , 0.3]
  541. , ["value" , 1343.32]
  542. , ["value" , 3345]
  543. , ["value" , 3.1e124]
  544. , ["value" , 9223372036854775807]
  545. , ["value" , -9223372036854775807]
  546. , ["value" , 0.1e2]
  547. , ["value" , 1e1]
  548. , ["value" , 3.141569]
  549. , ["value" , 10000000000000e-10]
  550. , ["value" , 0.00011999999999999999]
  551. , ["value" , 6E-06]
  552. , ["value" , 6E-06]
  553. , ["value" , 1E-06]
  554. , ["value" , 1E-06]
  555. , ["value" , "2009-10-20@20:38:21.539575"]
  556. , ["value" , 9223372036854775808]
  557. , ["value" , 123456789]
  558. , ["value" , -123456789]
  559. , ["value" , 2147483647]
  560. , ["value" , -2147483647]
  561. , ['closearray' , undefined]
  562. , ['end' , undefined]
  563. , ['ready' , undefined]
  564. ]
  565. }
  566. , johnsmith :
  567. { text : '{ "firstName": "John", "lastName" : "Smith", "age" : ' +
  568. '25, "address" : { "streetAddress": "21 2nd Street", ' +
  569. '"city" : "New York", "state" : "NY", "postalCode" : ' +
  570. ' "10021" }, "phoneNumber": [ { "type" : "home", ' +
  571. '"number": "212 555-1234" }, { "type" : "fax", ' +
  572. '"number": "646 555-4567" } ] }'
  573. , events :
  574. [ ["openobject" , "firstName"]
  575. , ["value" , "John"]
  576. , ["key" , "lastName"]
  577. , ["value" , "Smith"]
  578. , ["key" , "age"]
  579. , ["value" , 25]
  580. , ["key" , "address"]
  581. , ["openobject" , "streetAddress"]
  582. , ["value" , "21 2nd Street"]
  583. , ["key" , "city"]
  584. , ["value" , "New York"]
  585. , ["key" , "state"]
  586. , ["value" , "NY"]
  587. , ["key" , "postalCode"]
  588. , ["value" , "10021"]
  589. , ["closeobject" , undefined]
  590. , ["key" , "phoneNumber"]
  591. , ["openarray" , undefined]
  592. , ["openobject" , "type"]
  593. , ["value" , "home"]
  594. , ["key" , "number"]
  595. , ["value" , "212 555-1234"]
  596. , ["closeobject" , undefined]
  597. , ["openobject" , "type"]
  598. , ["value" , "fax"]
  599. , ["key" , "number"]
  600. , ["value" , "646 555-4567"]
  601. , ["closeobject" , undefined]
  602. , ["closearray" , undefined]
  603. , ["closeobject" , undefined]
  604. ]
  605. }
  606. , array_null :
  607. { text : '[null,false,true]',
  608. chunks : ['[nu', 'll,', 'fa', 'lse,', 'tr', 'ue]']
  609. , events :
  610. [ ["openarray" , undefined]
  611. , ["value" , null]
  612. , ["value" , false]
  613. , ["value" , true]
  614. , ["closearray" , undefined]
  615. , ['end' , undefined]
  616. , ['ready' , undefined]
  617. ]
  618. }
  619. , empty_array_comma :
  620. { text : '{"a":[],"c": {}, "b": true}'
  621. , events :
  622. [ ["openobject" , "a"]
  623. , ["openarray" , undefined]
  624. , ["closearray" , undefined]
  625. , ["key" , "c"]
  626. , ["openobject" , undefined]
  627. , ["closeobject" , undefined]
  628. , ["key" , "b"]
  629. , ["value" , true]
  630. , ["closeobject" , undefined]
  631. , ['end' , undefined]
  632. , ['ready' , undefined]
  633. ]
  634. }
  635. , incomplete_json_terminates_ending_in_number :
  636. { text : '[[1,2,3],[4,5'
  637. , events :
  638. [ ["openarray" , undefined]
  639. , ["openarray" , undefined]
  640. , ["value" , 1]
  641. , ["value" , 2]
  642. , ["value" , 3]
  643. , ["closearray" , undefined]
  644. , ["openarray" , undefined]
  645. , ["value" , 4]
  646. , ["error" , undefined]
  647. ]
  648. }
  649. , incomplete_json_terminates_ending_in_comma :
  650. { text : '[[1,2,3],'
  651. , events :
  652. [ ["openarray" , undefined]
  653. , ["openarray" , undefined]
  654. , ["value" , 1]
  655. , ["value" , 2]
  656. , ["value" , 3]
  657. , ["closearray" , undefined]
  658. , ["error" , undefined]
  659. ]
  660. }
  661. , json_org :
  662. { text :
  663. ('{\r\n' +
  664. ' "glossary": {\n' +
  665. ' "title": "example glossary",\n\r' +
  666. ' \t\t"GlossDiv": {\r\n' +
  667. ' "title": "S",\r\n' +
  668. ' \t\t\t"GlossList": {\r\n' +
  669. ' "GlossEntry": {\r\n' +
  670. ' "ID": "SGML",\r\n' +
  671. ' \t\t\t\t\t"SortAs": "SGML",\r\n' +
  672. ' \t\t\t\t\t"GlossTerm": "Standard Generalized ' +
  673. 'Markup Language",\r\n' +
  674. ' \t\t\t\t\t"Acronym": "SGML",\r\n' +
  675. ' \t\t\t\t\t"Abbrev": "ISO 8879:1986",\r\n' +
  676. ' \t\t\t\t\t"GlossDef": {\r\n' +
  677. ' "para": "A meta-markup language,' +
  678. ' used to create markup languages such as DocBook.",\r\n' +
  679. ' \t\t\t\t\t\t"GlossSeeAlso": ["GML", "XML"]\r\n' +
  680. ' },\r\n' +
  681. ' \t\t\t\t\t"GlossSee": "markup"\r\n' +
  682. ' }\r\n' +
  683. ' }\r\n' +
  684. ' }\r\n' +
  685. ' }\r\n' +
  686. ' }\r\n')
  687. , events :
  688. [ ["openobject" , "glossary"]
  689. , ["openobject" , "title"]
  690. , ['value' , "example glossary"]
  691. , ["key" , "GlossDiv"]
  692. , ["openobject" , "title"]
  693. , ['value' , "S"]
  694. , ["key" , "GlossList"]
  695. , ["openobject" , "GlossEntry"]
  696. , ["openobject" , "ID"]
  697. , ['value' , "SGML"]
  698. , ["key" , "SortAs"]
  699. , ['value' , "SGML"]
  700. , ["key" , "GlossTerm"]
  701. , ['value' , "Standard Generalized Markup Language"]
  702. , ["key" , "Acronym"]
  703. , ['value' , "SGML"]
  704. , ["key" , "Abbrev"]
  705. , ['value' , 'ISO 8879:1986']
  706. , ["key" , "GlossDef"]
  707. , ["openobject" , "para"]
  708. , ['value' , 'A meta-markup language, used to create markup languages such as DocBook.']
  709. , ["key" , "GlossSeeAlso"]
  710. , ['openarray' , undefined]
  711. , ['value' , "GML"]
  712. , ['value' , "XML"]
  713. , ['closearray' , undefined]
  714. , ["closeobject" , undefined]
  715. , ["key" , "GlossSee"]
  716. , ["value" , "markup"]
  717. , ["closeobject" , undefined]
  718. , ["closeobject" , undefined]
  719. , ["closeobject" , undefined]
  720. , ["closeobject" , undefined]
  721. , ["closeobject" , undefined]
  722. , ['end' , undefined]
  723. , ['ready' , undefined]
  724. ]
  725. }
  726. ,
  727. string_chunk_span :
  728. {
  729. text: '["L\'Oréal", "Lé\'Oral", "éalL\'Or"]',
  730. chunks: [
  731. '["L\'OrÃ',
  732. '©al", "Lé\'Oral", "éalL\'Or"]'
  733. ],
  734. events: [
  735. ['openarray', undefined],
  736. ['value', 'L\'Oréal'],
  737. ['value', 'Lé\'Oral'],
  738. ['value', 'éalL\'Or'],
  739. ['closearray', undefined]
  740. ]
  741. }
  742. };
  743. function generic(key, prechunked, sep) {
  744. return function () {
  745. var doc = docs[key].text
  746. , events = docs[key].events
  747. , l = typeof FastList === 'function' ? new FastList() : []
  748. , doc_chunks = !prechunked ? doc.split(sep) : docs[key].chunks
  749. , parser = clarinet.parser()
  750. , i = 0
  751. , current
  752. , env = process && process.env ? process.env : window
  753. , record = []
  754. ;
  755. _.each(events, function(event_pair) {
  756. l.push(event_pair);
  757. });
  758. _.each(clarinet.EVENTS, function(event) {
  759. parser["on"+event] = function (value) {
  760. if(env.CRECORD) { // for really big json we dont want to type all
  761. record.push([event,value]);
  762. if(event === 'end') console.log(JSON.stringify(record, null, 2));
  763. } else {
  764. current = l.shift();
  765. ++i;
  766. if(!(current && current[0])) { return; }
  767. assert(current[0] === event,
  768. '[ln' + i + '] event: [' + current[0] + '] got: [' + event +']');
  769. if(event!== 'error')
  770. assert(current[1] === value,
  771. '[ln' + i + '] value: [' + current[1] + '] got: [' + value +']');
  772. }
  773. };
  774. });
  775. _.each(doc_chunks, function(chunk) {
  776. parser.write(chunk);
  777. });
  778. parser.end();
  779. };
  780. }
  781. describe('clarinet', function(){
  782. describe('#generic', function() {
  783. for (var key in docs) {
  784. if (docs.hasOwnProperty(key)) {
  785. // undefined means no split
  786. // /\t|\n|\r| / means on whitespace
  787. // '' means on every char
  788. for(var i in seps) {
  789. sep = seps[i];
  790. it('[' + key + '] should be able to parse -> ' + sep,
  791. generic(key, false, sep));
  792. }
  793. }
  794. }
  795. });
  796. describe('#pre-chunked', function() {
  797. for (var key in docs) {
  798. if (docs.hasOwnProperty(key)) {
  799. if (!docs[key].chunks) continue;
  800. it('[' + key + '] should be able to parse pre-chunked', generic(key, true));
  801. }
  802. }
  803. });
  804. });