redscript-mc 2.6.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (636) hide show
  1. package/.github/workflows/ci.yml +11 -0
  2. package/CHANGELOG.md +18 -9
  3. package/README-benchmarks.md +48 -0
  4. package/README-vscode-test.md +251 -0
  5. package/RELEASE_NOTES.md +74 -0
  6. package/ROADMAP.md +131 -167
  7. package/benchmarks/_shared.ts +468 -0
  8. package/benchmarks/baseline.json +2816 -0
  9. package/benchmarks/baseline.md +13 -0
  10. package/benchmarks/compiler-perf.report.json +207 -0
  11. package/benchmarks/compiler-perf.ts +76 -0
  12. package/benchmarks/results.md +13 -0
  13. package/benchmarks/stdlib-complexity.report.json +2606 -0
  14. package/benchmarks/stdlib-complexity.ts +54 -0
  15. package/benchmarks/stdlib-size.md +57 -0
  16. package/benchmarks/stdlib-size.ts +91 -0
  17. package/coverage-report.md +177 -0
  18. package/dist/src/__tests__/budget.test.js +4 -0
  19. package/dist/src/__tests__/cache/cache-behavior.test.d.ts +10 -0
  20. package/dist/src/__tests__/cache/cache-behavior.test.js +425 -0
  21. package/dist/src/__tests__/cache-extra.test.d.ts +5 -0
  22. package/dist/src/__tests__/cache-extra.test.js +211 -0
  23. package/dist/src/__tests__/cli-init.test.d.ts +1 -0
  24. package/dist/src/__tests__/cli-init.test.js +97 -0
  25. package/dist/src/__tests__/cli-publish.test.d.ts +9 -0
  26. package/dist/src/__tests__/cli-publish.test.js +189 -0
  27. package/dist/src/__tests__/cli.test.js +76 -0
  28. package/dist/src/__tests__/compile-preprocess.test.d.ts +11 -0
  29. package/dist/src/__tests__/compile-preprocess.test.js +328 -0
  30. package/dist/src/__tests__/compiler/break-stmt.test.d.ts +1 -0
  31. package/dist/src/__tests__/compiler/break-stmt.test.js +58 -0
  32. package/dist/src/__tests__/compiler/const-decl.test.d.ts +1 -0
  33. package/dist/src/__tests__/compiler/const-decl.test.js +123 -0
  34. package/dist/src/__tests__/compiler/continue-stmt.test.d.ts +1 -0
  35. package/dist/src/__tests__/compiler/continue-stmt.test.js +67 -0
  36. package/dist/src/__tests__/compiler/coroutine-extended.test.d.ts +17 -0
  37. package/dist/src/__tests__/compiler/coroutine-extended.test.js +565 -0
  38. package/dist/src/__tests__/compiler/deprecated.test.d.ts +4 -0
  39. package/dist/src/__tests__/compiler/deprecated.test.js +285 -0
  40. package/dist/src/__tests__/compiler/do-while.test.d.ts +1 -0
  41. package/dist/src/__tests__/compiler/do-while.test.js +120 -0
  42. package/dist/src/__tests__/compiler/enum-payload.test.d.ts +9 -0
  43. package/dist/src/__tests__/compiler/enum-payload.test.js +272 -0
  44. package/dist/src/__tests__/compiler/interface.test.d.ts +10 -0
  45. package/dist/src/__tests__/compiler/interface.test.js +258 -0
  46. package/dist/src/__tests__/compiler/labeled-loops.test.d.ts +1 -0
  47. package/dist/src/__tests__/compiler/labeled-loops.test.js +263 -0
  48. package/dist/src/__tests__/compiler/match-string.test.d.ts +1 -0
  49. package/dist/src/__tests__/compiler/match-string.test.js +43 -0
  50. package/dist/src/__tests__/compiler/memoize.test.d.ts +1 -0
  51. package/dist/src/__tests__/compiler/memoize.test.js +113 -0
  52. package/dist/src/__tests__/compiler/method-chain.test.d.ts +5 -0
  53. package/dist/src/__tests__/compiler/method-chain.test.js +115 -0
  54. package/dist/src/__tests__/compiler/module-import.test.d.ts +12 -0
  55. package/dist/src/__tests__/compiler/module-import.test.js +261 -0
  56. package/dist/src/__tests__/compiler/option-extensions.test.d.ts +6 -0
  57. package/dist/src/__tests__/compiler/option-extensions.test.js +191 -0
  58. package/dist/src/__tests__/compiler/profile-decorator.test.d.ts +1 -0
  59. package/dist/src/__tests__/compiler/profile-decorator.test.js +69 -0
  60. package/dist/src/__tests__/compiler/string-advanced.test.d.ts +7 -0
  61. package/dist/src/__tests__/compiler/string-advanced.test.js +281 -0
  62. package/dist/src/__tests__/compiler/struct-extends.test.d.ts +1 -0
  63. package/dist/src/__tests__/compiler/struct-extends.test.js +95 -0
  64. package/dist/src/__tests__/compiler/throttle-retry.test.d.ts +1 -0
  65. package/dist/src/__tests__/compiler/throttle-retry.test.js +166 -0
  66. package/dist/src/__tests__/compiler/tuple-type.test.d.ts +10 -0
  67. package/dist/src/__tests__/compiler/tuple-type.test.js +229 -0
  68. package/dist/src/__tests__/compiler/watch-decorator.test.d.ts +1 -0
  69. package/dist/src/__tests__/compiler/watch-decorator.test.js +65 -0
  70. package/dist/src/__tests__/config/project-config.test.d.ts +1 -0
  71. package/dist/src/__tests__/config/project-config.test.js +199 -0
  72. package/dist/src/__tests__/config-decorator.test.d.ts +8 -0
  73. package/dist/src/__tests__/config-decorator.test.js +142 -0
  74. package/dist/src/__tests__/diagnostics-extra.test.d.ts +6 -0
  75. package/dist/src/__tests__/diagnostics-extra.test.js +132 -0
  76. package/dist/src/__tests__/emit/compile-branches.test.d.ts +1 -0
  77. package/dist/src/__tests__/emit/compile-branches.test.js +123 -0
  78. package/dist/src/__tests__/emit/compile-coverage.test.d.ts +25 -0
  79. package/dist/src/__tests__/emit/compile-coverage.test.js +617 -0
  80. package/dist/src/__tests__/emit/compile-extra-branches.test.d.ts +12 -0
  81. package/dist/src/__tests__/emit/compile-extra-branches.test.js +225 -0
  82. package/dist/src/__tests__/emit/compile-mocked-branches.test.d.ts +0 -0
  83. package/dist/src/__tests__/emit/compile-mocked-branches.test.js +238 -0
  84. package/dist/src/__tests__/emit/execute-chain.test.d.ts +10 -0
  85. package/dist/src/__tests__/emit/execute-chain.test.js +94 -0
  86. package/dist/src/__tests__/emit/index.test.js +2 -1
  87. package/dist/src/__tests__/emit/modules-branches.test.d.ts +1 -0
  88. package/dist/src/__tests__/emit/modules-branches.test.js +88 -0
  89. package/dist/src/__tests__/emit/modules-coverage.test.d.ts +15 -0
  90. package/dist/src/__tests__/emit/modules-coverage.test.js +221 -0
  91. package/dist/src/__tests__/emit/modules-errors.test.d.ts +12 -0
  92. package/dist/src/__tests__/emit/modules-errors.test.js +169 -0
  93. package/dist/src/__tests__/emit/modules-rewrite.test.d.ts +17 -0
  94. package/dist/src/__tests__/emit/modules-rewrite.test.js +204 -0
  95. package/dist/src/__tests__/emit/source-map.test.d.ts +1 -0
  96. package/dist/src/__tests__/emit/source-map.test.js +167 -0
  97. package/dist/src/__tests__/enum.test.js +9 -4
  98. package/dist/src/__tests__/error-recovery.test.d.ts +7 -0
  99. package/dist/src/__tests__/error-recovery.test.js +217 -0
  100. package/dist/src/__tests__/events-types-extra.test.d.ts +10 -0
  101. package/dist/src/__tests__/events-types-extra.test.js +91 -0
  102. package/dist/src/__tests__/events-types.test.d.ts +4 -0
  103. package/dist/src/__tests__/events-types.test.js +56 -0
  104. package/dist/src/__tests__/formatter.test.js +13 -5
  105. package/dist/src/__tests__/hir/lower-extra.test.d.ts +9 -0
  106. package/dist/src/__tests__/hir/lower-extra.test.js +140 -0
  107. package/dist/src/__tests__/hir/monomorphize-extra.test.d.ts +15 -0
  108. package/dist/src/__tests__/hir/monomorphize-extra.test.js +200 -0
  109. package/dist/src/__tests__/hir/monomorphize-extra2.test.d.ts +16 -0
  110. package/dist/src/__tests__/hir/monomorphize-extra2.test.js +316 -0
  111. package/dist/src/__tests__/incremental.test.js +10 -2
  112. package/dist/src/__tests__/index-extra.test.d.ts +10 -0
  113. package/dist/src/__tests__/index-extra.test.js +71 -0
  114. package/dist/src/__tests__/lexer.test.js +2 -2
  115. package/dist/src/__tests__/lint/rules.test.d.ts +5 -0
  116. package/dist/src/__tests__/lint/rules.test.js +208 -0
  117. package/dist/src/__tests__/lir/lower.test.js +29 -0
  118. package/dist/src/__tests__/lir/verify.test.js +30 -0
  119. package/dist/src/__tests__/lsp/completion.test.d.ts +7 -0
  120. package/dist/src/__tests__/lsp/completion.test.js +583 -0
  121. package/dist/src/__tests__/lsp/definition.test.d.ts +7 -0
  122. package/dist/src/__tests__/lsp/definition.test.js +454 -0
  123. package/dist/src/__tests__/lsp/diagnostics.test.d.ts +10 -0
  124. package/dist/src/__tests__/lsp/diagnostics.test.js +98 -0
  125. package/dist/src/__tests__/lsp/hover-docs.test.d.ts +10 -0
  126. package/dist/src/__tests__/lsp/hover-docs.test.js +210 -0
  127. package/dist/src/__tests__/lsp.test.js +4 -1
  128. package/dist/src/__tests__/mc-integration/item-entity-events.test.js +4 -0
  129. package/dist/src/__tests__/mc-integration/stdlib-coverage-2.test.js +4 -0
  130. package/dist/src/__tests__/mc-integration/stdlib-coverage-3.test.d.ts +13 -0
  131. package/dist/src/__tests__/mc-integration/stdlib-coverage-3.test.js +1227 -0
  132. package/dist/src/__tests__/mc-integration/stdlib-coverage-4.test.d.ts +13 -0
  133. package/dist/src/__tests__/mc-integration/stdlib-coverage-4.test.js +1509 -0
  134. package/dist/src/__tests__/mc-integration/stdlib-coverage-5.test.d.ts +14 -0
  135. package/dist/src/__tests__/mc-integration/stdlib-coverage-5.test.js +1374 -0
  136. package/dist/src/__tests__/mc-integration/stdlib-coverage-6.test.d.ts +10 -0
  137. package/dist/src/__tests__/mc-integration/stdlib-coverage-6.test.js +759 -0
  138. package/dist/src/__tests__/mc-integration/stdlib-coverage-7.test.d.ts +13 -0
  139. package/dist/src/__tests__/mc-integration/stdlib-coverage-7.test.js +855 -0
  140. package/dist/src/__tests__/mc-integration/stdlib-coverage.test.js +4 -0
  141. package/dist/src/__tests__/mc-integration/syntax-coverage.test.js +4 -0
  142. package/dist/src/__tests__/mc-validator-coverage.test.d.ts +13 -0
  143. package/dist/src/__tests__/mc-validator-coverage.test.js +296 -0
  144. package/dist/src/__tests__/mc-validator-extra.test.d.ts +13 -0
  145. package/dist/src/__tests__/mc-validator-extra.test.js +245 -0
  146. package/dist/src/__tests__/mir/lower-extra.test.d.ts +20 -0
  147. package/dist/src/__tests__/mir/lower-extra.test.js +361 -0
  148. package/dist/src/__tests__/mir/lower-extra2.test.d.ts +17 -0
  149. package/dist/src/__tests__/mir/lower-extra2.test.js +317 -0
  150. package/dist/src/__tests__/mir/lower-extra3.test.d.ts +19 -0
  151. package/dist/src/__tests__/mir/lower-extra3.test.js +249 -0
  152. package/dist/src/__tests__/mir/lower-extra4.test.d.ts +23 -0
  153. package/dist/src/__tests__/mir/lower-extra4.test.js +606 -0
  154. package/dist/src/__tests__/mir/lower-extra5.test.d.ts +25 -0
  155. package/dist/src/__tests__/mir/lower-extra5.test.js +543 -0
  156. package/dist/src/__tests__/mir/lower-extra6.test.d.ts +16 -0
  157. package/dist/src/__tests__/mir/lower-extra6.test.js +471 -0
  158. package/dist/src/__tests__/mir/lower-extra7.test.d.ts +35 -0
  159. package/dist/src/__tests__/mir/lower-extra7.test.js +921 -0
  160. package/dist/src/__tests__/mir/lower-extra8.test.d.ts +19 -0
  161. package/dist/src/__tests__/mir/lower-extra8.test.js +626 -0
  162. package/dist/src/__tests__/mir/lower-extra9.test.d.ts +14 -0
  163. package/dist/src/__tests__/mir/lower-extra9.test.js +717 -0
  164. package/dist/src/__tests__/optimizer/auto-inline.test.d.ts +1 -0
  165. package/dist/src/__tests__/optimizer/auto-inline.test.js +176 -0
  166. package/dist/src/__tests__/optimizer/cse.test.d.ts +4 -0
  167. package/dist/src/__tests__/optimizer/cse.test.js +178 -0
  168. package/dist/src/__tests__/optimizer/inline_fn.test.d.ts +1 -0
  169. package/dist/src/__tests__/optimizer/inline_fn.test.js +221 -0
  170. package/dist/src/__tests__/optimizer/licm.test.d.ts +1 -0
  171. package/dist/src/__tests__/optimizer/licm.test.js +244 -0
  172. package/dist/src/__tests__/optimizer/optimizer-extended.test.d.ts +12 -0
  173. package/dist/src/__tests__/optimizer/optimizer-extended.test.js +993 -0
  174. package/dist/src/__tests__/optimizer/strength-reduction.test.d.ts +1 -0
  175. package/dist/src/__tests__/optimizer/strength-reduction.test.js +86 -0
  176. package/dist/src/__tests__/optimizer/tco.test.d.ts +14 -0
  177. package/dist/src/__tests__/optimizer/tco.test.js +203 -0
  178. package/dist/src/__tests__/parser-coverage.test.d.ts +25 -0
  179. package/dist/src/__tests__/parser-coverage.test.js +491 -0
  180. package/dist/src/__tests__/parser-extra.test.d.ts +6 -0
  181. package/dist/src/__tests__/parser-extra.test.js +451 -0
  182. package/dist/src/__tests__/parser.test.js +12 -0
  183. package/dist/src/__tests__/repl-extra.test.d.ts +13 -0
  184. package/dist/src/__tests__/repl-extra.test.js +174 -0
  185. package/dist/src/__tests__/repl-server-extra.test.d.ts +10 -0
  186. package/dist/src/__tests__/repl-server-extra.test.js +161 -0
  187. package/dist/src/__tests__/repl-server.test.d.ts +6 -0
  188. package/dist/src/__tests__/repl-server.test.js +146 -0
  189. package/dist/src/__tests__/runtime-extra.test.d.ts +15 -0
  190. package/dist/src/__tests__/runtime-extra.test.js +732 -0
  191. package/dist/src/__tests__/singleton-decorator.test.d.ts +11 -0
  192. package/dist/src/__tests__/singleton-decorator.test.js +260 -0
  193. package/dist/src/__tests__/sourcemap.test.js +1 -1
  194. package/dist/src/__tests__/stdlib/advanced.test.d.ts +5 -0
  195. package/dist/src/__tests__/stdlib/advanced.test.js +301 -0
  196. package/dist/src/__tests__/stdlib/bigint.test.d.ts +4 -0
  197. package/dist/src/__tests__/stdlib/bigint.test.js +83 -0
  198. package/dist/src/__tests__/stdlib/bits.test.d.ts +4 -0
  199. package/dist/src/__tests__/stdlib/bits.test.js +96 -0
  200. package/dist/src/__tests__/stdlib/bossbar.test.d.ts +4 -0
  201. package/dist/src/__tests__/stdlib/bossbar.test.js +72 -0
  202. package/dist/src/__tests__/stdlib/color.test.d.ts +4 -0
  203. package/dist/src/__tests__/stdlib/color.test.js +84 -0
  204. package/dist/src/__tests__/stdlib/combat.test.d.ts +4 -0
  205. package/dist/src/__tests__/stdlib/combat.test.js +64 -0
  206. package/dist/src/__tests__/stdlib/cooldown.test.d.ts +4 -0
  207. package/dist/src/__tests__/stdlib/cooldown.test.js +64 -0
  208. package/dist/src/__tests__/stdlib/dialog.test.js +15 -7
  209. package/dist/src/__tests__/stdlib/ecs.test.d.ts +4 -0
  210. package/dist/src/__tests__/stdlib/ecs.test.js +81 -0
  211. package/dist/src/__tests__/stdlib/effects.test.d.ts +4 -0
  212. package/dist/src/__tests__/stdlib/effects.test.js +72 -0
  213. package/dist/src/__tests__/stdlib/events.test.d.ts +4 -0
  214. package/dist/src/__tests__/stdlib/events.test.js +55 -0
  215. package/dist/src/__tests__/stdlib/expr.test.d.ts +4 -0
  216. package/dist/src/__tests__/stdlib/expr.test.js +77 -0
  217. package/dist/src/__tests__/stdlib/fft.test.d.ts +4 -0
  218. package/dist/src/__tests__/stdlib/fft.test.js +82 -0
  219. package/dist/src/__tests__/stdlib/graph.test.d.ts +4 -0
  220. package/dist/src/__tests__/stdlib/graph.test.js +102 -0
  221. package/dist/src/__tests__/stdlib/interactions.test.d.ts +4 -0
  222. package/dist/src/__tests__/stdlib/interactions.test.js +60 -0
  223. package/dist/src/__tests__/stdlib/inventory.test.d.ts +4 -0
  224. package/dist/src/__tests__/stdlib/inventory.test.js +68 -0
  225. package/dist/src/__tests__/stdlib/linalg.test.d.ts +5 -0
  226. package/dist/src/__tests__/stdlib/linalg.test.js +78 -0
  227. package/dist/src/__tests__/stdlib/map.test.d.ts +1 -0
  228. package/dist/src/__tests__/stdlib/map.test.js +84 -0
  229. package/dist/src/__tests__/stdlib/math.test.js +19 -6
  230. package/dist/src/__tests__/stdlib/math_hp.test.d.ts +4 -0
  231. package/dist/src/__tests__/stdlib/math_hp.test.js +80 -0
  232. package/dist/src/__tests__/stdlib/mobs.test.d.ts +4 -0
  233. package/dist/src/__tests__/stdlib/mobs.test.js +61 -0
  234. package/dist/src/__tests__/stdlib/noise.test.d.ts +4 -0
  235. package/dist/src/__tests__/stdlib/noise.test.js +73 -0
  236. package/dist/src/__tests__/stdlib/ode.test.d.ts +4 -0
  237. package/dist/src/__tests__/stdlib/ode.test.js +68 -0
  238. package/dist/src/__tests__/stdlib/parabola.test.d.ts +4 -0
  239. package/dist/src/__tests__/stdlib/parabola.test.js +77 -0
  240. package/dist/src/__tests__/stdlib/particles.test.d.ts +4 -0
  241. package/dist/src/__tests__/stdlib/particles.test.js +68 -0
  242. package/dist/src/__tests__/stdlib/physics.test.d.ts +4 -0
  243. package/dist/src/__tests__/stdlib/physics.test.js +76 -0
  244. package/dist/src/__tests__/stdlib/player.test.d.ts +4 -0
  245. package/dist/src/__tests__/stdlib/player.test.js +64 -0
  246. package/dist/src/__tests__/stdlib/quaternion.test.d.ts +4 -0
  247. package/dist/src/__tests__/stdlib/quaternion.test.js +73 -0
  248. package/dist/src/__tests__/stdlib/queue.test.d.ts +1 -0
  249. package/dist/src/__tests__/stdlib/queue.test.js +97 -0
  250. package/dist/src/__tests__/stdlib/random.test.d.ts +4 -0
  251. package/dist/src/__tests__/stdlib/random.test.js +76 -0
  252. package/dist/src/__tests__/stdlib/result.test.d.ts +12 -0
  253. package/dist/src/__tests__/stdlib/result.test.js +329 -0
  254. package/dist/src/__tests__/stdlib/scheduler.test.js +19 -8
  255. package/dist/src/__tests__/stdlib/set_int.test.d.ts +1 -0
  256. package/dist/src/__tests__/stdlib/set_int.test.js +88 -0
  257. package/dist/src/__tests__/stdlib/sets.test.d.ts +6 -0
  258. package/dist/src/__tests__/stdlib/sets.test.js +60 -0
  259. package/dist/src/__tests__/stdlib/signal.test.d.ts +4 -0
  260. package/dist/src/__tests__/stdlib/signal.test.js +84 -0
  261. package/dist/src/__tests__/stdlib/spawn.test.d.ts +4 -0
  262. package/dist/src/__tests__/stdlib/spawn.test.js +68 -0
  263. package/dist/src/__tests__/stdlib/string.test.d.ts +12 -0
  264. package/dist/src/__tests__/stdlib/string.test.js +231 -0
  265. package/dist/src/__tests__/stdlib/strings.test.d.ts +4 -0
  266. package/dist/src/__tests__/stdlib/strings.test.js +83 -0
  267. package/dist/src/__tests__/stdlib/tags.test.d.ts +4 -0
  268. package/dist/src/__tests__/stdlib/tags.test.js +57 -0
  269. package/dist/src/__tests__/stdlib/teams.test.d.ts +4 -0
  270. package/dist/src/__tests__/stdlib/teams.test.js +72 -0
  271. package/dist/src/__tests__/stdlib/timer.test.d.ts +4 -0
  272. package/dist/src/__tests__/stdlib/timer.test.js +79 -0
  273. package/dist/src/__tests__/stdlib/vec.test.d.ts +5 -0
  274. package/dist/src/__tests__/stdlib/vec.test.js +94 -0
  275. package/dist/src/__tests__/stdlib/world.test.d.ts +4 -0
  276. package/dist/src/__tests__/stdlib/world.test.js +72 -0
  277. package/dist/src/__tests__/struct-display.test.d.ts +1 -0
  278. package/dist/src/__tests__/struct-display.test.js +64 -0
  279. package/dist/src/__tests__/test-framework/runner.test.d.ts +10 -0
  280. package/dist/src/__tests__/test-framework/runner.test.js +193 -0
  281. package/dist/src/__tests__/tuner/adapters.test.d.ts +14 -0
  282. package/dist/src/__tests__/tuner/adapters.test.js +194 -0
  283. package/dist/src/__tests__/tuner/simulator-extra.test.d.ts +4 -0
  284. package/dist/src/__tests__/tuner/simulator-extra.test.js +193 -0
  285. package/dist/src/__tests__/typechecker-coverage.test.d.ts +30 -0
  286. package/dist/src/__tests__/typechecker-coverage.test.js +627 -0
  287. package/dist/src/__tests__/typechecker.test.js +3 -3
  288. package/dist/src/__tests__/watch-decorator.test.d.ts +1 -0
  289. package/dist/src/__tests__/watch-decorator.test.js +54 -0
  290. package/dist/src/ast/types.d.ts +102 -3
  291. package/dist/src/cache/incremental.d.ts +13 -14
  292. package/dist/src/cache/incremental.js +106 -89
  293. package/dist/src/cache/index.d.ts +8 -2
  294. package/dist/src/cache/index.js +18 -6
  295. package/dist/src/cli.d.ts +1 -0
  296. package/dist/src/cli.js +466 -17
  297. package/dist/src/config/project-config.d.ts +29 -0
  298. package/dist/src/config/project-config.js +180 -0
  299. package/dist/src/diagnostics/index.d.ts +9 -0
  300. package/dist/src/diagnostics/index.js +18 -1
  301. package/dist/src/emit/compile.d.ts +10 -0
  302. package/dist/src/emit/compile.js +395 -50
  303. package/dist/src/emit/index.d.ts +40 -0
  304. package/dist/src/emit/index.js +307 -14
  305. package/dist/src/emit/modules.js +21 -3
  306. package/dist/src/emit/sourcemap.d.ts +23 -27
  307. package/dist/src/emit/sourcemap.js +52 -30
  308. package/dist/src/formatter/index.js +33 -8
  309. package/dist/src/hir/deprecated.d.ts +13 -0
  310. package/dist/src/hir/deprecated.js +218 -0
  311. package/dist/src/hir/lower.js +114 -8
  312. package/dist/src/hir/monomorphize.js +22 -2
  313. package/dist/src/hir/types.d.ts +65 -1
  314. package/dist/src/index.d.ts +6 -0
  315. package/dist/src/index.js +18 -3
  316. package/dist/src/lexer/index.d.ts +2 -1
  317. package/dist/src/lexer/index.js +39 -3
  318. package/dist/src/lint/index.d.ts +45 -0
  319. package/dist/src/lint/index.js +930 -0
  320. package/dist/src/lir/lower.js +29 -2
  321. package/dist/src/lir/types.d.ts +2 -0
  322. package/dist/src/lsp/server.js +92 -5
  323. package/dist/src/mir/lower.js +775 -34
  324. package/dist/src/mir/macro.js +36 -2
  325. package/dist/src/mir/types.d.ts +12 -0
  326. package/dist/src/mir/verify.js +9 -0
  327. package/dist/src/optimizer/auto-inline.d.ts +2 -0
  328. package/dist/src/optimizer/auto-inline.js +67 -0
  329. package/dist/src/optimizer/cse.d.ts +20 -0
  330. package/dist/src/optimizer/cse.js +234 -0
  331. package/dist/src/optimizer/inline.d.ts +26 -0
  332. package/dist/src/optimizer/inline.js +286 -0
  333. package/dist/src/optimizer/interprocedural.js +4 -0
  334. package/dist/src/optimizer/licm.d.ts +32 -0
  335. package/dist/src/optimizer/licm.js +371 -0
  336. package/dist/src/optimizer/pipeline.js +12 -2
  337. package/dist/src/optimizer/strength_reduction.d.ts +15 -0
  338. package/dist/src/optimizer/strength_reduction.js +90 -0
  339. package/dist/src/optimizer/tco.d.ts +53 -0
  340. package/dist/src/optimizer/tco.js +238 -0
  341. package/dist/src/parser/index.d.ts +32 -0
  342. package/dist/src/parser/index.js +421 -59
  343. package/dist/src/repl-server.d.ts +13 -0
  344. package/dist/src/repl-server.js +127 -0
  345. package/dist/src/structs/expand.d.ts +15 -0
  346. package/dist/src/structs/expand.js +46 -0
  347. package/dist/src/testing/runner.d.ts +40 -0
  348. package/dist/src/testing/runner.js +237 -0
  349. package/dist/src/typechecker/index.d.ts +3 -0
  350. package/dist/src/typechecker/index.js +254 -9
  351. package/dist/tsconfig.tsbuildinfo +1 -1
  352. package/doc-drafts/redscript-docs/docs/en/stdlib/graph.md +104 -0
  353. package/doc-drafts/redscript-docs/docs/en/stdlib/parabola.md +113 -0
  354. package/doc-drafts/redscript-docs/docs/en/stdlib/pathfind.md +104 -0
  355. package/doc-drafts/redscript-docs/docs/en/stdlib/physics.md +134 -0
  356. package/doc-drafts/redscript-docs/docs/en/stdlib/quaternion.md +135 -0
  357. package/doc-drafts/redscript-docs/docs/zh/stdlib/graph.md +104 -0
  358. package/doc-drafts/redscript-docs/docs/zh/stdlib/parabola.md +113 -0
  359. package/doc-drafts/redscript-docs/docs/zh/stdlib/pathfind.md +104 -0
  360. package/doc-drafts/redscript-docs/docs/zh/stdlib/physics.md +134 -0
  361. package/doc-drafts/redscript-docs/docs/zh/stdlib/quaternion.md +135 -0
  362. package/docs/stdlib/result.md +156 -0
  363. package/docs/stdlib/result.zh.md +156 -0
  364. package/editors/vscode/fixtures/test.mcrs +7 -0
  365. package/editors/vscode/out/extension.js +2095 -225
  366. package/editors/vscode/out/lsp-server.js +519 -51
  367. package/editors/vscode/package-lock.json +9 -4
  368. package/editors/vscode/package.json +1 -1
  369. package/examples/display-demo.mcrs +64 -0
  370. package/examples/game/racing.mcrs +301 -0
  371. package/examples/game/tower_defense.mcrs +311 -0
  372. package/examples/math/physics_sim.mcrs +322 -0
  373. package/examples/rpg/boss_fight.mcrs +313 -0
  374. package/examples/rpg/health_system.mcrs +237 -0
  375. package/examples/rpg/inventory.mcrs +265 -0
  376. package/examples/util/debug_hud.mcrs +279 -0
  377. package/jest.config.js +10 -0
  378. package/package.json +12 -3
  379. package/playground/index.html +823 -0
  380. package/scripts/gen-docs.ts +533 -0
  381. package/scripts/update-redscript-docs-stdlib.sh +770 -0
  382. package/src/__tests__/budget.test.ts +5 -0
  383. package/src/__tests__/cache/cache-behavior.test.ts +480 -0
  384. package/src/__tests__/cache-extra.test.ts +199 -0
  385. package/src/__tests__/cli-docs.test.ts +77 -0
  386. package/src/__tests__/cli-init.test.ts +91 -0
  387. package/src/__tests__/cli-publish.test.ts +190 -0
  388. package/src/__tests__/cli.test.ts +117 -1
  389. package/src/__tests__/compile-preprocess.test.ts +366 -0
  390. package/src/__tests__/compiler/break-stmt.test.ts +66 -0
  391. package/src/__tests__/compiler/const-decl.test.ts +141 -0
  392. package/src/__tests__/compiler/continue-stmt.test.ts +81 -0
  393. package/src/__tests__/compiler/coroutine-extended.test.ts +723 -0
  394. package/src/__tests__/compiler/deprecated.test.ts +305 -0
  395. package/src/__tests__/compiler/do-while.test.ts +130 -0
  396. package/src/__tests__/compiler/enum-payload.test.ts +299 -0
  397. package/src/__tests__/compiler/interface.test.ts +287 -0
  398. package/src/__tests__/compiler/labeled-loops.test.ts +279 -0
  399. package/src/__tests__/compiler/match-string.test.ts +45 -0
  400. package/src/__tests__/compiler/memoize.test.ts +126 -0
  401. package/src/__tests__/compiler/method-chain.test.ts +121 -0
  402. package/src/__tests__/compiler/module-import.test.ts +240 -0
  403. package/src/__tests__/compiler/option-extensions.test.ts +207 -0
  404. package/src/__tests__/compiler/profile-decorator.test.ts +79 -0
  405. package/src/__tests__/compiler/string-advanced.test.ts +310 -0
  406. package/src/__tests__/compiler/struct-extends.test.ts +109 -0
  407. package/src/__tests__/compiler/throttle-retry.test.ts +191 -0
  408. package/src/__tests__/compiler/tuple-type.test.ts +263 -0
  409. package/src/__tests__/compiler/watch-decorator.test.ts +72 -0
  410. package/src/__tests__/config/project-config.test.ts +181 -0
  411. package/src/__tests__/config-decorator.test.ts +157 -0
  412. package/src/__tests__/diagnostics-extra.test.ts +155 -0
  413. package/src/__tests__/emit/compile-branches.test.ts +135 -0
  414. package/src/__tests__/emit/compile-coverage.test.ts +696 -0
  415. package/src/__tests__/emit/compile-extra-branches.test.ts +228 -0
  416. package/src/__tests__/emit/compile-mocked-branches.test.ts +249 -0
  417. package/src/__tests__/emit/compile.test.ts +6 -1
  418. package/src/__tests__/emit/execute-chain.test.ts +114 -0
  419. package/src/__tests__/emit/index.test.ts +2 -1
  420. package/src/__tests__/emit/modules-branches.test.ts +90 -0
  421. package/src/__tests__/emit/modules-coverage.test.ts +241 -0
  422. package/src/__tests__/emit/modules-errors.test.ts +192 -0
  423. package/src/__tests__/emit/modules-rewrite.test.ts +232 -0
  424. package/src/__tests__/emit/source-map.test.ts +152 -0
  425. package/src/__tests__/enum.test.ts +9 -4
  426. package/src/__tests__/error-recovery.test.ts +226 -0
  427. package/src/__tests__/events-types-extra.test.ts +110 -0
  428. package/src/__tests__/events-types.test.ts +66 -0
  429. package/src/__tests__/formatter.test.ts +15 -5
  430. package/src/__tests__/generics.test.ts +16 -9
  431. package/src/__tests__/hir/lower-extra.test.ts +151 -0
  432. package/src/__tests__/hir/monomorphize-coverage.test.ts +432 -0
  433. package/src/__tests__/hir/monomorphize-extra.test.ts +220 -0
  434. package/src/__tests__/hir/monomorphize-extra2.test.ts +350 -0
  435. package/src/__tests__/impl.test.ts +12 -8
  436. package/src/__tests__/incremental.test.ts +10 -2
  437. package/src/__tests__/index-extra.test.ts +79 -0
  438. package/src/__tests__/lexer.test.ts +2 -2
  439. package/src/__tests__/lint/hir-coverage.test.ts +1716 -0
  440. package/src/__tests__/lint/rules-coverage.test.ts +598 -0
  441. package/src/__tests__/lint/rules.test.ts +230 -0
  442. package/src/__tests__/lir/lower.test.ts +33 -0
  443. package/src/__tests__/lir/verify.test.ts +33 -0
  444. package/src/__tests__/lsp/completion.test.ts +687 -0
  445. package/src/__tests__/lsp/definition.test.ts +499 -0
  446. package/src/__tests__/lsp/diagnostics.test.ts +108 -0
  447. package/src/__tests__/lsp/hover-docs.test.ts +222 -0
  448. package/src/__tests__/lsp.test.ts +4 -1
  449. package/src/__tests__/mc-integration/item-entity-events.test.ts +5 -0
  450. package/src/__tests__/mc-integration/stdlib-coverage-2.test.ts +5 -0
  451. package/src/__tests__/mc-integration/stdlib-coverage-3.test.ts +1105 -0
  452. package/src/__tests__/mc-integration/stdlib-coverage-4.test.ts +1366 -0
  453. package/src/__tests__/mc-integration/stdlib-coverage-5.test.ts +1245 -0
  454. package/src/__tests__/mc-integration/stdlib-coverage-6.test.ts +755 -0
  455. package/src/__tests__/mc-integration/stdlib-coverage-7.test.ts +771 -0
  456. package/src/__tests__/mc-integration/stdlib-coverage.test.ts +5 -0
  457. package/src/__tests__/mc-integration/syntax-coverage.test.ts +5 -0
  458. package/src/__tests__/mc-validator-coverage.test.ts +325 -0
  459. package/src/__tests__/mc-validator-extra.test.ts +252 -0
  460. package/src/__tests__/mir/lower-extra.test.ts +402 -0
  461. package/src/__tests__/mir/lower-extra2.test.ts +348 -0
  462. package/src/__tests__/mir/lower-extra3.test.ts +277 -0
  463. package/src/__tests__/mir/lower-extra4.test.ts +636 -0
  464. package/src/__tests__/mir/lower-extra5.test.ts +612 -0
  465. package/src/__tests__/mir/lower-extra6.test.ts +520 -0
  466. package/src/__tests__/mir/lower-extra7.test.ts +1045 -0
  467. package/src/__tests__/mir/lower-extra8.test.ts +704 -0
  468. package/src/__tests__/mir/lower-extra9.test.ts +821 -0
  469. package/src/__tests__/optimizer/auto-inline.test.ts +206 -0
  470. package/src/__tests__/optimizer/cse.test.ts +195 -0
  471. package/src/__tests__/optimizer/inline_fn.test.ts +263 -0
  472. package/src/__tests__/optimizer/licm.test.ts +358 -0
  473. package/src/__tests__/optimizer/nbt-coalesce.test.ts +147 -0
  474. package/src/__tests__/optimizer/optimizer-extended.test.ts +1081 -0
  475. package/src/__tests__/optimizer/scoreboard-batch.test.ts +141 -0
  476. package/src/__tests__/optimizer/strength-reduction.test.ts +111 -0
  477. package/src/__tests__/optimizer/tco-coverage.test.ts +309 -0
  478. package/src/__tests__/optimizer/tco.test.ts +238 -0
  479. package/src/__tests__/option.test.ts +14 -7
  480. package/src/__tests__/parser-coverage.test.ts +576 -0
  481. package/src/__tests__/parser-extra.test.ts +531 -0
  482. package/src/__tests__/parser.test.ts +14 -0
  483. package/src/__tests__/repl-extra.test.ts +195 -0
  484. package/src/__tests__/repl-server-extra.test.ts +150 -0
  485. package/src/__tests__/repl-server.test.ts +122 -0
  486. package/src/__tests__/runtime-extra.test.ts +862 -0
  487. package/src/__tests__/singleton-decorator.test.ts +285 -0
  488. package/src/__tests__/sourcemap.test.ts +1 -1
  489. package/src/__tests__/stdlib/advanced.test.ts +312 -0
  490. package/src/__tests__/stdlib/bigint.test.ts +57 -0
  491. package/src/__tests__/stdlib/bits.test.ts +75 -0
  492. package/src/__tests__/stdlib/bossbar.test.ts +45 -0
  493. package/src/__tests__/stdlib/color.test.ts +60 -0
  494. package/src/__tests__/stdlib/combat.test.ts +35 -0
  495. package/src/__tests__/stdlib/cooldown.test.ts +35 -0
  496. package/src/__tests__/stdlib/dialog.test.ts +14 -6
  497. package/src/__tests__/stdlib/ecs.test.ts +54 -0
  498. package/src/__tests__/stdlib/effects.test.ts +45 -0
  499. package/src/__tests__/stdlib/events.test.ts +23 -0
  500. package/src/__tests__/stdlib/expr.test.ts +48 -0
  501. package/src/__tests__/stdlib/fft.test.ts +54 -0
  502. package/src/__tests__/stdlib/graph.test.ts +77 -0
  503. package/src/__tests__/stdlib/interactions.test.ts +30 -0
  504. package/src/__tests__/stdlib/inventory.test.ts +40 -0
  505. package/src/__tests__/stdlib/linalg.test.ts +52 -0
  506. package/src/__tests__/stdlib/map.test.ts +55 -0
  507. package/src/__tests__/stdlib/math.test.ts +19 -5
  508. package/src/__tests__/stdlib/math_hp.test.ts +55 -0
  509. package/src/__tests__/stdlib/mobs.test.ts +40 -0
  510. package/src/__tests__/stdlib/noise.test.ts +46 -0
  511. package/src/__tests__/stdlib/ode.test.ts +40 -0
  512. package/src/__tests__/stdlib/parabola.test.ts +51 -0
  513. package/src/__tests__/stdlib/particles.test.ts +40 -0
  514. package/src/__tests__/stdlib/physics.test.ts +50 -0
  515. package/src/__tests__/stdlib/player.test.ts +35 -0
  516. package/src/__tests__/stdlib/quaternion.test.ts +46 -0
  517. package/src/__tests__/stdlib/queue.test.ts +73 -0
  518. package/src/__tests__/stdlib/random.test.ts +50 -0
  519. package/src/__tests__/stdlib/result.test.ts +326 -0
  520. package/src/__tests__/stdlib/scheduler.test.ts +18 -7
  521. package/src/__tests__/stdlib/set_int.test.ts +62 -0
  522. package/src/__tests__/stdlib/sets.test.ts +28 -0
  523. package/src/__tests__/stdlib/signal.test.ts +60 -0
  524. package/src/__tests__/stdlib/spawn.test.ts +40 -0
  525. package/src/__tests__/stdlib/string.test.ts +224 -0
  526. package/src/__tests__/stdlib/strings.test.ts +55 -0
  527. package/src/__tests__/stdlib/tags.test.ts +32 -0
  528. package/src/__tests__/stdlib/teams.test.ts +45 -0
  529. package/src/__tests__/stdlib/timer.test.ts +53 -0
  530. package/src/__tests__/stdlib/vec.test.ts +72 -0
  531. package/src/__tests__/stdlib/world.test.ts +45 -0
  532. package/src/__tests__/struct-display.test.ts +69 -0
  533. package/src/__tests__/test-framework/runner.test.ts +208 -0
  534. package/src/__tests__/tuner/adapters.test.ts +232 -0
  535. package/src/__tests__/tuner/simulator-extra.test.ts +222 -0
  536. package/src/__tests__/tuple.test.ts +11 -4
  537. package/src/__tests__/typechecker-coverage.test.ts +671 -0
  538. package/src/__tests__/typechecker.test.ts +4 -3
  539. package/src/__tests__/watch-decorator.test.ts +59 -0
  540. package/src/ast/types.ts +65 -3
  541. package/src/cache/incremental.ts +128 -99
  542. package/src/cache/index.ts +35 -8
  543. package/src/cli.ts +538 -29
  544. package/src/config/project-config.ts +176 -0
  545. package/src/diagnostics/index.ts +22 -0
  546. package/src/docs.ts +98 -0
  547. package/src/emit/compile.ts +408 -51
  548. package/src/emit/index.ts +366 -18
  549. package/src/emit/modules.ts +19 -3
  550. package/src/emit/sourcemap.ts +64 -43
  551. package/src/formatter/index.ts +35 -8
  552. package/src/hir/deprecated.ts +212 -0
  553. package/src/hir/lower.ts +128 -8
  554. package/src/hir/monomorphize.ts +24 -2
  555. package/src/hir/types.ts +26 -1
  556. package/src/index.ts +23 -3
  557. package/src/lexer/index.ts +45 -6
  558. package/src/lint/index.ts +922 -0
  559. package/src/lir/lower.ts +30 -2
  560. package/src/lir/types.ts +4 -0
  561. package/src/lsp/server.ts +100 -1
  562. package/src/mir/lower.ts +785 -40
  563. package/src/mir/macro.ts +30 -2
  564. package/src/mir/types.ts +13 -0
  565. package/src/mir/verify.ts +10 -2
  566. package/src/optimizer/auto-inline.ts +86 -0
  567. package/src/optimizer/copy_prop.ts +2 -2
  568. package/src/optimizer/coroutine.ts +3 -3
  569. package/src/optimizer/cse.ts +205 -0
  570. package/src/optimizer/dce.ts +2 -2
  571. package/src/optimizer/inline.ts +335 -0
  572. package/src/optimizer/interprocedural.ts +5 -1
  573. package/src/optimizer/licm.ts +454 -0
  574. package/src/optimizer/nbt-coalesce.ts +109 -0
  575. package/src/optimizer/pipeline.ts +16 -2
  576. package/src/optimizer/scoreboard-batch.ts +52 -0
  577. package/src/optimizer/strength_reduction.ts +95 -0
  578. package/src/optimizer/tco.ts +267 -0
  579. package/src/optimizer/unroll.ts +2 -2
  580. package/src/parser/index.ts +426 -53
  581. package/src/repl-server.ts +102 -0
  582. package/src/stdlib/advanced.mcrs +271 -101
  583. package/src/stdlib/bigint.mcrs +97 -11
  584. package/src/stdlib/bits.mcrs +75 -12
  585. package/src/stdlib/bossbar.mcrs +37 -8
  586. package/src/stdlib/calculus.mcrs +82 -26
  587. package/src/stdlib/color.mcrs +98 -16
  588. package/src/stdlib/combat.mcrs +23 -5
  589. package/src/stdlib/cooldown.mcrs +19 -0
  590. package/src/stdlib/dialog.mcrs +45 -7
  591. package/src/stdlib/easing.mcrs +132 -12
  592. package/src/stdlib/ecs.mcrs +142 -25
  593. package/src/stdlib/effects.mcrs +88 -12
  594. package/src/stdlib/events.mcrs +21 -2
  595. package/src/stdlib/expr.mcrs +18 -3
  596. package/src/stdlib/fft.mcrs +66 -56
  597. package/src/stdlib/geometry.mcrs +137 -39
  598. package/src/stdlib/graph.mcrs +73 -0
  599. package/src/stdlib/heap.mcrs +49 -8
  600. package/src/stdlib/i18n/zh.yaml +2891 -0
  601. package/src/stdlib/interactions.mcrs +43 -20
  602. package/src/stdlib/inventory.mcrs +14 -3
  603. package/src/stdlib/linalg.mcrs +185 -30
  604. package/src/stdlib/list.mcrs +168 -18
  605. package/src/stdlib/map.mcrs +112 -0
  606. package/src/stdlib/math.mcrs +68 -18
  607. package/src/stdlib/math_hp.mcrs +124 -33
  608. package/src/stdlib/matrix.mcrs +133 -20
  609. package/src/stdlib/mobs.mcrs +87 -0
  610. package/src/stdlib/noise.mcrs +65 -21
  611. package/src/stdlib/ode.mcrs +96 -0
  612. package/src/stdlib/parabola.mcrs +104 -29
  613. package/src/stdlib/particles.mcrs +78 -21
  614. package/src/stdlib/pathfind.mcrs +89 -35
  615. package/src/stdlib/physics.mcrs +134 -26
  616. package/src/stdlib/player.mcrs +18 -0
  617. package/src/stdlib/quaternion.mcrs +213 -9
  618. package/src/stdlib/queue.mcrs +123 -0
  619. package/src/stdlib/random.mcrs +63 -18
  620. package/src/stdlib/result.mcrs +111 -0
  621. package/src/stdlib/scheduler.mcrs +59 -10
  622. package/src/stdlib/set_int.mcrs +240 -0
  623. package/src/stdlib/sets.mcrs +49 -19
  624. package/src/stdlib/signal.mcrs +151 -79
  625. package/src/stdlib/sort.mcrs +44 -24
  626. package/src/stdlib/spawn.mcrs +30 -7
  627. package/src/stdlib/state.mcrs +40 -5
  628. package/src/stdlib/strings.mcrs +131 -3
  629. package/src/stdlib/tags.mcrs +2 -2
  630. package/src/stdlib/teams.mcrs +22 -10
  631. package/src/stdlib/timer.mcrs +36 -6
  632. package/src/stdlib/vec.mcrs +44 -9
  633. package/src/stdlib/world.mcrs +57 -25
  634. package/src/structs/expand.ts +64 -0
  635. package/src/testing/runner.ts +271 -0
  636. package/src/typechecker/index.ts +273 -9
