@vbarbarosh/node-helpers 3.75.0 → 3.76.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (369) hide show
  1. package/README.md +29 -3
  2. package/dist/browser.js +1 -2504
  3. package/dist/index.html +1 -1
  4. package/package.json +33 -12
  5. package/src/HeartbeatServer.js +24 -3
  6. package/src/HeartbeatServer.md +33 -0
  7. package/src/array_chunk.js +1 -1
  8. package/src/array_chunk.md +8 -0
  9. package/src/array_chunk_balanced.md +14 -0
  10. package/src/array_fps.md +12 -0
  11. package/src/array_gcd.js +4 -2
  12. package/src/array_gcd.md +2 -1
  13. package/src/array_group.js +3 -3
  14. package/src/array_group.md +14 -0
  15. package/src/array_group_map.js +3 -3
  16. package/src/array_group_map.md +13 -0
  17. package/src/array_index.js +2 -2
  18. package/src/array_index.md +9 -0
  19. package/src/array_lcm.js +4 -2
  20. package/src/array_lcm.md +2 -1
  21. package/src/array_max.js +11 -4
  22. package/src/array_max.md +1 -1
  23. package/src/array_min.js +11 -4
  24. package/src/array_min.md +1 -1
  25. package/src/array_permutations.js +4 -0
  26. package/src/array_permutations.md +13 -0
  27. package/src/array_sort.js +7 -2
  28. package/src/array_sort.md +13 -0
  29. package/src/array_sort_other.js +8 -5
  30. package/src/array_sort_other.md +11 -0
  31. package/src/array_sum.js +2 -2
  32. package/src/array_sum.md +8 -0
  33. package/src/array_unique.js +2 -2
  34. package/src/array_unique_last.js +2 -2
  35. package/src/assert_valid_expires_at.md +10 -0
  36. package/src/clamp.md +9 -0
  37. package/src/cli-apps/watchdog.js +5 -0
  38. package/src/cli.js +3 -1
  39. package/src/cli.md +15 -0
  40. package/src/const_stream.md +7 -0
  41. package/src/const_type.md +5 -0
  42. package/src/countdown.js +22 -5
  43. package/src/countdown.md +21 -0
  44. package/src/crypto_decrypt_aes256.md +13 -0
  45. package/src/crypto_encrypt_aes256.md +13 -0
  46. package/src/crypto_hash_md5.md +10 -0
  47. package/src/crypto_hash_sha256.md +10 -0
  48. package/src/crypto_hmac_sha256.md +11 -0
  49. package/src/date_add_hours.md +8 -0
  50. package/src/date_add_milliseconds.md +4 -0
  51. package/src/date_add_minutes.md +4 -0
  52. package/src/date_add_months.md +13 -0
  53. package/src/date_add_seconds.md +4 -0
  54. package/src/date_diff_seconds.md +4 -0
  55. package/src/date_is_leap_year.md +9 -0
  56. package/src/escape_content_disposition.js +6 -3
  57. package/src/escape_content_disposition.md +13 -0
  58. package/src/escape_regexp.md +7 -0
  59. package/src/eta.js +7 -1
  60. package/src/eta.md +18 -0
  61. package/src/factorize_ms.js +3 -0
  62. package/src/factorize_ms.md +10 -0
  63. package/src/fastdl.js +14 -3
  64. package/src/fcmp_dates.md +12 -0
  65. package/src/fcmp_default.js +7 -0
  66. package/src/fcmp_default.md +29 -0
  67. package/src/fcmp_default_desc.js +4 -7
  68. package/src/fcmp_default_desc.md +10 -0
  69. package/src/fcmp_from_spec.md +13 -0
  70. package/src/fcmp_numbers.md +11 -0
  71. package/src/fcmp_tuples.md +17 -0
  72. package/src/fcmp_utf8_bin.md +14 -0
  73. package/src/fcmp_utf8_ci.md +14 -0
  74. package/src/fcmp_utf8_cs.md +15 -0
  75. package/src/fcmp_utf8_natural_bin.js +38 -0
  76. package/src/fcmp_utf8_natural_bin.md +8 -0
  77. package/src/fcmp_utf8_natural_ci.md +13 -0
  78. package/src/fcmp_utf8_natural_cs.md +13 -0
  79. package/src/fcmpx.md +26 -9
  80. package/src/filter1_from_spec.js +3 -3
  81. package/src/format_bytes.md +15 -0
  82. package/src/format_date.md +7 -0
  83. package/src/format_date_fs.md +7 -0
  84. package/src/format_date_human.md +6 -0
  85. package/src/format_date_ymd.md +6 -0
  86. package/src/format_error_report.js +3 -3
  87. package/src/format_error_report.md +12 -0
  88. package/src/format_kilo.md +13 -0
  89. package/src/format_ms.js +3 -2
  90. package/src/format_ms.md +12 -0
  91. package/src/format_ms2.js +6 -3
  92. package/src/format_ms2.md +12 -0
  93. package/src/format_ms3.js +3 -2
  94. package/src/format_ms3.md +12 -0
  95. package/src/format_percents.md +10 -0
  96. package/src/format_progress_bytes.md +13 -0
  97. package/src/format_progress_kilo.md +10 -0
  98. package/src/format_seconds.md +11 -0
  99. package/src/format_thousands.md +9 -0
  100. package/src/fs_append.md +7 -0
  101. package/src/fs_append_json.md +8 -0
  102. package/src/fs_append_utf8.md +6 -0
  103. package/src/fs_assert_file_exists.md +3 -0
  104. package/src/fs_assert_file_readable.js +1 -1
  105. package/src/fs_assert_file_readable.md +3 -0
  106. package/src/fs_assert_file_socket.md +2 -0
  107. package/src/fs_copy.md +7 -0
  108. package/src/fs_copy_excl.md +2 -0
  109. package/src/fs_exists.md +6 -0
  110. package/src/fs_fclose.md +5 -0
  111. package/src/fs_fi.js +13 -1
  112. package/src/fs_fi.md +11 -0
  113. package/src/fs_file_md5.md +8 -0
  114. package/src/fs_find.md +7 -0
  115. package/src/fs_fopen.md +6 -0
  116. package/src/fs_fread.js +2 -2
  117. package/src/fs_fread.md +11 -0
  118. package/src/fs_fsize.md +2 -0
  119. package/src/fs_fstat.md +2 -0
  120. package/src/fs_fwrite.js +2 -2
  121. package/src/fs_fwrite.md +9 -0
  122. package/src/fs_list.md +5 -0
  123. package/src/fs_list_deep.md +5 -0
  124. package/src/fs_ls.md +2 -0
  125. package/src/fs_lsr.md +4 -0
  126. package/src/fs_lstat.md +3 -0
  127. package/src/fs_mkdir.md +3 -0
  128. package/src/fs_mkdirp.js +3 -30
  129. package/src/fs_mkdirp.md +7 -0
  130. package/src/fs_path_basename.md +2 -0
  131. package/src/fs_path_dirname.md +2 -0
  132. package/src/fs_path_extname.md +9 -0
  133. package/src/fs_path_join.md +2 -0
  134. package/src/fs_path_relative.md +2 -0
  135. package/src/fs_path_resolve.md +2 -0
  136. package/src/fs_path_tempdir.md +2 -0
  137. package/src/fs_path_untildify.md +8 -0
  138. package/src/fs_read.md +3 -0
  139. package/src/fs_read_buffer.md +5 -0
  140. package/src/fs_read_json.md +6 -0
  141. package/src/fs_read_lines.md +7 -0
  142. package/src/fs_read_stream.md +2 -0
  143. package/src/fs_read_utf8.md +5 -0
  144. package/src/fs_readdir.md +3 -0
  145. package/src/fs_readlink.md +6 -0
  146. package/src/fs_rename.md +6 -0
  147. package/src/fs_rm.md +4 -0
  148. package/src/fs_rmdir.md +3 -0
  149. package/src/fs_rmf.md +2 -0
  150. package/src/fs_rmrf.md +8 -0
  151. package/src/fs_sha256.js +16 -0
  152. package/src/fs_sha256.md +9 -0
  153. package/src/fs_size.js +2 -2
  154. package/src/fs_size.md +6 -0
  155. package/src/fs_stat.md +2 -0
  156. package/src/fs_tempdir.js +20 -5
  157. package/src/fs_touch.md +6 -0
  158. package/src/fs_walk.js +2 -2
  159. package/src/fs_walk.md +14 -0
  160. package/src/fs_write.md +3 -0
  161. package/src/fs_write_json.md +7 -0
  162. package/src/fs_write_stream.md +2 -0
  163. package/src/gettype.md +13 -0
  164. package/src/http_delete.md +11 -0
  165. package/src/http_get_blob.md +8 -0
  166. package/src/http_get_buffer.md +10 -0
  167. package/src/http_get_file.js +8 -8
  168. package/src/http_get_file.md +14 -0
  169. package/src/http_get_json.md +10 -0
  170. package/src/http_get_stream.md +14 -0
  171. package/src/http_get_stream_range.js +27 -9
  172. package/src/http_get_stream_range.md +22 -0
  173. package/src/http_get_utf8.md +9 -0
  174. package/src/http_head.md +9 -0
  175. package/src/http_patch_json.md +10 -0
  176. package/src/http_post_json.md +11 -0
  177. package/src/http_post_multipart.md +15 -0
  178. package/src/http_post_urlencoded.md +11 -0
  179. package/src/http_put_buffer.md +9 -0
  180. package/src/http_put_file.js +9 -6
  181. package/src/http_put_file.md +16 -0
  182. package/src/http_put_json.md +11 -0
  183. package/src/http_put_utf8.md +9 -0
  184. package/src/http_range_parse.js +6 -3
  185. package/src/http_range_parse.md +18 -0
  186. package/src/http_stream_range.js +35 -22
  187. package/src/http_stream_range.md +29 -0
  188. package/src/identity.md +2 -0
  189. package/src/ignore.md +2 -0
  190. package/src/json_stringify_safe.md +10 -0
  191. package/src/json_stringify_stable.md +9 -0
  192. package/src/logger.js +2 -3
  193. package/src/logger.md +15 -0
  194. package/src/make_progress.js +8 -5
  195. package/src/make_progress.md +20 -0
  196. package/src/math_gcd.js +2 -1
  197. package/src/mongo_stream_upsert.js +10 -3
  198. package/src/mongo_stream_upsert.md +17 -0
  199. package/src/mongo_stream_write.js +10 -3
  200. package/src/mongo_stream_write.md +16 -0
  201. package/src/msval.md +10 -0
  202. package/src/now_fs.md +7 -0
  203. package/src/now_human.md +6 -0
  204. package/src/object_defaults.md +11 -0
  205. package/src/object_schema.js +2 -1
  206. package/src/object_schema.md +12 -0
  207. package/src/object_walk_preorder.md +16 -0
  208. package/src/parallel.js +23 -10
  209. package/src/parse_bytes.js +4 -2
  210. package/src/parse_bytes.md +15 -0
  211. package/src/parse_hms.js +1 -1
  212. package/src/parse_http_content_range.js +9 -5
  213. package/src/parse_http_content_range.md +16 -0
  214. package/src/perf_end_human.md +10 -0
  215. package/src/perf_end_ms.md +8 -0
  216. package/src/perf_measure.md +10 -0
  217. package/src/perf_measure_human.md +8 -0
  218. package/src/perf_start.md +9 -0
  219. package/src/pgid_exists.md +6 -0
  220. package/src/pgid_kill_grace.js +1 -1
  221. package/src/pgid_kill_grace.md +15 -0
  222. package/src/pid_exists.md +5 -0
  223. package/src/pid_kill_grace.js +1 -1
  224. package/src/pid_kill_grace.md +14 -0
  225. package/src/plural.md +13 -0
  226. package/src/random_hex.md +9 -0
  227. package/src/random_int.md +8 -0
  228. package/src/range.js +4 -2
  229. package/src/range.md +2 -0
  230. package/src/redis_connect.js +1 -1
  231. package/src/redis_connect.md +10 -0
  232. package/src/redis_lshift.md +14 -0
  233. package/src/redis_poll.js +1 -0
  234. package/src/redis_poll.md +17 -0
  235. package/src/redis_poll_zshift_callback_rpush.js +1 -2
  236. package/src/redis_poll_zshift_callback_rpush.md +17 -0
  237. package/src/redis_poll_zshift_spawn_rpush.js +2 -1
  238. package/src/redis_poll_zshift_spawn_rpush.md +20 -0
  239. package/src/redis_zshift.md +14 -0
  240. package/src/round.js +7 -8
  241. package/src/round.md +15 -0
  242. package/src/sanitize_dash_name.md +13 -0
  243. package/src/sanitize_filename.md +9 -0
  244. package/src/sanitize_var_name.md +14 -0
  245. package/src/sftp_get_file_info.js +2 -2
  246. package/src/sftp_get_file_info.md +14 -0
  247. package/src/sftp_get_stream_range.js +32 -22
  248. package/src/sftp_get_stream_range.md +20 -0
  249. package/src/shell_curl_progress.js +2 -1
  250. package/src/shell_curl_progress.md +17 -0
  251. package/src/shell_lines.js +2 -2
  252. package/src/shell_lines.md +1 -1
  253. package/src/shell_spawn.js +7 -0
  254. package/src/shell_ytdlp_progress.js +2 -1
  255. package/src/shell_ytdlp_progress.md +17 -0
  256. package/src/str_camel_to_snake.md +11 -0
  257. package/src/str_parse_kv.md +11 -0
  258. package/src/stream_curl_progress.md +14 -0
  259. package/src/stream_data_ln.js +7 -1
  260. package/src/stream_discard.md +8 -0
  261. package/src/stream_group.md +3 -0
  262. package/src/stream_gunzip.md +7 -0
  263. package/src/stream_hash.md +10 -0
  264. package/src/stream_map.js +8 -1
  265. package/src/stream_map_parallel.js +9 -1
  266. package/src/stream_md5.md +9 -0
  267. package/src/stream_multiplex.js +11 -0
  268. package/src/stream_multiplex.md +16 -0
  269. package/src/stream_through.md +3 -0
  270. package/src/stream_transform.md +2 -0
  271. package/src/stream_xml_analyze.js +9 -1
  272. package/src/stream_xml_parse.js +9 -1
  273. package/src/stream_ytdlp_progress.js +1 -1
  274. package/src/stream_ytdlp_progress.md +18 -0
  275. package/src/strtr.js +15 -5
  276. package/src/strtr.md +11 -0
  277. package/src/urlclean.js +9 -2
  278. package/src/urlmod.js +22 -11
  279. package/src/urlmod.md +15 -3
  280. package/src/urlparts.md +17 -0
  281. package/src/wait_while.js +1 -1
  282. package/src/wait_while.md +1 -1
  283. package/src/HeartbeatServer.test.js +0 -31
  284. package/src/array_chunk.test.js +0 -24
  285. package/src/array_chunk_balanced.test.js +0 -37
  286. package/src/array_fps.test.js +0 -72
  287. package/src/array_gcd.test.js +0 -10
  288. package/src/array_index.test.js +0 -14
  289. package/src/array_lcm.test.js +0 -12
  290. package/src/array_max.test.js +0 -20
  291. package/src/array_min.test.js +0 -20
  292. package/src/array_permutations.test.js +0 -20
  293. package/src/array_sort.test.js +0 -85
  294. package/src/array_sort_other.test.js +0 -9
  295. package/src/array_sum.test.js +0 -11
  296. package/src/cli-apps/watchdog.d/connect_close.js +0 -17
  297. package/src/cli-apps/watchdog.d/connect_close2.js +0 -20
  298. package/src/cli-apps/watchdog.d/connect_close3.js +0 -25
  299. package/src/cli-apps/watchdog.d/connect_no_ping.js +0 -13
  300. package/src/cli-apps/watchdog.d/early_exit.js +0 -7
  301. package/src/cli-apps/watchdog.d/flood.js +0 -13
  302. package/src/cli-apps/watchdog.d/flood2.js +0 -15
  303. package/src/cli-apps/watchdog.d/hang.js +0 -8
  304. package/src/cli-apps/watchdog.d/huge_delay.js +0 -18
  305. package/src/cli-apps/watchdog.d/ignore_sigterm.js +0 -29
  306. package/src/cli-apps/watchdog.d/late_heartbeat.js +0 -21
  307. package/src/cli-apps/watchdog.d/my-exit-after-2-pings.js +0 -16
  308. package/src/cli-apps/watchdog.d/my-happy-path.js +0 -16
  309. package/src/cli-apps/watchdog.d/my-ignore-sigterm.js +0 -22
  310. package/src/cli-apps/watchdog.d/my-never-ping.js +0 -15
  311. package/src/cli-apps/watchdog.d/no_heartbeat.js +0 -5
  312. package/src/cli-apps/watchdog.d/ok.js +0 -17
  313. package/src/cli-apps/watchdog.d/quick-exit-after-2-pings.js +0 -15
  314. package/src/cli-apps/watchdog.d/quick-hang-after-1-ping.js +0 -15
  315. package/src/cli-apps/watchdog.d/spawn_children.js +0 -14
  316. package/src/cli-apps/watchdog.test.js +0 -48
  317. package/src/crypto_encrypt_aes256.test.js +0 -10
  318. package/src/crypto_hash_sha256.test.js +0 -10
  319. package/src/date_add_months.test.js +0 -40
  320. package/src/date_is_leap_year.test.js +0 -14
  321. package/src/escape_content_disposition.test.js +0 -22
  322. package/src/fcmp_from_spec.test.js +0 -91
  323. package/src/fcmpx.test.js +0 -173
  324. package/src/filter1_from_spec.test.js +0 -31
  325. package/src/format_bytes.test.js +0 -22
  326. package/src/format_error_report.d/src/1.js +0 -26
  327. package/src/format_error_report.d/src/2.js +0 -29
  328. package/src/format_kilo.test.js +0 -25
  329. package/src/format_ms.test.js +0 -33
  330. package/src/format_ms2.test.js +0 -33
  331. package/src/format_ms3.test.js +0 -33
  332. package/src/format_percents.test.js +0 -22
  333. package/src/format_progress_bytes.test.js +0 -19
  334. package/src/format_progress_kilo.test.js +0 -19
  335. package/src/format_seconds.test.js +0 -42
  336. package/src/format_thousands.test.js +0 -28
  337. package/src/fs_file_md5.test.js +0 -11
  338. package/src/fs_mkdirp.test.js +0 -24
  339. package/src/fs_path_extname.test.js +0 -22
  340. package/src/gettype.test.js +0 -27
  341. package/src/object_schema.test.js +0 -15
  342. package/src/object_walk_preorder.test.js +0 -17
  343. package/src/parallel.test.js +0 -11
  344. package/src/parse_bytes.test.js +0 -21
  345. package/src/parse_hms.test.js +0 -32
  346. package/src/parse_http_content_range.test.js +0 -14
  347. package/src/pid_kill_grace.d/ignore-sigterm-for-10ms.js +0 -33
  348. package/src/pid_kill_grace.d/ignore-sigterm.js +0 -22
  349. package/src/pid_kill_grace.test.js +0 -63
  350. package/src/ping_socket.test.js +0 -58
  351. package/src/plural.test.js +0 -20
  352. package/src/range.test.js +0 -41
  353. package/src/redis_lshift.test.js +0 -57
  354. package/src/redis_zshift.test.js +0 -58
  355. package/src/round.test.js +0 -56
  356. package/src/sanitize_dash_name.test.js +0 -59
  357. package/src/sanitize_var_name.test.js +0 -39
  358. package/src/shell_spawn.test.js +0 -30
  359. package/src/str_camel_to_snake.test.js +0 -17
  360. package/src/stream_curl_progress.d/basic +0 -3
  361. package/src/stream_curl_progress.d/basic.json +0 -42
  362. package/src/stream_curl_progress.test.js +0 -17
  363. package/src/stream_data_ln.test.js +0 -24
  364. package/src/stream_map_parallel.test.js +0 -26
  365. package/src/stream_multiplex.test.js +0 -67
  366. package/src/stream_strpbrk.test.js +0 -29
  367. package/src/urlclean.test.js +0 -18
  368. package/src/urlmod.test.js +0 -40
  369. package/src/urlparts.test.js +0 -294
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const Promise = require('bluebird');
4
- const cli = require('../../cli');
5
- const ping_socket = require('../../ping_socket');
6
-
7
- cli(main);
8
-
9
- async function main()
10
- {
11
- await ping_socket(process.env.WATCHDOG_SOCKET);
12
- while (true) {
13
- await Promise.delay(1000);
14
- }
15
- }
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // ❌ 6. Client that spawns children
4
- // This tests your process group killing.
5
- // If watchdog does not kill the entire group, the sleeps will remain after watchdog exits.
6
-
7
- const {spawn} = require('child_process');
8
-
9
- spawn('sleep', ['9999'], {detached: false});
10
- spawn('sleep', ['9999'], {detached: false});
11
-
12
- console.log('spawned 2 children');
13
-
14
- setInterval(() => {}, 1000);
@@ -1,48 +0,0 @@
1
- const assert = require('assert');
2
- const pid_exists = require('../pid_exists');
3
- const shell_spawn = require('../shell_spawn');
4
- const stream = require('stream');
5
- const stream_each = require('../stream_each');
6
- const stream_lines = require('../stream_lines');
7
-
8
- // watchdog true -> race condition; true exists too quickly; bug in shell_spawn
9
-
10
- describe('watchdog', function () {
11
- this.timeout(1000);
12
- it('Happy Path', async function () {
13
- const env = {...process.env, WATCHDOG_INTERVAL: 100, __TESTING__: 1};
14
- const proc = shell_spawn([`${__dirname}/watchdog.js`, `${__dirname}/watchdog.d/quick-exit-after-2-pings.js`], {env});
15
- try {
16
- const stdout = [];
17
- await Promise.all([
18
- stream.promises.pipeline(proc.stdout, stream_lines(), stream_each(v => stdout.push(v))),
19
- proc.promise(),
20
- ]);
21
- assert.strictEqual(stdout.filter(v => v.includes('[watchdog_ping]')).length, 2);
22
- assert.strictEqual(stdout.filter(v => v.includes('[watchdog_end_ok] pings=2')).length, 1);
23
- }
24
- finally {
25
- if (pid_exists(proc.pid)) {
26
- process.kill(proc.pid, 'SIGTERM');
27
- }
28
- }
29
- });
30
- it('Hang after 1 ping', async function () {
31
- const env = {...process.env, WATCHDOG_INTERVAL: 100, __TESTING__: 1};
32
- const proc = shell_spawn([`${__dirname}/watchdog.js`, `${__dirname}/watchdog.d/quick-hang-after-1-ping.js`], {env});
33
- const stdout = [];
34
- try {
35
- await Promise.all([
36
- stream.promises.pipeline(proc.stdout, stream_lines(), stream_each(v => stdout.push(v))),
37
- assert.rejects(proc.promise().timeout(500), {message: 'Process terminated with code 124 and signal null'}),
38
- ]);
39
- assert.strictEqual(stdout.filter(v => v.includes('[watchdog_ping]')).length, 1);
40
- assert.strictEqual(stdout.filter(v => v.includes('[watchdog_end_error] pings=1 | No heartbeat for the last 100ms')).length, 1);
41
- }
42
- finally {
43
- if (pid_exists(proc.pid)) {
44
- process.kill(proc.pid, 'SIGTERM');
45
- }
46
- }
47
- });
48
- });
@@ -1,10 +0,0 @@
1
- const assert = require('assert');
2
- const crypto_decrypt_aes256 = require('./crypto_decrypt_aes256');
3
- const crypto_encrypt_aes256 = require('./crypto_encrypt_aes256');
4
-
5
- describe('crypto_encrypt_aes256', function () {
6
- it('should handle basic input', function () {
7
- const password = 'pass123';
8
- assert.deepStrictEqual(crypto_decrypt_aes256(password, crypto_encrypt_aes256(password, 'hello')).toString('utf8'), 'hello');
9
- });
10
- });
@@ -1,10 +0,0 @@
1
- const assert = require('assert');
2
- const crypto_hash_sha256 = require('./crypto_hash_sha256');
3
-
4
- describe('crypto_hash_sha256', function () {
5
- it('should handle basic input', function () {
6
- assert.deepStrictEqual(crypto_hash_sha256('').toString('hex'), 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
7
- assert.deepStrictEqual(crypto_hash_sha256('1').toString('hex'), '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b');
8
- assert.deepStrictEqual(crypto_hash_sha256('hello').toString('hex'), '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824');
9
- });
10
- });
@@ -1,40 +0,0 @@
1
- const assert = require('assert');
2
- const date_add_months = require('./date_add_months');
3
- const format_date_ymd = require('./format_date_ymd');
4
-
5
- const items = [
6
- ['2024/12/24', '2024/12/24', 0],
7
- ['2024/12/24', '2025/01/24', 1],
8
- ['2024/12/24', '2024/11/24', -1],
9
- ['2012/01/14', '2011/10/14', -3],
10
- ['2019/03/31', '2019/02/28', -1],
11
- ['2023/01/15', '2023/04/15', 3, 'Basic Positive Addition'],
12
- ['2023/05/15', '2023/03/15', -2, 'Basic Negative Addition'],
13
- ['2023/10/15', '2024/03/15', 5, 'Year Crossover (Positive)'],
14
- ['2023/03/15', '2022/10/15', -5, 'Year Crossover (Negative)'],
15
- ['2024/02/29', '2025/02/28', 12, 'Leap Year - Adding Months in Leap Year'],
16
- ['2024/03/01', '2023/03/01', -12, 'Negative Leap Year Crossover'],
17
- ['2023/01/31', '2023/02/28', 1, 'End of Month (31st to Shorter Month)'],
18
- ['2023/03/31', '2023/02/28', -1, 'End of Month Crossover (Negative)'],
19
- ['2023/06/15', '2023/06/15', 0, 'Zero Months Added'],
20
- ['2023/01/01', '2033/01/01', 120, 'Large Positive Addition'],
21
- ['2023/01/01', '2013/01/01', -120, 'Large Negative Addition'],
22
- ['2020/02/29', '2024/02/29', 48, 'Multiple Leap Years'],
23
- ['2023/12/15', '2024/01/15', 1, 'Adding to December'],
24
- ['2023/01/15', '2022/12/15', -1, 'Subtracting from January'],
25
- ['2023/05/31', '2023/06/30', 1, 'Day Preservation with Shorter Month'],
26
- ['2023/02/28', '2024/02/28', 12, 'Adding Months to February (Non-Leap Year)'],
27
- ['2024/03/01', '2023/02/01', -13, 'Negative Months Across Leap Year'],
28
- ['2000/01/01', '2030/01/01', 360, 'Multiple Decades'],
29
- ['1970/01/01', '2020/01/01', 600, 'Edge Case: Epoch Date'],
30
- ['3000/01/01', '2900/01/01', -1200, 'Far Future Date']
31
- ];
32
-
33
- describe('date_add_months', function () {
34
- items.forEach(function ([input, expected, months, message]) {
35
- it(`${input} → ${expected}`, function () {
36
- const d = date_add_months(new Date(input), months);
37
- assert.strictEqual(format_date_ymd(d), expected, message);
38
- });
39
- });
40
- });
@@ -1,14 +0,0 @@
1
- const assert = require('assert');
2
- const date_is_leap_year = require('./date_is_leap_year');
3
-
4
- describe('date_add_months', function () {
5
- it('Brute force', function () {
6
- for (let year = 100; year < 9999; ++year) {
7
- const d = new Date(`${year}/01/01 00:00:00`);
8
- const d2 = new Date(`${year}/02/29 00:00:00`);
9
- assert.strictEqual(d.getFullYear(), year);
10
- assert.strictEqual(d2.getFullYear(), year);
11
- assert.strictEqual(date_is_leap_year(d), d2.getMonth() === 1, year);
12
- }
13
- });
14
- });
@@ -1,22 +0,0 @@
1
- const assert = require('assert');
2
- const escape_content_disposition = require('./escape_content_disposition');
3
-
4
- const items = [
5
- ['foo.bar', 'foo.bar'],
6
- ['foo"bar', 'foo\\"bar'],
7
- ['foo;bar', '"foo;bar"'],
8
- ['foo%bar', 'foo\\%bar'],
9
- ['foo\\bar', 'foo\\\\bar'],
10
- ['foo\nbar', 'foo%x0Abar'],
11
- ['foo\0bar', 'foo%x00bar'],
12
- ['foo bar', '"foo bar"'],
13
- ['foo "bar".txt', '"foo \\"bar\\".txt"'],
14
- ];
15
-
16
- describe('escape_content_disposition', function () {
17
- items.forEach(function ([input, expected]) {
18
- it(`${input} → ${expected}`, function () {
19
- assert.strictEqual(escape_content_disposition(input), expected);
20
- });
21
- });
22
- });
@@ -1,91 +0,0 @@
1
- const assert = require('assert');
2
- const fcmp_from_spec = require('./fcmp_from_spec');
3
-
4
- describe('fcmp_from_spec', function () {
5
- it('basic [id] • sort by id (asc)', function () {
6
- const actual = [
7
- {id: 3, name: 'Banana', price: 8.25},
8
- {id: 1, name: 'Apple', price: 10.99},
9
- {id: 2, name: 'Cherry', price: 15.49},
10
- ];
11
- actual.sort(fcmp_from_spec(['id']));
12
- const expected = [
13
- {id: 1, name: 'Apple', price: 10.99},
14
- {id: 2, name: 'Cherry', price: 15.49},
15
- {id: 3, name: 'Banana', price: 8.25},
16
- ];
17
- assert.deepStrictEqual(actual, expected);
18
- });
19
- it('basic [-id] • sort by id (desc)', function () {
20
- const actual = [
21
- {id: 3, name: 'Banana', price: 8.25},
22
- {id: 1, name: 'Apple', price: 10.99},
23
- {id: 2, name: 'Cherry', price: 15.49},
24
- ];
25
- actual.sort(fcmp_from_spec(['-id']));
26
- const expected = [
27
- {id: 3, name: 'Banana', price: 8.25},
28
- {id: 2, name: 'Cherry', price: 15.49},
29
- {id: 1, name: 'Apple', price: 10.99},
30
- ];
31
- assert.deepStrictEqual(actual, expected);
32
- });
33
- it('basic [name] • sort by name (asc)', function () {
34
- const actual = [
35
- {id: 3, name: 'Banana', price: 8.25},
36
- {id: 1, name: 'Apple', price: 10.99},
37
- {id: 2, name: 'Cherry', price: 15.49},
38
- ];
39
- actual.sort(fcmp_from_spec(['name']));
40
- const expected = [
41
- {id: 1, name: 'Apple', price: 10.99},
42
- {id: 3, name: 'Banana', price: 8.25},
43
- {id: 2, name: 'Cherry', price: 15.49},
44
- ];
45
- assert.deepStrictEqual(actual, expected);
46
- });
47
- it('basic [-name] • sort by name (desc)', function () {
48
- const actual = [
49
- {id: 3, name: 'Banana', price: 8.25},
50
- {id: 1, name: 'Apple', price: 10.99},
51
- {id: 2, name: 'Cherry', price: 15.49},
52
- ];
53
- actual.sort(fcmp_from_spec(['-name']));
54
- const expected = [
55
- {id: 2, name: 'Cherry', price: 15.49},
56
- {id: 3, name: 'Banana', price: 8.25},
57
- {id: 1, name: 'Apple', price: 10.99},
58
- ];
59
- assert.deepStrictEqual(actual, expected);
60
- });
61
- it('compound [price,name] • sort by price (asc), name (asc)', function () {
62
- const actual = [
63
- {id: 1, name: 'Apple', price: 10.99},
64
- {id: 2, name: 'Cherry', price: 10.99},
65
- {id: 3, name: 'Banana', price: 8.25},
66
- ];
67
- actual.sort(fcmp_from_spec(['price', 'name']));
68
- const expected = [
69
- {id: 3, name: 'Banana', price: 8.25},
70
- {id: 1, name: 'Apple', price: 10.99},
71
- {id: 2, name: 'Cherry', price: 10.99},
72
- ];
73
- assert.deepStrictEqual(actual, expected);
74
- });
75
- it('compound [-price,name,id] • sort by price (desc), name (asc), id (asc)', function () {
76
- const actual = [
77
- {id: 1, name: 'Apple', price: 10.99},
78
- {id: 2, name: 'Cherry', price: 15.49},
79
- {id: 3, name: 'Banana', price: 8.25},
80
- {id: 4, name: 'Banana', price: 8.25},
81
- ];
82
- actual.sort(fcmp_from_spec(['-price', 'name', 'id']));
83
- const expected = [
84
- {id: 2, name: 'Cherry', price: 15.49},
85
- {id: 1, name: 'Apple', price: 10.99},
86
- {id: 3, name: 'Banana', price: 8.25},
87
- {id: 4, name: 'Banana', price: 8.25},
88
- ];
89
- assert.deepStrictEqual(actual, expected);
90
- });
91
- });
package/src/fcmpx.test.js DELETED
@@ -1,173 +0,0 @@
1
- const assert = require('assert');
2
- const fcmpx = require('./fcmpx');
3
-
4
- const users = [
5
- {id: 'fred|48|100', user: {name: 'fred', age: 48, balance: 100}},
6
- {id: 'barney|36|-200', user: {name: 'barney', age: 36, balance: -200}},
7
- {id: 'wilma|-|-', user: {name: 'wilma', tag: {short: 'foo', long: 'foofoo'}}},
8
- {id: 'betty|32|-', user: {name: 'betty', tag: {short: 'bar', long: 'barbar'}, age: 32}},
9
- ];
10
-
11
- // https://dummyjson.com/docs/products
12
-
13
- const products = [
14
- {id: 1, name: 'Yoga Mat', category: 'Yoga', price: 25.99, brand: 'BalanceFrom', rating: 4.6, discount: 0.1, availability: 'in_stock'},
15
- {id: 2, name: 'Adjustable Dumbbells', category: 'Strength', price: 199.99, brand: 'Bowflex', rating: 4.8, availability: 'preorder'},
16
- {id: 3, name: 'Resistance Bands Set', category: 'Strength', price: 32.5, brand: 'Fit Simplify', rating: 4.5, discount: 0.15, availability: 'in_stock'},
17
- {id: 4, name: 'Treadmill', category: 'Cardio', price: 899, brand: 'NordicTrack', rating: 4.7, availability: 'out_of_stock'},
18
- {id: 5, name: 'Kettlebell 20lb', category: 'Strength', price: 45, brand: 'CAP Barbell', rating: 4.4, discount: 0.05, availability: 'in_stock'},
19
- {id: 6, name: 'Foam Roller', category: 'Recovery', price: 19.99, brand: 'TriggerPoint', rating: 4.6, availability: 'limited'},
20
- {id: 7, name: 'Exercise Bike', category: 'Cardio', price: 599, brand: 'Peloton', rating: 4.9, discount: 0.2, availability: 'in_stock'},
21
- {id: 8, name: 'Pull-Up Bar', category: 'Strength', price: 29.95, brand: 'Iron Gym', rating: 4.3, availability: 'in_stock'},
22
- {id: 9, name: 'Jump Rope', category: 'Cardio', price: 12.99, brand: 'WOD Nation', rating: 4.2, discount: 0.25, availability: 'limited'},
23
- {id: 10, name: 'Ab Roller', category: 'Core', price: 21.49, brand: 'Perfect Fitness', rating: 4.5, availability: 'in_stock'},
24
- ];
25
-
26
- const tests = [
27
- {
28
- description: 'missing: should move undefined values to the bottom',
29
- items: [
30
- {id: 'user1', user: {age: 48}},
31
- {id: 'user2', user: {age: 36}},
32
- {id: 'user3'},
33
- {id: 'user4', user: {age: 32}},
34
- ],
35
- extract: v => v.id,
36
- expressions: [
37
- 'user.age',
38
- v => v.user?.age,
39
- {read: 'user.age'},
40
- {read: v => v.user?.age},
41
- ['user.age'],
42
- [v => v.user?.age],
43
- [{read: 'user.age'}],
44
- [{read: v => v.user?.age}],
45
- ],
46
- expected: ['user4', 'user2', 'user1', 'user3'],
47
- },
48
- {
49
- description: 'missing: should move undefined values to the bottom #2',
50
- items: [
51
- {id: 'user1', user: {age: 48}},
52
- {id: 'user2', user: {age: 36}},
53
- {id: 'user3', user: {tag: {short: 'foo'}}},
54
- {id: 'user4', user: {tag: {short: 'bar'}, age: 32}},
55
- ],
56
- extract: v => v.id,
57
- expressions: [
58
- 'user.age,user.tag.short',
59
- ['user.age', 'user.tag.short'],
60
- [v => v.user.age, v => v.user.tag?.short],
61
- [{read: 'user.age'}, {read: 'user.tag.short'}],
62
- [{read: v => v.user.age}, {read: v => v.user.tag?.short}],
63
- ],
64
- expected: ['user4', 'user2', 'user1', 'user3'],
65
- },
66
- {
67
- description: 'missing: should move undefined values to the bottom and keep their initial order',
68
- items: [
69
- {id: 'user1', user: {balance: 100}},
70
- {id: 'user2', user: {balance: -200}},
71
- {id: 'user3'},
72
- {id: 'user4'},
73
- ],
74
- extract: v => v.id,
75
- expressions: [
76
- 'user.balance',
77
- v => v.user?.balance,
78
- [v => v.user?.balance],
79
- ],
80
- expected: ['user2', 'user1', 'user3', 'user4'],
81
- },
82
- {
83
- description: 'move undefined value to the bottom, keep their initial order',
84
- items: users,
85
- extract: v => v.id,
86
- expressions: [
87
- 'user.balance,user.age',
88
- [v => v.user.balance, v => v.user.age],
89
- ],
90
- expected: ['barney|36|-200', 'fred|48|100', 'betty|32|-', 'wilma|-|-'],
91
- },
92
- {
93
- description: 'move undefined value to the bottom, keep their initial order',
94
- items: users,
95
- extract: v => v.id,
96
- expressions: [
97
- 'user.balance,user.age',
98
- [v => v.user.balance, v => v.user.age],
99
- ],
100
- expected: ['barney|36|-200', 'fred|48|100', 'betty|32|-', 'wilma|-|-'],
101
- },
102
- {
103
- description: 'user.tag.short',
104
- items: [
105
- {user: {name: 'fred', age: 48}},
106
- {user: {name: 'barney', age: 36}},
107
- {user: {name: 'wilma', tag: {short: 'foo'}}},
108
- {user: {name: 'betty', tag: {short: 'bar'}, age: 32}},
109
- ],
110
- extract: v => `${v.user.name}|${v.user.tag?.short ?? '-'}`,
111
- expressions: [
112
- 'user.tag.short',
113
- v => v.user.tag?.short,
114
- [v => v.user.tag?.short],
115
- ],
116
- expected: ['betty|bar', 'wilma|foo', 'fred|-', 'barney|-'],
117
- },
118
- {
119
- description: 'user.tag.short,user.age',
120
- items: [
121
- {user: {name: 'fred', age: 48}},
122
- {user: {name: 'barney', age: 36}},
123
- {user: {name: 'wilma', tag: {short: 'foo'}}},
124
- {user: {name: 'betty', tag: {short: 'bar'}, age: 32}},
125
- ],
126
- extract: v => `${v.user.name}|${v.user.tag?.short ?? ''}|${v.user.age ?? ''}`,
127
- expressions: [
128
- 'user.tag.short,user.age',
129
- ['user.tag.short', 'user.age'],
130
- [v => v.user.tag?.short, v => v.user.age],
131
- ],
132
- expected: ['betty|bar|32', 'wilma|foo|', 'barney||36', 'fred||48'],
133
- },
134
- {
135
- description: 'top: move specified values to the top',
136
- items: [
137
- {id: 'task1', priority: 'normal'},
138
- {id: 'task2', priority: 'low'},
139
- {id: 'task3', priority: 'high'},
140
- {id: 'task4', priority: 'normal'},
141
- ],
142
- extract: v => `${v.id}:${v.priority}`,
143
- expressions: [
144
- {read: 'priority', top: ['high']},
145
- ],
146
- expected: ['task3:high', 'task1:normal', 'task2:low', 'task4:normal'],
147
- },
148
- {
149
- description: 'top: move specified values to the top #2',
150
- items: [
151
- {id: 'task1', priority: 'normal'},
152
- {id: 'task2', priority: 'low'},
153
- {id: 'task3', priority: 'high'},
154
- {id: 'task4', priority: 'normal'},
155
- ],
156
- extract: v => `${v.id}:${v.priority}`,
157
- expressions: [
158
- {read: 'priority', top: ['high', 'normal', 'low']},
159
- ],
160
- expected: ['task3:high', 'task1:normal', 'task4:normal', 'task2:low'],
161
- },
162
- ];
163
-
164
- describe('fcmpx', function () {
165
- tests.forEach(function (test) {
166
- test.expressions.forEach(function (expr, i) {
167
- it(`${test.description}: #${i + 1} | ${test.description}`, function () {
168
- const actual = test.items.slice().sort(fcmpx(expr)).map(test.extract);
169
- assert.deepStrictEqual(actual, test.expected);
170
- });
171
- });
172
- });
173
- });
@@ -1,31 +0,0 @@
1
- const assert = require('assert');
2
- const filter1_from_spec = require('./filter1_from_spec');
3
-
4
- const scenarios = [
5
- // Format: [spec, input, expected, description]
6
- ['substr', 'this is a substr example', true, 'Single substring match'],
7
- ['^start', 'start of the string', true, 'Starts with substring'],
8
- ['end$', 'this is the end', true, 'Ends with substring'],
9
- ['!foo', 'this string does not contain it', true, 'Does not contain substring'],
10
- ['^start/end$', 'start and end', true, 'Starts and ends with substrings'],
11
- ['substr1/substr2', 'contains substr1 and substr2', true, 'Two matches'],
12
- ['substr1/substr2/substr3', 'contains substr1, substr2, and substr3', true, 'Three matches'],
13
- ['substr1/substr2/substr3/substr4', 'contains substr1, substr2, substr3, and substr4', true, 'Four matches'],
14
- ['substr1/substr2/substr3/substr4/substr5', 'contains substr1, substr2, substr3, substr4, substr5', true, 'Five matches'],
15
- ['!not1/!not2', 'this string avoids nota and notb', true, 'Does not contain multiple substrings'],
16
- ['^start1/^start2', 'start1 followed by start2', false, 'Conflicting start substrings'],
17
- ['end1$/end2$', 'ends with end1 or end2', false, 'Conflicting end substrings'],
18
- ['^start1/!substr1', 'start1 without substr', true, 'Starts with start1 and have no substr1'],
19
- ['substr/!not', 'contains substr but no ...', true, 'Combination of positive and negative substrings'],
20
- ['!missing', 'this string does not mention it', true, 'Negative substring absent'],
21
- ['missing', 'this string does not mention it', false, 'Substring missing']
22
- ];
23
-
24
- describe('filter1_from_spec', function () {
25
- scenarios.forEach(function ([spec, input, expected, description]) {
26
- it(`${description || spec}`, function () {
27
- const filter = filter1_from_spec(spec);
28
- assert.strictEqual(filter(input), expected, description);
29
- });
30
- });
31
- });
@@ -1,22 +0,0 @@
1
- const assert = require('assert');
2
- const format_bytes = require('./format_bytes');
3
-
4
- const items = [
5
- ['', 'n/a'],
6
- [null, 'n/a'],
7
- [undefined, 'n/a'],
8
- [0, '0KB'],
9
- [1, '1KB'],
10
- [1023, '1KB'],
11
- [2048, '2KB'],
12
- [35.45*1024*1024, '35.45MB'],
13
- [3.92*1024*1024*1024, '3.92GB'],
14
- ];
15
-
16
- describe('format_bytes', function () {
17
- items.forEach(function ([input, expected]) {
18
- it(`${input} → ${expected}`, function () {
19
- assert.strictEqual(format_bytes(input), expected);
20
- });
21
- });
22
- });
@@ -1,26 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const axios = require('axios');
4
- const cli = require('../../cli');
5
- const express = require('express');
6
- const fs_path_resolve = require('../../fs_path_resolve');
7
- const fs_write = require('../../fs_write');
8
- const json_stringify_safe = require('../../json_stringify_safe');
9
-
10
- cli(main);
11
-
12
- async function main()
13
- {
14
- const app = express();
15
- app.get('/', (req, res) => {});
16
- const server = app.listen(3000);
17
-
18
- try {
19
- await axios('http://127.0.0.1:3000', {timeout: 1});
20
- }
21
- catch (error) {
22
- await fs_write(fs_path_resolve(__dirname, '../1.json'), json_stringify_safe(error, null, 4).replaceAll(fs_path_resolve(__dirname, '../../../..'), '/app'));
23
- }
24
-
25
- server.close();
26
- }
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const axios = require('axios');
4
- const cli = require('../../cli');
5
- const express = require('express');
6
- const fs_path_resolve = require('../../fs_path_resolve');
7
- const fs_write = require('../../fs_write');
8
- const json_stringify_safe = require('../../json_stringify_safe');
9
-
10
- cli(main);
11
-
12
- async function main()
13
- {
14
- const app = express();
15
- app.post('/fail', function (req, res) {
16
- throw new Error('Some Error Here');
17
- });
18
- const server = app.listen(3000);
19
-
20
- try {
21
- await axios.post('http://127.0.0.1:3000/fail');
22
- }
23
- catch (error) {
24
- console.log(error);
25
- await fs_write(fs_path_resolve(__dirname, '../2.json'), json_stringify_safe(error, null, 4).replaceAll(fs_path_resolve(__dirname, '../../../..'), '/app'));
26
- }
27
-
28
- server.close();
29
- }
@@ -1,25 +0,0 @@
1
- const assert = require('assert');
2
- const format_kilo = require('./format_kilo');
3
-
4
- const items = [
5
- ['', 'n/a'],
6
- [null, 'n/a'],
7
- [undefined, 'n/a'],
8
- [0, '0'],
9
- [1, '1'],
10
- [55.45, '55'],
11
- [55.55, '56'],
12
- [900, '900'],
13
- [1500, '1.50K'],
14
- [2000, '2.00K'],
15
- [35.45*1000*1000, '35.45M'],
16
- [3.92*1000*1000*1000, '3.92G'],
17
- ];
18
-
19
- describe('format_kilo', function () {
20
- items.forEach(function ([input, expected]) {
21
- it(`${input} → ${expected}`, function () {
22
- assert.strictEqual(format_kilo(input), expected);
23
- });
24
- });
25
- });
@@ -1,33 +0,0 @@
1
- const assert = require('assert');
2
- const format_ms = require('./format_ms');
3
- const msval = require('./msval');
4
-
5
- const items = [
6
- ['00:00', ''],
7
- ['00:00', null],
8
- ['00:00', undefined],
9
- ['00:00', msval(0, 0, 0, 0)],
10
- ['00:00', msval(0, 0, 0, 1)],
11
- ['00:00', msval(0, 0, 0, 900)],
12
- ['00:01', msval(0, 0, 1, 0)],
13
- ['00:01', msval(0, 0, 1, 500)],
14
- ['00:02', msval(0, 0, 2, 0)],
15
- ['00:05', msval(0, 0, 5, 445)],
16
- ['01:00', msval(0, 1, 0, 0)],
17
- ['12:00', msval(0, 12, 0, 0)],
18
- ['12:12', msval(0, 12, 12, 12)],
19
- ['01:00:00', msval(1, 0, 0, 0)],
20
- ['01:01:00', msval(1, 1, 0, 0)],
21
- ['01:01:01', msval(1, 1, 1, 0)],
22
- ['01:01:01', msval(1, 1, 1, 1)],
23
- ['12:12:12', msval(12, 12, 12, 12)],
24
- ['999:00:00', msval(999, 0, 0, 0)],
25
- ];
26
-
27
- describe('format_ms', function () {
28
- items.forEach(function ([expected, input]) {
29
- it(`${input} → ${expected}`, function () {
30
- assert.strictEqual(format_ms(input), expected);
31
- });
32
- });
33
- });
@@ -1,33 +0,0 @@
1
- const assert = require('assert');
2
- const format_ms2 = require('./format_ms2');
3
- const msval = require('./msval');
4
-
5
- const items = [
6
- ['00:00.00', ''],
7
- ['00:00.00', null],
8
- ['00:00.00', undefined],
9
- ['00:00.00', msval(0, 0, 0, 0)],
10
- ['00:00.00', msval(0, 0, 0, 1)],
11
- ['00:00.90', msval(0, 0, 0, 900)],
12
- ['00:01.00', msval(0, 0, 1, 0)],
13
- ['00:01.50', msval(0, 0, 1, 500)],
14
- ['00:02.00', msval(0, 0, 2, 0)],
15
- ['00:05.45', msval(0, 0, 5, 445)],
16
- ['01:00.00', msval(0, 1, 0, 0)],
17
- ['12:00.00', msval(0, 12, 0, 0)],
18
- ['12:12.01', msval(0, 12, 12, 12)],
19
- ['01:00:00.00', msval(1, 0, 0, 0)],
20
- ['01:01:00.00', msval(1, 1, 0, 0)],
21
- ['01:01:01.00', msval(1, 1, 1, 0)],
22
- ['01:01:01.00', msval(1, 1, 1, 1)],
23
- ['12:12:12.01', msval(12, 12, 12, 12)],
24
- ['999:00:00.00', msval(999, 0, 0, 0)],
25
- ];
26
-
27
- describe('format_ms2', function () {
28
- items.forEach(function ([expected, input]) {
29
- it(`${input} → ${expected}`, function () {
30
- assert.strictEqual(format_ms2(input), expected);
31
- });
32
- });
33
- });