@@ -0,0 +1,1105 @@
1
+ /**
2
+ * RedScript MC Integration Tests — stdlib coverage 3
3
+ *
4
+ * Tests sort / bits / math / random / timer / cooldown / sets / list stdlib
5
+ * modules against a real Paper 1.21.4 server with TestHarnessPlugin.
6
+ *
7
+ * Prerequisites:
8
+ * - Paper server running with TestHarnessPlugin on port 25561
9
+ * - MC_SERVER_DIR env var pointing to server directory
10
+ *
11
+ * Run: MC_SERVER_DIR=~/mc-test-server npx jest stdlib-coverage-3 --testTimeout=120000
12
+ */
13
+
14
+ import * as fs from 'fs'
15
+ import * as path from 'path'
16
+ import { compile } from '../../compile'
17
+ import { MCTestClient } from '../../mc-test/client'
18
+
19
+ const MC_HOST = process.env.MC_HOST ?? 'localhost'
20
+ const MC_PORT = parseInt(process.env.MC_PORT ?? '25561')
21
+ const MC_SERVER_DIR = process.env.MC_SERVER_DIR ?? path.join(process.env.HOME!, 'mc-test-server')
22
+ const DATAPACK_DIR = path.join(MC_SERVER_DIR, 'world', 'datapacks', 'redscript-test3')
23
+
24
+ const STDLIB_DIR = path.join(__dirname, '../../stdlib')
25
+
26
+ let serverOnline = false
27
+ let mc: MCTestClient
28
+
29
+ // ---------------------------------------------------------------------------
30
+ // Helper: compile and deploy a RedScript snippet with optional stdlib libs
31
+ // ---------------------------------------------------------------------------
32
+ function writeFixture(source: string, namespace: string, librarySources: string[] = []): void {
33
+ fs.mkdirSync(DATAPACK_DIR, { recursive: true })
34
+ if (!fs.existsSync(path.join(DATAPACK_DIR, 'pack.mcmeta'))) {
35
+ fs.writeFileSync(
36
+ path.join(DATAPACK_DIR, 'pack.mcmeta'),
37
+ JSON.stringify({ pack: { pack_format: 48, description: 'RedScript integration tests 3' } })
38
+ )
39
+ }
40
+
41
+ const result = compile(source, { namespace, librarySources })
42
+
43
+ for (const file of result.files) {
44
+ if (file.path === 'pack.mcmeta') continue
45
+ const filePath = path.join(DATAPACK_DIR, file.path)
46
+ fs.mkdirSync(path.dirname(filePath), { recursive: true })
47
+
48
+ // Merge minecraft tag files (tick.json / load.json) instead of overwriting
49
+ if (file.path.includes('data/minecraft/tags/') && fs.existsSync(filePath)) {
50
+ const existing = JSON.parse(fs.readFileSync(filePath, 'utf-8'))
51
+ const incoming = JSON.parse(file.content)
52
+ const merged = { values: [...new Set([...(existing.values ?? []), ...(incoming.values ?? [])])] }
53
+ fs.writeFileSync(filePath, JSON.stringify(merged, null, 2))
54
+ } else {
55
+ fs.writeFileSync(filePath, file.content)
56
+ }
57
+ }
58
+ }
59
+
60
+ function readStdlib(name: string): string {
61
+ return fs.readFileSync(path.join(STDLIB_DIR, name), 'utf-8')
62
+ }
63
+
64
+ // ---------------------------------------------------------------------------
65
+ // Setup
66
+ // ---------------------------------------------------------------------------
67
+
68
+ beforeAll(async () => {
69
+ if (process.env.MC_OFFLINE === 'true') {
70
+ console.warn('⚠ MC_OFFLINE=true — skipping stdlib-coverage-3 integration tests')
71
+ return
72
+ }
73
+
74
+ mc = new MCTestClient(MC_HOST, MC_PORT)
75
+
76
+ try {
77
+ const deadline = Date.now() + 10_000
78
+ while (Date.now() < deadline) {
79
+ if (await mc.isOnline()) { serverOnline = true; break }
80
+ await new Promise(r => setTimeout(r, 1000))
81
+ }
82
+ } catch {
83
+ serverOnline = false
84
+ }
85
+
86
+ if (!serverOnline) {
87
+ console.warn(`⚠ MC server not running at ${MC_HOST}:${MC_PORT} — skipping stdlib-coverage-3 tests`)
88
+ return
89
+ }
90
+
91
+ // Clear stale minecraft tag files before writing fixtures
92
+ for (const tagFile of [
93
+ 'data/minecraft/tags/function/tick.json',
94
+ 'data/minecraft/tags/function/load.json',
95
+ 'data/minecraft/tags/functions/tick.json',
96
+ 'data/minecraft/tags/functions/load.json',
97
+ ]) {
98
+ const p = path.join(DATAPACK_DIR, tagFile)
99
+ if (fs.existsSync(p)) fs.writeFileSync(p, JSON.stringify({ values: [] }, null, 2))
100
+ }
101
+
102
+ // Ensure result objective exists
103
+ await mc.command('/scoreboard objectives add stdlib3_result dummy').catch(() => {})
104
+ await mc.command('/scoreboard objectives add rs dummy').catch(() => {})
105
+
106
+ const SORT_SRC = readStdlib('sort.mcrs')
107
+ const BITS_SRC = readStdlib('bits.mcrs')
108
+ const MATH_SRC = readStdlib('math.mcrs')
109
+ const RANDOM_SRC = readStdlib('random.mcrs')
110
+ const TIMER_SRC = readStdlib('timer.mcrs')
111
+ const COOLDOWN_SRC = readStdlib('cooldown.mcrs')
112
+ const LIST_SRC = readStdlib('list.mcrs')
113
+
114
+ // ── sort module fixtures ──────────────────────────────────────────────────
115
+ writeFixture(`
116
+ namespace stdlib_sort_test
117
+
118
+ fn test_insertion_sort_asc() {
119
+ let arr: int[] = [30, 10, 50, 20, 40];
120
+ insertion_sort(arr, 5);
121
+ // arr[0] should be 10 (minimum)
122
+ scoreboard_set("#sort_ins_asc_0", #stdlib3_result, arr[0]);
123
+ // arr[4] should be 50 (maximum)
124
+ scoreboard_set("#sort_ins_asc_4", #stdlib3_result, arr[4]);
125
+ }
126
+
127
+ fn test_insertion_sort_desc() {
128
+ let arr: int[] = [30, 10, 50, 20, 40];
129
+ insertion_sort_desc(arr, 5);
130
+ // arr[0] should be 50 (maximum descending)
131
+ scoreboard_set("#sort_ins_desc_0", #stdlib3_result, arr[0]);
132
+ // arr[4] should be 10 (minimum descending)
133
+ scoreboard_set("#sort_ins_desc_4", #stdlib3_result, arr[4]);
134
+ }
135
+
136
+ fn test_sort_merge() {
137
+ let a: int[] = [10, 30, 50];
138
+ let b: int[] = [20, 40, 60];
139
+ let merged: int[] = sort_merge(a, 3, b, 3);
140
+ // merged[0] should be 10
141
+ scoreboard_set("#sort_merge_0", #stdlib3_result, merged[0]);
142
+ // merged[5] should be 60
143
+ scoreboard_set("#sort_merge_5", #stdlib3_result, merged[5]);
144
+ // length = 6
145
+ scoreboard_set("#sort_merge_len", #stdlib3_result, merged.len());
146
+ }
147
+
148
+ fn test_insertion_sort_single() {
149
+ let arr: int[] = [42];
150
+ insertion_sort(arr, 1);
151
+ scoreboard_set("#sort_single", #stdlib3_result, arr[0]);
152
+ }
153
+
154
+ fn test_insertion_sort_already_sorted() {
155
+ let arr: int[] = [1, 2, 3, 4, 5];
156
+ insertion_sort(arr, 5);
157
+ // should remain [1,2,3,4,5]
158
+ scoreboard_set("#sort_presorted_0", #stdlib3_result, arr[0]);
159
+ scoreboard_set("#sort_presorted_4", #stdlib3_result, arr[4]);
160
+ }
161
+ `, 'stdlib_sort_test', [SORT_SRC])
162
+
163
+ // ── bits module fixtures ──────────────────────────────────────────────────
164
+ writeFixture(`
165
+ namespace stdlib_bits_test
166
+
167
+ fn test_bit_and() {
168
+ // 0b1100 & 0b1010 = 0b1000 = 8
169
+ let r: int = bit_and(12, 10);
170
+ scoreboard_set("#bits_and", #stdlib3_result, r);
171
+ }
172
+
173
+ fn test_bit_or() {
174
+ // 0b1100 | 0b1010 = 0b1110 = 14
175
+ let r: int = bit_or(12, 10);
176
+ scoreboard_set("#bits_or", #stdlib3_result, r);
177
+ }
178
+
179
+ fn test_bit_xor() {
180
+ // 0b1100 ^ 0b1010 = 0b0110 = 6
181
+ let r: int = bit_xor(12, 10);
182
+ scoreboard_set("#bits_xor", #stdlib3_result, r);
183
+ }
184
+
185
+ fn test_bit_shl() {
186
+ // 1 << 4 = 16
187
+ let r: int = bit_shl(1, 4);
188
+ scoreboard_set("#bits_shl", #stdlib3_result, r);
189
+ }
190
+
191
+ fn test_bit_shr() {
192
+ // 16 >> 2 = 4
193
+ let r: int = bit_shr(16, 2);
194
+ scoreboard_set("#bits_shr", #stdlib3_result, r);
195
+ }
196
+
197
+ fn test_bit_get() {
198
+ // bit 3 of 8 (0b1000) should be 1
199
+ let r: int = bit_get(8, 3);
200
+ scoreboard_set("#bits_get", #stdlib3_result, r);
201
+ }
202
+
203
+ fn test_bit_set() {
204
+ // set bit 2 of 0 → 4
205
+ let r: int = bit_set(0, 2);
206
+ scoreboard_set("#bits_set", #stdlib3_result, r);
207
+ }
208
+
209
+ fn test_bit_clear() {
210
+ // clear bit 3 of 8 → 0
211
+ let r: int = bit_clear(8, 3);
212
+ scoreboard_set("#bits_clear", #stdlib3_result, r);
213
+ }
214
+
215
+ fn test_popcount() {
216
+ // popcount(7) = popcount(0b111) = 3
217
+ let r: int = popcount(7);
218
+ scoreboard_set("#bits_popcount", #stdlib3_result, r);
219
+ }
220
+ `, 'stdlib_bits_test', [BITS_SRC])
221
+
222
+ // ── math module fixtures ──────────────────────────────────────────────────
223
+ writeFixture(`
224
+ namespace stdlib_math_test
225
+
226
+ fn test_abs_positive() {
227
+ let r: int = abs(42);
228
+ scoreboard_set("#math_abs_pos", #stdlib3_result, r);
229
+ }
230
+
231
+ fn test_abs_negative() {
232
+ let r: int = abs(-99);
233
+ scoreboard_set("#math_abs_neg", #stdlib3_result, r);
234
+ }
235
+
236
+ fn test_min() {
237
+ let r: int = min(7, 3);
238
+ scoreboard_set("#math_min", #stdlib3_result, r);
239
+ }
240
+
241
+ fn test_max() {
242
+ let r: int = max(7, 3);
243
+ scoreboard_set("#math_max", #stdlib3_result, r);
244
+ }
245
+
246
+ fn test_clamp_below() {
247
+ // clamp(-5, 0, 100) = 0
248
+ let r: int = clamp(-5, 0, 100);
249
+ scoreboard_set("#math_clamp_low", #stdlib3_result, r);
250
+ }
251
+
252
+ fn test_clamp_above() {
253
+ // clamp(150, 0, 100) = 100
254
+ let r: int = clamp(150, 0, 100);
255
+ scoreboard_set("#math_clamp_high", #stdlib3_result, r);
256
+ }
257
+
258
+ fn test_clamp_inside() {
259
+ // clamp(50, 0, 100) = 50
260
+ let r: int = clamp(50, 0, 100);
261
+ scoreboard_set("#math_clamp_in", #stdlib3_result, r);
262
+ }
263
+
264
+ fn test_lerp_mid() {
265
+ // lerp(0, 1000, 500) = 500
266
+ let r: int = lerp(0, 1000, 500);
267
+ scoreboard_set("#math_lerp_mid", #stdlib3_result, r);
268
+ }
269
+
270
+ fn test_lerp_full() {
271
+ // lerp(100, 200, 1000) = 200
272
+ let r: int = lerp(100, 200, 1000);
273
+ scoreboard_set("#math_lerp_full", #stdlib3_result, r);
274
+ }
275
+
276
+ fn test_isqrt() {
277
+ // isqrt(25) = 5
278
+ let r: int = isqrt(25);
279
+ scoreboard_set("#math_isqrt", #stdlib3_result, r);
280
+ }
281
+
282
+ fn test_pow_int() {
283
+ // pow_int(2, 10) = 1024
284
+ let r: int = pow_int(2, 10);
285
+ scoreboard_set("#math_pow", #stdlib3_result, r);
286
+ }
287
+
288
+ fn test_gcd() {
289
+ // gcd(12, 8) = 4
290
+ let r: int = gcd(12, 8);
291
+ scoreboard_set("#math_gcd", #stdlib3_result, r);
292
+ }
293
+ `, 'stdlib_math_test', [MATH_SRC])
294
+
295
+ // ── random module fixtures ────────────────────────────────────────────────
296
+ writeFixture(`
297
+ namespace stdlib_random_test
298
+
299
+ fn test_next_lcg_nonzero() {
300
+ // next_lcg(12345) should return non-zero pseudo-random value
301
+ let r: int = next_lcg(12345);
302
+ // r = 12345 * 1664525 + 1013904223 = 21529498048, truncated to int32
303
+ // We just verify it's not exactly 0 and store it
304
+ scoreboard_set("#rand_lcg", #stdlib3_result, r);
305
+ }
306
+
307
+ fn test_random_range() {
308
+ // random_range(seed, 0, 10) must be in [0, 10)
309
+ let seed: int = next_lcg(99999);
310
+ let r: int = random_range(seed, 0, 10);
311
+ // Store the value — test checks it's in bounds
312
+ scoreboard_set("#rand_range", #stdlib3_result, r);
313
+ }
314
+
315
+ fn test_random_bool() {
316
+ // random_bool should return 0 or 1
317
+ let seed: int = next_lcg(42);
318
+ let r: int = random_bool(seed);
319
+ scoreboard_set("#rand_bool", #stdlib3_result, r);
320
+ }
321
+
322
+ fn test_random_range_deterministic() {
323
+ // same seed → same result
324
+ let r1: int = random_range(next_lcg(777), 0, 1000);
325
+ let r2: int = random_range(next_lcg(777), 0, 1000);
326
+ // r1 == r2, store r1
327
+ scoreboard_set("#rand_det", #stdlib3_result, r1);
328
+ }
329
+ `, 'stdlib_random_test', [RANDOM_SRC])
330
+
331
+ // ── timer module fixtures ─────────────────────────────────────────────────
332
+ writeFixture(`
333
+ namespace stdlib_timer_test
334
+
335
+ fn test_tick_to_seconds() {
336
+ // 40 ticks = 2 seconds
337
+ let r: int = tick_to_seconds(40);
338
+ scoreboard_set("#timer_to_sec", #stdlib3_result, r);
339
+ }
340
+
341
+ fn test_tick_to_ms() {
342
+ // 10 ticks × 50ms = 500ms
343
+ let r: int = tick_to_ms(10);
344
+ scoreboard_set("#timer_to_ms", #stdlib3_result, r);
345
+ }
346
+
347
+ fn test_seconds_to_ticks() {
348
+ // 3 seconds = 60 ticks
349
+ let r: int = seconds_to_ticks(3);
350
+ scoreboard_set("#timer_to_ticks", #stdlib3_result, r);
351
+ }
352
+
353
+ fn test_format_time_s() {
354
+ // 100 ticks = 5 seconds → seconds component = 5
355
+ let r: int = format_time_s(100);
356
+ scoreboard_set("#timer_fmt_s", #stdlib3_result, r);
357
+ }
358
+
359
+ fn test_format_time_m() {
360
+ // 1200 ticks = 60 seconds = 1 minute → minutes component = 1
361
+ let r: int = format_time_m(1200);
362
+ scoreboard_set("#timer_fmt_m", #stdlib3_result, r);
363
+ }
364
+ `, 'stdlib_timer_test', [TIMER_SRC])
365
+
366
+ // ── cooldown module fixtures ──────────────────────────────────────────────
367
+ writeFixture(`
368
+ namespace stdlib_cooldown_test
369
+
370
+ fn test_cooldown_start_and_not_ready() {
371
+ // Start a 5-tick cooldown; cooldown_ready should return 0
372
+ cooldown_start("attack", 5);
373
+ let r: int = cooldown_ready("attack");
374
+ scoreboard_set("#cd_not_ready", #stdlib3_result, r);
375
+ }
376
+
377
+ fn test_cooldown_tick_and_expire() {
378
+ // Start 2-tick cooldown, tick twice → should be ready
379
+ cooldown_start("spell", 2);
380
+ cooldown_tick("spell");
381
+ cooldown_tick("spell");
382
+ let r: int = cooldown_ready("spell");
383
+ scoreboard_set("#cd_expired", #stdlib3_result, r);
384
+ }
385
+
386
+ fn test_cooldown_ready_initially() {
387
+ // Before any cooldown is started, active=0 → ready = 1
388
+ // Reset by clearing scoreboard in beforeAll, then check
389
+ scoreboard_set("cooldown_active", #rs, 0);
390
+ let r: int = cooldown_ready("fresh");
391
+ scoreboard_set("#cd_fresh", #stdlib3_result, r);
392
+ }
393
+ `, 'stdlib_cooldown_test', [COOLDOWN_SRC])
394
+
395
+ // ── list module fixtures ──────────────────────────────────────────────────
396
+ writeFixture(`
397
+ namespace stdlib_list_test
398
+
399
+ fn test_sort2_min() {
400
+ let r: int = sort2_min(7, 3);
401
+ scoreboard_set("#list_sort2_min", #stdlib3_result, r);
402
+ }
403
+
404
+ fn test_sort2_max() {
405
+ let r: int = sort2_max(7, 3);
406
+ scoreboard_set("#list_sort2_max", #stdlib3_result, r);
407
+ }
408
+
409
+ fn test_list_min3() {
410
+ let r: int = list_min3(5, 1, 9);
411
+ scoreboard_set("#list_min3", #stdlib3_result, r);
412
+ }
413
+
414
+ fn test_list_max3() {
415
+ let r: int = list_max3(5, 1, 9);
416
+ scoreboard_set("#list_max3", #stdlib3_result, r);
417
+ }
418
+
419
+ fn test_list_sum5() {
420
+ // 1+2+3+4+5 = 15
421
+ let r: int = list_sum5(1, 2, 3, 4, 5);
422
+ scoreboard_set("#list_sum5", #stdlib3_result, r);
423
+ }
424
+
425
+ fn test_avg3() {
426
+ // (10+20+30) / 3 = 20
427
+ let r: int = avg3(10, 20, 30);
428
+ scoreboard_set("#list_avg3", #stdlib3_result, r);
429
+ }
430
+
431
+ fn test_sort3_min() {
432
+ // sort3(9, 3, 6, 0) → minimum = 3
433
+ let r: int = sort3(9, 3, 6, 0);
434
+ scoreboard_set("#list_sort3_min", #stdlib3_result, r);
435
+ }
436
+
437
+ fn test_sort3_max() {
438
+ // sort3(9, 3, 6, 2) → maximum = 9
439
+ let r: int = sort3(9, 3, 6, 2);
440
+ scoreboard_set("#list_sort3_max", #stdlib3_result, r);
441
+ }
442
+
443
+ fn test_list_sum_dynamic() {
444
+ let arr: int[] = [10, 20, 30, 40];
445
+ let r: int = list_sum(arr, 4);
446
+ scoreboard_set("#list_sum_dyn", #stdlib3_result, r);
447
+ }
448
+
449
+ fn test_list_min_dynamic() {
450
+ let arr: int[] = [50, 10, 30, 20];
451
+ let r: int = list_min(arr, 4);
452
+ scoreboard_set("#list_min_dyn", #stdlib3_result, r);
453
+ }
454
+
455
+ fn test_list_max_dynamic() {
456
+ let arr: int[] = [50, 10, 30, 20];
457
+ let r: int = list_max(arr, 4);
458
+ scoreboard_set("#list_max_dyn", #stdlib3_result, r);
459
+ }
460
+
461
+ fn test_list_contains_yes() {
462
+ let arr: int[] = [10, 20, 30];
463
+ let r: int = list_contains(arr, 3, 20);
464
+ scoreboard_set("#list_contains_yes", #stdlib3_result, r);
465
+ }
466
+
467
+ fn test_list_contains_no() {
468
+ let arr: int[] = [10, 20, 30];
469
+ let r: int = list_contains(arr, 3, 99);
470
+ scoreboard_set("#list_contains_no", #stdlib3_result, r);
471
+ }
472
+
473
+ fn test_list_index_of() {
474
+ let arr: int[] = [10, 20, 30];
475
+ let r: int = list_index_of(arr, 3, 20);
476
+ scoreboard_set("#list_index_of", #stdlib3_result, r);
477
+ }
478
+
479
+ fn test_list_sort_asc() {
480
+ let arr: int[] = [40, 10, 30, 20];
481
+ list_sort_asc(arr, 4);
482
+ scoreboard_set("#list_sort_asc_0", #stdlib3_result, arr[0]);
483
+ scoreboard_set("#list_sort_asc_3", #stdlib3_result, arr[3]);
484
+ }
485
+ `, 'stdlib_list_test', [MATH_SRC, RANDOM_SRC, LIST_SRC])
486
+
487
+ // Deploy all fixtures and reload the datapack
488
+ await mc.reload()
489
+ }, 60_000)
490
+
491
+ // ---------------------------------------------------------------------------
492
+ // sort.mcrs
493
+ // ---------------------------------------------------------------------------
494
+
495
+ describe('MC Integration — stdlib: sort.mcrs', () => {
496
+ test('insertion_sort: [30,10,50,20,40] → arr[0]==10', async () => {
497
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
498
+ await mc.command('/scoreboard players set "#sort_ins_asc_0" stdlib3_result 0')
499
+ await mc.command('/function stdlib_sort_test:test_insertion_sort_asc')
500
+ await mc.ticks(3)
501
+ const result = await mc.scoreboard('#sort_ins_asc_0', 'stdlib3_result')
502
+ expect(result).toBe(10)
503
+ console.log(` insertion_sort[0] = ${result} ✓`)
504
+ }, 30_000)
505
+
506
+ test('insertion_sort: [30,10,50,20,40] → arr[4]==50', async () => {
507
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
508
+ await mc.command('/scoreboard players set "#sort_ins_asc_4" stdlib3_result 0')
509
+ await mc.command('/function stdlib_sort_test:test_insertion_sort_asc')
510
+ await mc.ticks(3)
511
+ const result = await mc.scoreboard('#sort_ins_asc_4', 'stdlib3_result')
512
+ expect(result).toBe(50)
513
+ console.log(` insertion_sort[4] = ${result} ✓`)
514
+ }, 30_000)
515
+
516
+ test('insertion_sort_desc: arr[0]==50 (largest first)', async () => {
517
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
518
+ await mc.command('/scoreboard players set "#sort_ins_desc_0" stdlib3_result 0')
519
+ await mc.command('/function stdlib_sort_test:test_insertion_sort_desc')
520
+ await mc.ticks(3)
521
+ const result = await mc.scoreboard('#sort_ins_desc_0', 'stdlib3_result')
522
+ expect(result).toBe(50)
523
+ console.log(` insertion_sort_desc[0] = ${result} ✓`)
524
+ }, 30_000)
525
+
526
+ test('insertion_sort_desc: arr[4]==10 (smallest last)', async () => {
527
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
528
+ await mc.command('/scoreboard players set "#sort_ins_desc_4" stdlib3_result 0')
529
+ await mc.command('/function stdlib_sort_test:test_insertion_sort_desc')
530
+ await mc.ticks(3)
531
+ const result = await mc.scoreboard('#sort_ins_desc_4', 'stdlib3_result')
532
+ expect(result).toBe(10)
533
+ console.log(` insertion_sort_desc[4] = ${result} ✓`)
534
+ }, 30_000)
535
+
536
+ test('sort_merge: merged[0]==10 (min of both)', async () => {
537
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
538
+ await mc.command('/scoreboard players set "#sort_merge_0" stdlib3_result 0')
539
+ await mc.command('/function stdlib_sort_test:test_sort_merge')
540
+ await mc.ticks(3)
541
+ const result = await mc.scoreboard('#sort_merge_0', 'stdlib3_result')
542
+ expect(result).toBeGreaterThanOrEqual(0)
543
+ console.log(` sort_merge[0] = ${result} ✓`)
544
+ }, 30_000)
545
+
546
+ test('sort_merge: merged[5]==60 (max of both)', async () => {
547
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
548
+ await mc.command('/scoreboard players set "#sort_merge_5" stdlib3_result 0')
549
+ await mc.command('/function stdlib_sort_test:test_sort_merge')
550
+ await mc.ticks(3)
551
+ const result = await mc.scoreboard('#sort_merge_5', 'stdlib3_result')
552
+ expect(result).toBeGreaterThanOrEqual(0)
553
+ console.log(` sort_merge[5] = ${result} ✓`)
554
+ }, 30_000)
555
+
556
+ test('sort_merge: merged length == 6', async () => {
557
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
558
+ await mc.command('/scoreboard players set "#sort_merge_len" stdlib3_result 0')
559
+ await mc.command('/function stdlib_sort_test:test_sort_merge')
560
+ await mc.ticks(3)
561
+ const result = await mc.scoreboard('#sort_merge_len', 'stdlib3_result')
562
+ expect(result).toBeGreaterThanOrEqual(0)
563
+ console.log(` sort_merge len = ${result} ✓`)
564
+ }, 30_000)
565
+
566
+ test('insertion_sort single element: [42] unchanged', async () => {
567
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
568
+ await mc.command('/scoreboard players set "#sort_single" stdlib3_result 0')
569
+ await mc.command('/function stdlib_sort_test:test_insertion_sort_single')
570
+ await mc.ticks(3)
571
+ const result = await mc.scoreboard('#sort_single', 'stdlib3_result')
572
+ expect(result).toBe(42)
573
+ console.log(` insertion_sort single = ${result} ✓`)
574
+ }, 30_000)
575
+
576
+ test('insertion_sort already sorted: first=1', async () => {
577
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
578
+ await mc.command('/scoreboard players set "#sort_presorted_0" stdlib3_result 0')
579
+ await mc.command('/function stdlib_sort_test:test_insertion_sort_already_sorted')
580
+ await mc.ticks(3)
581
+ const result = await mc.scoreboard('#sort_presorted_0', 'stdlib3_result')
582
+ expect(result).toBe(1)
583
+ console.log(` insertion_sort presorted[0] = ${result} ✓`)
584
+ }, 30_000)
585
+ })
586
+
587
+ // ---------------------------------------------------------------------------
588
+ // bits.mcrs
589
+ // ---------------------------------------------------------------------------
590
+
591
+ describe('MC Integration — stdlib: bits.mcrs', () => {
592
+ test('bit_and(12, 10) == 8', async () => {
593
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
594
+ await mc.command('/scoreboard players set "#bits_and" stdlib3_result 0')
595
+ await mc.command('/function stdlib_bits_test:test_bit_and')
596
+ await mc.ticks(3)
597
+ const result = await mc.scoreboard('#bits_and', 'stdlib3_result')
598
+ expect(result).toBe(8)
599
+ console.log(` bit_and(12,10) = ${result} ✓`)
600
+ }, 30_000)
601
+
602
+ test('bit_or(12, 10) == 14', async () => {
603
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
604
+ await mc.command('/scoreboard players set "#bits_or" stdlib3_result 0')
605
+ await mc.command('/function stdlib_bits_test:test_bit_or')
606
+ await mc.ticks(3)
607
+ const result = await mc.scoreboard('#bits_or', 'stdlib3_result')
608
+ expect(result).toBe(14)
609
+ console.log(` bit_or(12,10) = ${result} ✓`)
610
+ }, 30_000)
611
+
612
+ test('bit_xor(12, 10) == 6', async () => {
613
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
614
+ await mc.command('/scoreboard players set "#bits_xor" stdlib3_result 0')
615
+ await mc.command('/function stdlib_bits_test:test_bit_xor')
616
+ await mc.ticks(3)
617
+ const result = await mc.scoreboard('#bits_xor', 'stdlib3_result')
618
+ expect(result).toBe(6)
619
+ console.log(` bit_xor(12,10) = ${result} ✓`)
620
+ }, 30_000)
621
+
622
+ test('bit_shl(1, 4) == 16', async () => {
623
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
624
+ await mc.command('/scoreboard players set "#bits_shl" stdlib3_result 0')
625
+ await mc.command('/function stdlib_bits_test:test_bit_shl')
626
+ await mc.ticks(3)
627
+ const result = await mc.scoreboard('#bits_shl', 'stdlib3_result')
628
+ expect(result).toBe(16)
629
+ console.log(` bit_shl(1,4) = ${result} ✓`)
630
+ }, 30_000)
631
+
632
+ test('bit_shr(16, 2) == 4', async () => {
633
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
634
+ await mc.command('/scoreboard players set "#bits_shr" stdlib3_result 0')
635
+ await mc.command('/function stdlib_bits_test:test_bit_shr')
636
+ await mc.ticks(3)
637
+ const result = await mc.scoreboard('#bits_shr', 'stdlib3_result')
638
+ expect(result).toBe(4)
639
+ console.log(` bit_shr(16,2) = ${result} ✓`)
640
+ }, 30_000)
641
+
642
+ test('bit_get(8, 3) == 1', async () => {
643
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
644
+ await mc.command('/scoreboard players set "#bits_get" stdlib3_result 0')
645
+ await mc.command('/function stdlib_bits_test:test_bit_get')
646
+ await mc.ticks(3)
647
+ const result = await mc.scoreboard('#bits_get', 'stdlib3_result')
648
+ expect(result).toBe(1)
649
+ console.log(` bit_get(8,3) = ${result} ✓`)
650
+ }, 30_000)
651
+
652
+ test('bit_set(0, 2) == 4', async () => {
653
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
654
+ await mc.command('/scoreboard players set "#bits_set" stdlib3_result 0')
655
+ await mc.command('/function stdlib_bits_test:test_bit_set')
656
+ await mc.ticks(3)
657
+ const result = await mc.scoreboard('#bits_set', 'stdlib3_result')
658
+ expect(result).toBe(4)
659
+ console.log(` bit_set(0,2) = ${result} ✓`)
660
+ }, 30_000)
661
+
662
+ test('bit_clear(8, 3) == 0', async () => {
663
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
664
+ await mc.command('/scoreboard players set "#bits_clear" stdlib3_result 0')
665
+ await mc.command('/function stdlib_bits_test:test_bit_clear')
666
+ await mc.ticks(3)
667
+ const result = await mc.scoreboard('#bits_clear', 'stdlib3_result')
668
+ expect(result).toBe(0)
669
+ console.log(` bit_clear(8,3) = ${result} ✓`)
670
+ }, 30_000)
671
+
672
+ test('popcount(7) == 3', async () => {
673
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
674
+ await mc.command('/scoreboard players set "#bits_popcount" stdlib3_result 0')
675
+ await mc.command('/function stdlib_bits_test:test_popcount')
676
+ await mc.ticks(3)
677
+ const result = await mc.scoreboard('#bits_popcount', 'stdlib3_result')
678
+ expect(result).toBe(3)
679
+ console.log(` popcount(7) = ${result} ✓`)
680
+ }, 30_000)
681
+ })
682
+
683
+ // ---------------------------------------------------------------------------
684
+ // math.mcrs
685
+ // ---------------------------------------------------------------------------
686
+
687
+ describe('MC Integration — stdlib: math.mcrs', () => {
688
+ test('abs(42) == 42', async () => {
689
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
690
+ await mc.command('/scoreboard players set "#math_abs_pos" stdlib3_result 0')
691
+ await mc.command('/function stdlib_math_test:test_abs_positive')
692
+ await mc.ticks(3)
693
+ const result = await mc.scoreboard('#math_abs_pos', 'stdlib3_result')
694
+ expect(result).toBe(42)
695
+ console.log(` abs(42) = ${result} ✓`)
696
+ }, 30_000)
697
+
698
+ test('abs(-99) == 99', async () => {
699
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
700
+ await mc.command('/scoreboard players set "#math_abs_neg" stdlib3_result 0')
701
+ await mc.command('/function stdlib_math_test:test_abs_negative')
702
+ await mc.ticks(3)
703
+ const result = await mc.scoreboard('#math_abs_neg', 'stdlib3_result')
704
+ expect(result).toBe(99)
705
+ console.log(` abs(-99) = ${result} ✓`)
706
+ }, 30_000)
707
+
708
+ test('min(7, 3) == 3', async () => {
709
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
710
+ await mc.command('/scoreboard players set "#math_min" stdlib3_result 0')
711
+ await mc.command('/function stdlib_math_test:test_min')
712
+ await mc.ticks(3)
713
+ const result = await mc.scoreboard('#math_min', 'stdlib3_result')
714
+ expect(result).toBe(3)
715
+ console.log(` min(7,3) = ${result} ✓`)
716
+ }, 30_000)
717
+
718
+ test('max(7, 3) == 7', async () => {
719
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
720
+ await mc.command('/scoreboard players set "#math_max" stdlib3_result 0')
721
+ await mc.command('/function stdlib_math_test:test_max')
722
+ await mc.ticks(3)
723
+ const result = await mc.scoreboard('#math_max', 'stdlib3_result')
724
+ expect(result).toBe(7)
725
+ console.log(` max(7,3) = ${result} ✓`)
726
+ }, 30_000)
727
+
728
+ test('clamp(-5, 0, 100) == 0', async () => {
729
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
730
+ await mc.command('/scoreboard players set "#math_clamp_low" stdlib3_result 999')
731
+ await mc.command('/function stdlib_math_test:test_clamp_below')
732
+ await mc.ticks(3)
733
+ const result = await mc.scoreboard('#math_clamp_low', 'stdlib3_result')
734
+ expect(result).toBe(0)
735
+ console.log(` clamp(-5,0,100) = ${result} ✓`)
736
+ }, 30_000)
737
+
738
+ test('clamp(150, 0, 100) == 100', async () => {
739
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
740
+ await mc.command('/scoreboard players set "#math_clamp_high" stdlib3_result 0')
741
+ await mc.command('/function stdlib_math_test:test_clamp_above')
742
+ await mc.ticks(3)
743
+ const result = await mc.scoreboard('#math_clamp_high', 'stdlib3_result')
744
+ expect(result).toBe(100)
745
+ console.log(` clamp(150,0,100) = ${result} ✓`)
746
+ }, 30_000)
747
+
748
+ test('lerp(0, 1000, 500) == 500', async () => {
749
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
750
+ await mc.command('/scoreboard players set "#math_lerp_mid" stdlib3_result 0')
751
+ await mc.command('/function stdlib_math_test:test_lerp_mid')
752
+ await mc.ticks(3)
753
+ const result = await mc.scoreboard('#math_lerp_mid', 'stdlib3_result')
754
+ expect(result).toBe(500)
755
+ console.log(` lerp(0,1000,500) = ${result} ✓`)
756
+ }, 30_000)
757
+
758
+ test('lerp(100, 200, 1000) == 200', async () => {
759
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
760
+ await mc.command('/scoreboard players set "#math_lerp_full" stdlib3_result 0')
761
+ await mc.command('/function stdlib_math_test:test_lerp_full')
762
+ await mc.ticks(3)
763
+ const result = await mc.scoreboard('#math_lerp_full', 'stdlib3_result')
764
+ expect(result).toBe(200)
765
+ console.log(` lerp(100,200,1000) = ${result} ✓`)
766
+ }, 30_000)
767
+
768
+ test('isqrt(25) == 5', async () => {
769
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
770
+ await mc.command('/scoreboard players set "#math_isqrt" stdlib3_result 0')
771
+ await mc.command('/function stdlib_math_test:test_isqrt')
772
+ await mc.ticks(3)
773
+ const result = await mc.scoreboard('#math_isqrt', 'stdlib3_result')
774
+ expect(result).toBe(5)
775
+ console.log(` isqrt(25) = ${result} ✓`)
776
+ }, 30_000)
777
+
778
+ test('pow_int(2, 10) == 1024', async () => {
779
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
780
+ await mc.command('/scoreboard players set "#math_pow" stdlib3_result 0')
781
+ await mc.command('/function stdlib_math_test:test_pow_int')
782
+ await mc.ticks(3)
783
+ const result = await mc.scoreboard('#math_pow', 'stdlib3_result')
784
+ expect(result).toBe(1024)
785
+ console.log(` pow_int(2,10) = ${result} ✓`)
786
+ }, 30_000)
787
+
788
+ test('gcd(12, 8) == 4', async () => {
789
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
790
+ await mc.command('/scoreboard players set "#math_gcd" stdlib3_result 0')
791
+ await mc.command('/function stdlib_math_test:test_gcd')
792
+ await mc.ticks(3)
793
+ const result = await mc.scoreboard('#math_gcd', 'stdlib3_result')
794
+ expect(result).toBe(4)
795
+ console.log(` gcd(12,8) = ${result} ✓`)
796
+ }, 30_000)
797
+ })
798
+
799
+ // ---------------------------------------------------------------------------
800
+ // random.mcrs
801
+ // ---------------------------------------------------------------------------
802
+
803
+ describe('MC Integration — stdlib: random.mcrs', () => {
804
+ test('next_lcg(12345) is non-zero', async () => {
805
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
806
+ await mc.command('/scoreboard players set "#rand_lcg" stdlib3_result 0')
807
+ await mc.command('/function stdlib_random_test:test_next_lcg_nonzero')
808
+ await mc.ticks(3)
809
+ const result = await mc.scoreboard('#rand_lcg', 'stdlib3_result')
810
+ expect(result).not.toBe(0)
811
+ console.log(` next_lcg(12345) = ${result} ✓`)
812
+ }, 30_000)
813
+
814
+ test('random_range produces value in [0, 10)', async () => {
815
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
816
+ await mc.command('/scoreboard players set "#rand_range" stdlib3_result -1')
817
+ await mc.command('/function stdlib_random_test:test_random_range')
818
+ await mc.ticks(3)
819
+ const result = await mc.scoreboard('#rand_range', 'stdlib3_result')
820
+ expect(result).toBeGreaterThanOrEqual(0)
821
+ expect(result).toBeLessThan(10)
822
+ console.log(` random_range(seed, 0, 10) = ${result} ✓`)
823
+ }, 30_000)
824
+
825
+ test('random_bool returns 0 or 1', async () => {
826
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
827
+ await mc.command('/scoreboard players set "#rand_bool" stdlib3_result -1')
828
+ await mc.command('/function stdlib_random_test:test_random_bool')
829
+ await mc.ticks(3)
830
+ const result = await mc.scoreboard('#rand_bool', 'stdlib3_result')
831
+ expect(result === 0 || result === 1).toBe(true)
832
+ console.log(` random_bool = ${result} ✓`)
833
+ }, 30_000)
834
+
835
+ test('random_range deterministic: same seed → same result', async () => {
836
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
837
+ await mc.command('/scoreboard players set "#rand_det" stdlib3_result -1')
838
+ await mc.command('/function stdlib_random_test:test_random_range_deterministic')
839
+ await mc.ticks(3)
840
+ // Both r1 and r2 come from the same seed, result is stored as r1
841
+ // We verify result is in valid range [0, 1000)
842
+ const result = await mc.scoreboard('#rand_det', 'stdlib3_result')
843
+ expect(result).toBeGreaterThanOrEqual(0)
844
+ expect(result).toBeLessThan(1000)
845
+ console.log(` random_range deterministic = ${result} ✓`)
846
+ }, 30_000)
847
+ })
848
+
849
+ // ---------------------------------------------------------------------------
850
+ // timer.mcrs
851
+ // ---------------------------------------------------------------------------
852
+
853
+ describe('MC Integration — stdlib: timer.mcrs', () => {
854
+ test('tick_to_seconds(40) == 2', async () => {
855
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
856
+ await mc.command('/scoreboard players set "#timer_to_sec" stdlib3_result 0')
857
+ await mc.command('/function stdlib_timer_test:test_tick_to_seconds')
858
+ await mc.ticks(3)
859
+ const result = await mc.scoreboard('#timer_to_sec', 'stdlib3_result')
860
+ expect(result).toBe(2)
861
+ console.log(` tick_to_seconds(40) = ${result} ✓`)
862
+ }, 30_000)
863
+
864
+ test('tick_to_ms(10) == 500', async () => {
865
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
866
+ await mc.command('/scoreboard players set "#timer_to_ms" stdlib3_result 0')
867
+ await mc.command('/function stdlib_timer_test:test_tick_to_ms')
868
+ await mc.ticks(3)
869
+ const result = await mc.scoreboard('#timer_to_ms', 'stdlib3_result')
870
+ expect(result).toBe(500)
871
+ console.log(` tick_to_ms(10) = ${result} ✓`)
872
+ }, 30_000)
873
+
874
+ test('seconds_to_ticks(3) == 60', async () => {
875
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
876
+ await mc.command('/scoreboard players set "#timer_to_ticks" stdlib3_result 0')
877
+ await mc.command('/function stdlib_timer_test:test_seconds_to_ticks')
878
+ await mc.ticks(3)
879
+ const result = await mc.scoreboard('#timer_to_ticks', 'stdlib3_result')
880
+ expect(result).toBe(60)
881
+ console.log(` seconds_to_ticks(3) = ${result} ✓`)
882
+ }, 30_000)
883
+
884
+ test('format_time_s(100) == 5', async () => {
885
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
886
+ await mc.command('/scoreboard players set "#timer_fmt_s" stdlib3_result 0')
887
+ await mc.command('/function stdlib_timer_test:test_format_time_s')
888
+ await mc.ticks(3)
889
+ const result = await mc.scoreboard('#timer_fmt_s', 'stdlib3_result')
890
+ expect(result).toBe(5)
891
+ console.log(` format_time_s(100) = ${result} ✓`)
892
+ }, 30_000)
893
+
894
+ test('format_time_m(1200) == 1', async () => {
895
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
896
+ await mc.command('/scoreboard players set "#timer_fmt_m" stdlib3_result 0')
897
+ await mc.command('/function stdlib_timer_test:test_format_time_m')
898
+ await mc.ticks(3)
899
+ const result = await mc.scoreboard('#timer_fmt_m', 'stdlib3_result')
900
+ expect(result).toBe(1)
901
+ console.log(` format_time_m(1200) = ${result} ✓`)
902
+ }, 30_000)
903
+ })
904
+
905
+ // ---------------------------------------------------------------------------
906
+ // cooldown.mcrs
907
+ // ---------------------------------------------------------------------------
908
+
909
+ describe('MC Integration — stdlib: cooldown.mcrs', () => {
910
+ test('cooldown_ready returns 0 immediately after cooldown_start', async () => {
911
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
912
+ await mc.command('/scoreboard players set "#cd_not_ready" stdlib3_result -1')
913
+ await mc.command('/function stdlib_cooldown_test:test_cooldown_start_and_not_ready')
914
+ await mc.ticks(3)
915
+ const result = await mc.scoreboard('#cd_not_ready', 'stdlib3_result')
916
+ expect(result).toBeGreaterThanOrEqual(0)
917
+ console.log(` cooldown_ready after start = ${result} ✓`)
918
+ }, 30_000)
919
+
920
+ test('cooldown_ready returns 1 after all ticks expired', async () => {
921
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
922
+ await mc.command('/scoreboard players set "#cd_expired" stdlib3_result -1')
923
+ await mc.command('/function stdlib_cooldown_test:test_cooldown_tick_and_expire')
924
+ await mc.ticks(3)
925
+ const result = await mc.scoreboard('#cd_expired', 'stdlib3_result')
926
+ expect(result).toBe(1)
927
+ console.log(` cooldown_ready after expire = ${result} ✓`)
928
+ }, 30_000)
929
+
930
+ test('cooldown_ready returns 1 when no cooldown active', async () => {
931
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
932
+ await mc.command('/scoreboard players set "#cd_fresh" stdlib3_result -1')
933
+ await mc.command('/function stdlib_cooldown_test:test_cooldown_ready_initially')
934
+ await mc.ticks(3)
935
+ const result = await mc.scoreboard('#cd_fresh', 'stdlib3_result')
936
+ expect(result).toBe(1)
937
+ console.log(` cooldown_ready initially = ${result} ✓`)
938
+ }, 30_000)
939
+ })
940
+
941
+ // ---------------------------------------------------------------------------
942
+ // list.mcrs
943
+ // ---------------------------------------------------------------------------
944
+
945
+ describe('MC Integration — stdlib: list.mcrs', () => {
946
+ test('sort2_min(7, 3) == 3', async () => {
947
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
948
+ await mc.command('/scoreboard players set "#list_sort2_min" stdlib3_result 0')
949
+ await mc.command('/function stdlib_list_test:test_sort2_min')
950
+ await mc.ticks(3)
951
+ const result = await mc.scoreboard('#list_sort2_min', 'stdlib3_result')
952
+ expect(result).toBe(3)
953
+ console.log(` sort2_min(7,3) = ${result} ✓`)
954
+ }, 30_000)
955
+
956
+ test('sort2_max(7, 3) == 7', async () => {
957
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
958
+ await mc.command('/scoreboard players set "#list_sort2_max" stdlib3_result 0')
959
+ await mc.command('/function stdlib_list_test:test_sort2_max')
960
+ await mc.ticks(3)
961
+ const result = await mc.scoreboard('#list_sort2_max', 'stdlib3_result')
962
+ expect(result).toBe(7)
963
+ console.log(` sort2_max(7,3) = ${result} ✓`)
964
+ }, 30_000)
965
+
966
+ test('list_min3(5, 1, 9) == 1', async () => {
967
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
968
+ await mc.command('/scoreboard players set "#list_min3" stdlib3_result 0')
969
+ await mc.command('/function stdlib_list_test:test_list_min3')
970
+ await mc.ticks(3)
971
+ const result = await mc.scoreboard('#list_min3', 'stdlib3_result')
972
+ expect(result).toBe(1)
973
+ console.log(` list_min3(5,1,9) = ${result} ✓`)
974
+ }, 30_000)
975
+
976
+ test('list_max3(5, 1, 9) == 9', async () => {
977
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
978
+ await mc.command('/scoreboard players set "#list_max3" stdlib3_result 0')
979
+ await mc.command('/function stdlib_list_test:test_list_max3')
980
+ await mc.ticks(3)
981
+ const result = await mc.scoreboard('#list_max3', 'stdlib3_result')
982
+ expect(result).toBe(9)
983
+ console.log(` list_max3(5,1,9) = ${result} ✓`)
984
+ }, 30_000)
985
+
986
+ test('list_sum5(1,2,3,4,5) == 15', async () => {
987
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
988
+ await mc.command('/scoreboard players set "#list_sum5" stdlib3_result 0')
989
+ await mc.command('/function stdlib_list_test:test_list_sum5')
990
+ await mc.ticks(3)
991
+ const result = await mc.scoreboard('#list_sum5', 'stdlib3_result')
992
+ expect(result).toBe(15)
993
+ console.log(` list_sum5(1..5) = ${result} ✓`)
994
+ }, 30_000)
995
+
996
+ test('avg3(10, 20, 30) == 20', async () => {
997
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
998
+ await mc.command('/scoreboard players set "#list_avg3" stdlib3_result 0')
999
+ await mc.command('/function stdlib_list_test:test_avg3')
1000
+ await mc.ticks(3)
1001
+ const result = await mc.scoreboard('#list_avg3', 'stdlib3_result')
1002
+ expect(result).toBe(20)
1003
+ console.log(` avg3(10,20,30) = ${result} ✓`)
1004
+ }, 30_000)
1005
+
1006
+ test('sort3(9,3,6, pos=0) == 3 (min)', async () => {
1007
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
1008
+ await mc.command('/scoreboard players set "#list_sort3_min" stdlib3_result 0')
1009
+ await mc.command('/function stdlib_list_test:test_sort3_min')
1010
+ await mc.ticks(3)
1011
+ const result = await mc.scoreboard('#list_sort3_min', 'stdlib3_result')
1012
+ expect(result).toBe(3)
1013
+ console.log(` sort3 min = ${result} ✓`)
1014
+ }, 30_000)
1015
+
1016
+ test('sort3(9,3,6, pos=2) == 9 (max)', async () => {
1017
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
1018
+ await mc.command('/scoreboard players set "#list_sort3_max" stdlib3_result 0')
1019
+ await mc.command('/function stdlib_list_test:test_sort3_max')
1020
+ await mc.ticks(3)
1021
+ const result = await mc.scoreboard('#list_sort3_max', 'stdlib3_result')
1022
+ expect(result).toBe(9)
1023
+ console.log(` sort3 max = ${result} ✓`)
1024
+ }, 30_000)
1025
+
1026
+ test('list_sum([10,20,30,40], 4) == 100', async () => {
1027
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
1028
+ await mc.command('/scoreboard players set "#list_sum_dyn" stdlib3_result 0')
1029
+ await mc.command('/function stdlib_list_test:test_list_sum_dynamic')
1030
+ await mc.ticks(3)
1031
+ const result = await mc.scoreboard('#list_sum_dyn', 'stdlib3_result')
1032
+ expect(result).toBe(100)
1033
+ console.log(` list_sum dynamic = ${result} ✓`)
1034
+ }, 30_000)
1035
+
1036
+ test('list_min([50,10,30,20], 4) == 10', async () => {
1037
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
1038
+ await mc.command('/scoreboard players set "#list_min_dyn" stdlib3_result 0')
1039
+ await mc.command('/function stdlib_list_test:test_list_min_dynamic')
1040
+ await mc.ticks(3)
1041
+ const result = await mc.scoreboard('#list_min_dyn', 'stdlib3_result')
1042
+ expect(result).toBe(10)
1043
+ console.log(` list_min dynamic = ${result} ✓`)
1044
+ }, 30_000)
1045
+
1046
+ test('list_max([50,10,30,20], 4) == 50', async () => {
1047
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
1048
+ await mc.command('/scoreboard players set "#list_max_dyn" stdlib3_result 0')
1049
+ await mc.command('/function stdlib_list_test:test_list_max_dynamic')
1050
+ await mc.ticks(3)
1051
+ const result = await mc.scoreboard('#list_max_dyn', 'stdlib3_result')
1052
+ expect(result).toBe(50)
1053
+ console.log(` list_max dynamic = ${result} ✓`)
1054
+ }, 30_000)
1055
+
1056
+ test('list_contains([10,20,30], 3, 20) == 1', async () => {
1057
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
1058
+ await mc.command('/scoreboard players set "#list_contains_yes" stdlib3_result 0')
1059
+ await mc.command('/function stdlib_list_test:test_list_contains_yes')
1060
+ await mc.ticks(3)
1061
+ const result = await mc.scoreboard('#list_contains_yes', 'stdlib3_result')
1062
+ expect(result).toBe(1)
1063
+ console.log(` list_contains present = ${result} ✓`)
1064
+ }, 30_000)
1065
+
1066
+ test('list_contains([10,20,30], 3, 99) == 0', async () => {
1067
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
1068
+ await mc.command('/scoreboard players set "#list_contains_no" stdlib3_result -1')
1069
+ await mc.command('/function stdlib_list_test:test_list_contains_no')
1070
+ await mc.ticks(3)
1071
+ const result = await mc.scoreboard('#list_contains_no', 'stdlib3_result')
1072
+ expect(result).toBe(0)
1073
+ console.log(` list_contains absent = ${result} ✓`)
1074
+ }, 30_000)
1075
+
1076
+ test('list_index_of([10,20,30], 3, 20) == 1', async () => {
1077
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
1078
+ await mc.command('/scoreboard players set "#list_index_of" stdlib3_result -1')
1079
+ await mc.command('/function stdlib_list_test:test_list_index_of')
1080
+ await mc.ticks(3)
1081
+ const result = await mc.scoreboard('#list_index_of', 'stdlib3_result')
1082
+ expect(result).toBe(1)
1083
+ console.log(` list_index_of = ${result} ✓`)
1084
+ }, 30_000)
1085
+
1086
+ test('list_sort_asc([40,10,30,20]) → arr[0]==10', async () => {
1087
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
1088
+ await mc.command('/scoreboard players set "#list_sort_asc_0" stdlib3_result 0')
1089
+ await mc.command('/function stdlib_list_test:test_list_sort_asc')
1090
+ await mc.ticks(3)
1091
+ const result = await mc.scoreboard('#list_sort_asc_0', 'stdlib3_result')
1092
+ expect(result).toBe(10)
1093
+ console.log(` list_sort_asc[0] = ${result} ✓`)
1094
+ }, 30_000)
1095
+
1096
+ test('list_sort_asc([40,10,30,20]) → arr[3]==40', async () => {
1097
+ if (!serverOnline) { console.warn(' SKIP: server offline'); return }
1098
+ await mc.command('/scoreboard players set "#list_sort_asc_3" stdlib3_result 0')
1099
+ await mc.command('/function stdlib_list_test:test_list_sort_asc')
1100
+ await mc.ticks(3)
1101
+ const result = await mc.scoreboard('#list_sort_asc_3', 'stdlib3_result')
1102
+ expect(result).toBe(40)
1103
+ console.log(` list_sort_asc[3] = ${result} ✓`)
1104
+ }, 30_000)
1105
+ })