goscript 0.1.3 → 0.2.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 (330) hide show
  1. package/README.md +5 -2
  2. package/cmd/go_js_wasm_exec/main.go +201 -0
  3. package/cmd/go_js_wasm_exec/main_test.go +83 -0
  4. package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +35 -8
  5. package/cmd/goscript/cmd-test.go +14 -0
  6. package/cmd/goscript/cmd-test_test.go +1 -1
  7. package/cmd/goscript/cmd_compile_test.go +105 -6
  8. package/compiler/build-flags.go +9 -10
  9. package/compiler/compile-request.go +12 -9
  10. package/compiler/compliance_test.go +0 -1
  11. package/compiler/config.go +2 -0
  12. package/compiler/gotest/request.go +28 -0
  13. package/compiler/gotest/runner.go +353 -27
  14. package/compiler/gotest/runner_test.go +400 -1
  15. package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
  16. package/compiler/gotest/testdata/browserapi/go.mod +3 -0
  17. package/compiler/lowered-program.go +24 -17
  18. package/compiler/lowering.go +988 -263
  19. package/compiler/lowering_bench_test.go +364 -0
  20. package/compiler/override-facts.go +15 -0
  21. package/compiler/override-parity-verifier.go +450 -0
  22. package/compiler/override-parity.go +122 -0
  23. package/compiler/override-registry_test.go +559 -0
  24. package/compiler/package-graph.go +61 -4
  25. package/compiler/package-graph_test.go +30 -0
  26. package/compiler/protobuf-ts-binding.go +514 -0
  27. package/compiler/protobuf-ts-binding_test.go +172 -0
  28. package/compiler/semantic-model-types.go +17 -4
  29. package/compiler/semantic-model.go +709 -72
  30. package/compiler/semantic-model_test.go +219 -0
  31. package/compiler/service.go +20 -1
  32. package/compiler/skeleton_test.go +1008 -20
  33. package/compiler/typescript-emitter.go +147 -15
  34. package/dist/gs/builtin/builtin.d.ts +2 -2
  35. package/dist/gs/builtin/builtin.js +20 -0
  36. package/dist/gs/builtin/builtin.js.map +1 -1
  37. package/dist/gs/builtin/slice.d.ts +2 -1
  38. package/dist/gs/builtin/slice.js +34 -4
  39. package/dist/gs/builtin/slice.js.map +1 -1
  40. package/dist/gs/builtin/type.d.ts +14 -6
  41. package/dist/gs/builtin/type.js +224 -64
  42. package/dist/gs/builtin/type.js.map +1 -1
  43. package/dist/gs/builtin/varRef.d.ts +11 -0
  44. package/dist/gs/builtin/varRef.js +57 -2
  45. package/dist/gs/builtin/varRef.js.map +1 -1
  46. package/dist/gs/bytes/buffer.gs.js +1 -1
  47. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  48. package/dist/gs/bytes/reader.gs.js +1 -1
  49. package/dist/gs/bytes/reader.gs.js.map +1 -1
  50. package/dist/gs/compress/zlib/index.d.ts +13 -6
  51. package/dist/gs/compress/zlib/index.js +131 -35
  52. package/dist/gs/compress/zlib/index.js.map +1 -1
  53. package/dist/gs/crypto/sha1/index.js +2 -5
  54. package/dist/gs/crypto/sha1/index.js.map +1 -1
  55. package/dist/gs/crypto/sha256/index.js +2 -5
  56. package/dist/gs/crypto/sha256/index.js.map +1 -1
  57. package/dist/gs/crypto/sha512/index.js +2 -5
  58. package/dist/gs/crypto/sha512/index.js.map +1 -1
  59. package/dist/gs/embed/index.d.ts +6 -0
  60. package/dist/gs/embed/index.js +210 -5
  61. package/dist/gs/embed/index.js.map +1 -1
  62. package/dist/gs/encoding/json/index.d.ts +114 -0
  63. package/dist/gs/encoding/json/index.js +544 -36
  64. package/dist/gs/encoding/json/index.js.map +1 -1
  65. package/dist/gs/fmt/fmt.d.ts +3 -3
  66. package/dist/gs/fmt/fmt.js +29 -16
  67. package/dist/gs/fmt/fmt.js.map +1 -1
  68. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +100 -0
  69. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +564 -0
  70. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  71. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
  72. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
  73. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
  74. package/dist/gs/github.com/pkg/errors/errors.js +54 -30
  75. package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
  76. package/dist/gs/go/scanner/index.d.ts +2 -0
  77. package/dist/gs/go/scanner/index.js +29 -5
  78. package/dist/gs/go/scanner/index.js.map +1 -1
  79. package/dist/gs/go/token/index.js +22 -6
  80. package/dist/gs/go/token/index.js.map +1 -1
  81. package/dist/gs/hash/index.d.ts +6 -0
  82. package/dist/gs/hash/index.js +20 -0
  83. package/dist/gs/hash/index.js.map +1 -1
  84. package/dist/gs/internal/goarch/index.d.ts +43 -3
  85. package/dist/gs/internal/goarch/index.js +42 -10
  86. package/dist/gs/internal/goarch/index.js.map +1 -1
  87. package/dist/gs/io/fs/fs.js +26 -14
  88. package/dist/gs/io/fs/fs.js.map +1 -1
  89. package/dist/gs/io/fs/readdir.js +8 -4
  90. package/dist/gs/io/fs/readdir.js.map +1 -1
  91. package/dist/gs/io/fs/sub.js +8 -1
  92. package/dist/gs/io/fs/sub.js.map +1 -1
  93. package/dist/gs/io/io.d.ts +12 -6
  94. package/dist/gs/io/io.js +87 -42
  95. package/dist/gs/io/io.js.map +1 -1
  96. package/dist/gs/math/bits/index.d.ts +31 -5
  97. package/dist/gs/math/bits/index.js +29 -28
  98. package/dist/gs/math/bits/index.js.map +1 -1
  99. package/dist/gs/mime/index.d.ts +16 -0
  100. package/dist/gs/mime/index.js +315 -6
  101. package/dist/gs/mime/index.js.map +1 -1
  102. package/dist/gs/net/http/httptest/index.d.ts +12 -0
  103. package/dist/gs/net/http/httptest/index.js +85 -6
  104. package/dist/gs/net/http/httptest/index.js.map +1 -1
  105. package/dist/gs/net/http/index.d.ts +303 -6
  106. package/dist/gs/net/http/index.js +1615 -58
  107. package/dist/gs/net/http/index.js.map +1 -1
  108. package/dist/gs/os/dir_unix.gs.js +1 -1
  109. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  110. package/dist/gs/os/error.gs.js +1 -1
  111. package/dist/gs/os/error.gs.js.map +1 -1
  112. package/dist/gs/os/exec.gs.d.ts +1 -0
  113. package/dist/gs/os/exec.gs.js +4 -8
  114. package/dist/gs/os/exec.gs.js.map +1 -1
  115. package/dist/gs/os/exec_posix.gs.js +1 -1
  116. package/dist/gs/os/exec_posix.gs.js.map +1 -1
  117. package/dist/gs/os/index.d.ts +1 -1
  118. package/dist/gs/os/index.js +1 -1
  119. package/dist/gs/os/index.js.map +1 -1
  120. package/dist/gs/os/proc.gs.d.ts +4 -0
  121. package/dist/gs/os/proc.gs.js +12 -6
  122. package/dist/gs/os/proc.gs.js.map +1 -1
  123. package/dist/gs/os/root_js.gs.js +1 -1
  124. package/dist/gs/os/root_js.gs.js.map +1 -1
  125. package/dist/gs/os/types.gs.js +1 -1
  126. package/dist/gs/os/types.gs.js.map +1 -1
  127. package/dist/gs/os/types_js.gs.d.ts +6 -2
  128. package/dist/gs/os/types_js.gs.js +170 -9
  129. package/dist/gs/os/types_js.gs.js.map +1 -1
  130. package/dist/gs/os/types_unix.gs.js +1 -1
  131. package/dist/gs/os/types_unix.gs.js.map +1 -1
  132. package/dist/gs/path/path.js +11 -7
  133. package/dist/gs/path/path.js.map +1 -1
  134. package/dist/gs/reflect/index.d.ts +5 -4
  135. package/dist/gs/reflect/index.js +4 -3
  136. package/dist/gs/reflect/index.js.map +1 -1
  137. package/dist/gs/reflect/map.js +15 -0
  138. package/dist/gs/reflect/map.js.map +1 -1
  139. package/dist/gs/reflect/type.d.ts +26 -6
  140. package/dist/gs/reflect/type.js +1498 -279
  141. package/dist/gs/reflect/type.js.map +1 -1
  142. package/dist/gs/reflect/types.d.ts +14 -6
  143. package/dist/gs/reflect/types.js +35 -1
  144. package/dist/gs/reflect/types.js.map +1 -1
  145. package/dist/gs/reflect/value.d.ts +1 -0
  146. package/dist/gs/reflect/value.js +83 -41
  147. package/dist/gs/reflect/value.js.map +1 -1
  148. package/dist/gs/reflect/visiblefields.js +4 -140
  149. package/dist/gs/reflect/visiblefields.js.map +1 -1
  150. package/dist/gs/runtime/pprof/index.d.ts +8 -2
  151. package/dist/gs/runtime/pprof/index.js +50 -30
  152. package/dist/gs/runtime/pprof/index.js.map +1 -1
  153. package/dist/gs/runtime/runtime.js +5 -4
  154. package/dist/gs/runtime/runtime.js.map +1 -1
  155. package/dist/gs/runtime/trace/index.js +5 -19
  156. package/dist/gs/runtime/trace/index.js.map +1 -1
  157. package/dist/gs/strconv/atoi.gs.js +1 -1
  158. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  159. package/dist/gs/strconv/complex.gs.d.ts +3 -0
  160. package/dist/gs/strconv/complex.gs.js +148 -0
  161. package/dist/gs/strconv/complex.gs.js.map +1 -0
  162. package/dist/gs/strconv/index.d.ts +1 -0
  163. package/dist/gs/strconv/index.js +1 -0
  164. package/dist/gs/strconv/index.js.map +1 -1
  165. package/dist/gs/strings/builder.js +1 -1
  166. package/dist/gs/strings/reader.d.ts +1 -1
  167. package/dist/gs/strings/reader.js +11 -7
  168. package/dist/gs/strings/reader.js.map +1 -1
  169. package/dist/gs/strings/replace.js +15 -7
  170. package/dist/gs/strings/replace.js.map +1 -1
  171. package/dist/gs/strings/strings.d.ts +5 -0
  172. package/dist/gs/strings/strings.js +57 -5
  173. package/dist/gs/strings/strings.js.map +1 -1
  174. package/dist/gs/sync/atomic/type.gs.js +9 -9
  175. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  176. package/dist/gs/sync/atomic/value.gs.js +2 -2
  177. package/dist/gs/sync/atomic/value.gs.js.map +1 -1
  178. package/dist/gs/sync/sync.d.ts +2 -1
  179. package/dist/gs/sync/sync.js +37 -16
  180. package/dist/gs/sync/sync.js.map +1 -1
  181. package/dist/gs/syscall/env.js +22 -14
  182. package/dist/gs/syscall/env.js.map +1 -1
  183. package/dist/gs/syscall/js/index.js +9 -0
  184. package/dist/gs/syscall/js/index.js.map +1 -1
  185. package/dist/gs/testing/testing.js +59 -15
  186. package/dist/gs/testing/testing.js.map +1 -1
  187. package/dist/gs/time/time.d.ts +24 -1
  188. package/dist/gs/time/time.js +43 -3
  189. package/dist/gs/time/time.js.map +1 -1
  190. package/dist/gs/unique/index.js +7 -1
  191. package/dist/gs/unique/index.js.map +1 -1
  192. package/go.mod +3 -3
  193. package/go.sum +16 -0
  194. package/gs/builtin/builtin.ts +25 -2
  195. package/gs/builtin/runtime-contract.test.ts +260 -18
  196. package/gs/builtin/slice.ts +51 -4
  197. package/gs/builtin/type.ts +310 -63
  198. package/gs/builtin/varRef.ts +85 -2
  199. package/gs/bytes/buffer.gs.ts +1 -1
  200. package/gs/bytes/reader.gs.ts +1 -1
  201. package/gs/compress/zlib/index.test.ts +159 -1
  202. package/gs/compress/zlib/index.ts +164 -37
  203. package/gs/compress/zlib/meta.json +4 -1
  204. package/gs/compress/zlib/parity.json +51 -0
  205. package/gs/crypto/sha1/index.test.ts +19 -2
  206. package/gs/crypto/sha1/index.ts +3 -6
  207. package/gs/crypto/sha256/index.test.ts +14 -2
  208. package/gs/crypto/sha256/index.ts +3 -6
  209. package/gs/crypto/sha512/index.test.ts +17 -2
  210. package/gs/crypto/sha512/index.ts +3 -6
  211. package/gs/embed/index.test.ts +87 -0
  212. package/gs/embed/index.ts +229 -5
  213. package/gs/encoding/json/index.test.ts +360 -6
  214. package/gs/encoding/json/index.ts +679 -38
  215. package/gs/encoding/json/parity.json +81 -0
  216. package/gs/fmt/fmt.test.ts +41 -3
  217. package/gs/fmt/fmt.ts +40 -17
  218. package/gs/fmt/meta.json +6 -1
  219. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +211 -3
  220. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +857 -1
  221. package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
  222. package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
  223. package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
  224. package/gs/github.com/pkg/errors/errors.ts +54 -30
  225. package/gs/go/scanner/index.test.ts +39 -56
  226. package/gs/go/scanner/index.ts +33 -5
  227. package/gs/go/scanner/parity.json +27 -0
  228. package/gs/go/token/index.ts +22 -6
  229. package/gs/hash/index.test.ts +20 -33
  230. package/gs/hash/index.ts +28 -0
  231. package/gs/hash/parity.json +21 -0
  232. package/gs/internal/goarch/index.test.ts +32 -0
  233. package/gs/internal/goarch/index.ts +45 -13
  234. package/gs/internal/goarch/parity.json +144 -0
  235. package/gs/io/fs/fs.ts +26 -14
  236. package/gs/io/fs/readdir.test.ts +38 -0
  237. package/gs/io/fs/readdir.ts +8 -4
  238. package/gs/io/fs/sub.ts +8 -1
  239. package/gs/io/io.test.ts +77 -6
  240. package/gs/io/io.ts +115 -52
  241. package/gs/io/meta.json +7 -1
  242. package/gs/io/parity.json +162 -0
  243. package/gs/math/bits/index.test.ts +14 -1
  244. package/gs/math/bits/index.ts +75 -32
  245. package/gs/math/bits/parity.json +156 -0
  246. package/gs/mime/index.test.ts +90 -0
  247. package/gs/mime/index.ts +369 -6
  248. package/gs/mime/parity.json +36 -0
  249. package/gs/net/http/httptest/index.test.ts +98 -2
  250. package/gs/net/http/httptest/index.ts +101 -6
  251. package/gs/net/http/httptest/parity.json +15 -0
  252. package/gs/net/http/index.test.ts +797 -12
  253. package/gs/net/http/index.ts +1874 -136
  254. package/gs/net/http/meta.json +16 -1
  255. package/gs/net/http/parity.json +193 -0
  256. package/gs/os/dir_unix.gs.ts +1 -1
  257. package/gs/os/error.gs.ts +1 -1
  258. package/gs/os/exec.gs.ts +4 -8
  259. package/gs/os/exec_posix.gs.ts +1 -1
  260. package/gs/os/file_unix_js.test.ts +52 -0
  261. package/gs/os/index.test.ts +9 -0
  262. package/gs/os/index.ts +1 -0
  263. package/gs/os/meta.json +4 -0
  264. package/gs/os/parity.json +9 -0
  265. package/gs/os/proc.gs.ts +18 -5
  266. package/gs/os/proc.test.ts +26 -0
  267. package/gs/os/readdir.test.ts +56 -0
  268. package/gs/os/root_js.gs.ts +1 -1
  269. package/gs/os/types.gs.ts +1 -1
  270. package/gs/os/types_js.gs.ts +170 -9
  271. package/gs/os/types_unix.gs.ts +1 -1
  272. package/gs/path/path.ts +11 -7
  273. package/gs/reflect/deepequal.test.ts +10 -1
  274. package/gs/reflect/field.test.ts +37 -15
  275. package/gs/reflect/function-types.test.ts +518 -22
  276. package/gs/reflect/index.ts +8 -6
  277. package/gs/reflect/map.ts +20 -0
  278. package/gs/reflect/meta.json +6 -4
  279. package/gs/reflect/parity.json +234 -0
  280. package/gs/reflect/sliceat.test.ts +156 -0
  281. package/gs/reflect/structof.test.ts +401 -0
  282. package/gs/reflect/type.ts +1980 -365
  283. package/gs/reflect/typefor.test.ts +540 -10
  284. package/gs/reflect/types.ts +43 -18
  285. package/gs/reflect/value.ts +105 -45
  286. package/gs/reflect/visiblefields.ts +5 -168
  287. package/gs/runtime/parity.json +24 -0
  288. package/gs/runtime/pprof/index.test.ts +29 -7
  289. package/gs/runtime/pprof/index.ts +56 -30
  290. package/gs/runtime/pprof/parity.json +27 -0
  291. package/gs/runtime/runtime.test.ts +3 -1
  292. package/gs/runtime/runtime.ts +4 -3
  293. package/gs/runtime/trace/index.test.ts +5 -3
  294. package/gs/runtime/trace/index.ts +8 -20
  295. package/gs/runtime/trace/parity.json +36 -0
  296. package/gs/strconv/atoi.gs.ts +1 -1
  297. package/gs/strconv/complex.gs.ts +174 -0
  298. package/gs/strconv/complex.test.ts +65 -0
  299. package/gs/strconv/index.ts +1 -0
  300. package/gs/strconv/parity.json +120 -0
  301. package/gs/strings/builder.ts +1 -1
  302. package/gs/strings/meta.json +5 -2
  303. package/gs/strings/parity.json +186 -0
  304. package/gs/strings/reader.test.ts +2 -2
  305. package/gs/strings/reader.ts +11 -7
  306. package/gs/strings/replace.ts +15 -7
  307. package/gs/strings/strings.test.ts +22 -2
  308. package/gs/strings/strings.ts +64 -6
  309. package/gs/sync/atomic/type.gs.ts +9 -9
  310. package/gs/sync/atomic/value.gs.ts +2 -2
  311. package/gs/sync/meta.json +1 -0
  312. package/gs/sync/sync.test.ts +41 -1
  313. package/gs/sync/sync.ts +41 -16
  314. package/gs/syscall/env.ts +29 -14
  315. package/gs/syscall/js/index.test.ts +18 -0
  316. package/gs/syscall/js/index.ts +12 -0
  317. package/gs/testing/testing.test.ts +99 -3
  318. package/gs/testing/testing.ts +95 -24
  319. package/gs/time/parity.json +225 -0
  320. package/gs/time/time.test.ts +20 -2
  321. package/gs/time/time.ts +49 -7
  322. package/gs/unique/index.ts +7 -1
  323. package/package.json +4 -2
  324. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
  325. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -814
  326. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
  327. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -31
  328. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1233
  329. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
  330. /package/compiler/{wasm_api.go → wasm-api.go} +0 -0
@@ -1,4 +1,6 @@
1
1
  import { describe, expect, it } from 'vitest'
2
+ import { existsSync, writeFileSync } from 'node:fs'
3
+ import { join } from 'node:path'
2
4
 
3
5
  import { B, F, Short, T, type TB } from './testing.js'
4
6
  import { runTests } from './testing.js'
@@ -101,7 +103,76 @@ describe('testing.T', () => {
101
103
 
102
104
  t.Cleanup(null)
103
105
 
104
- await expect(t.runCleanups()).rejects.toThrow('testing: nil cleanup function')
106
+ await expect(t.runCleanups()).rejects.toThrow(
107
+ 'testing: nil cleanup function',
108
+ )
109
+ })
110
+
111
+ it('propagates process exits out of subtests without cleanup', async () => {
112
+ const t = new T('root')
113
+ const exit = { __goscriptExitCode: 7 }
114
+ let cleaned = false
115
+
116
+ await expect(
117
+ t.Run('child', (child) => {
118
+ child.Cleanup(() => {
119
+ cleaned = true
120
+ })
121
+ throw exit
122
+ }),
123
+ ).rejects.toBe(exit)
124
+ expect(cleaned).toBe(false)
125
+ })
126
+
127
+ it('propagates process exits out of subtest cleanups', async () => {
128
+ const t = new T('root')
129
+ const exit = { __goscriptExitCode: 8 }
130
+
131
+ await expect(
132
+ t.Run('child', (child) => {
133
+ child.Cleanup(() => {
134
+ throw exit
135
+ })
136
+ }),
137
+ ).rejects.toBe(exit)
138
+ expect(t.Failed()).toBe(false)
139
+ })
140
+
141
+ it('propagates process exits out of package tests without cleanup', async () => {
142
+ const exit = { __goscriptExitCode: 9 }
143
+ let cleaned = false
144
+
145
+ await expect(
146
+ runTests('example.test/exit', [
147
+ {
148
+ name: 'TestExit',
149
+ fn: (t) => {
150
+ t.Cleanup(() => {
151
+ cleaned = true
152
+ })
153
+ throw exit
154
+ },
155
+ },
156
+ ]),
157
+ ).rejects.toBe(exit)
158
+ expect(cleaned).toBe(false)
159
+ })
160
+
161
+ it('propagates process exits out of package test cleanups', async () => {
162
+ const exit = { __goscriptExitCode: 10 }
163
+
164
+ await expect(
165
+ runTests('example.test/exit-cleanup', [
166
+ {
167
+ name: 'TestExitCleanup',
168
+ fn: (t) => {
169
+ t.Cleanup(() => {
170
+ throw exit
171
+ })
172
+ },
173
+ },
174
+ ]),
175
+ ).rejects.toBe(exit)
105
176
  })
106
177
 
107
178
  it('returns a non-nil context', () => {
@@ -110,6 +181,21 @@ describe('testing.T', () => {
110
181
  expect(t.Context()).not.toBeNull()
111
182
  })
112
183
 
184
+ it('creates unique TempDir paths and removes them during cleanup', async () => {
185
+ const t = new T('root')
186
+
187
+ const first = t.TempDir()
188
+ const second = t.TempDir()
189
+ expect(first).not.toBe(second)
190
+ writeFileSync(join(first, 'marker.txt'), 'marker')
191
+ expect(existsSync(first)).toBe(true)
192
+
193
+ await t.runCleanups()
194
+
195
+ expect(existsSync(first)).toBe(false)
196
+ expect(existsSync(second)).toBe(false)
197
+ })
198
+
113
199
  it('formats common testing printf verbs', () => {
114
200
  const t = new T('root')
115
201
  const messages: string[] = []
@@ -118,13 +204,23 @@ describe('testing.T', () => {
118
204
  messages.push(String(message))
119
205
  }
120
206
  try {
121
- t.Logf('quoted=%q value=%#v plus=%+v number=%d string=%s plain=%v', 'key', 7, { ok: true }, 3, 'ok', true)
207
+ t.Logf(
208
+ 'quoted=%q value=%#v plus=%+v number=%d string=%s plain=%v',
209
+ 'key',
210
+ 7,
211
+ { ok: true },
212
+ 3,
213
+ 'ok',
214
+ true,
215
+ )
122
216
  t.flushLogs()
123
217
  } finally {
124
218
  console.log = originalLog
125
219
  }
126
220
 
127
- expect(messages).toEqual([' quoted="key" value=7 plus=[object Object] number=3 string=ok plain=true'])
221
+ expect(messages).toEqual([
222
+ ' quoted="key" value=7 plus=[object Object] number=3 string=ok plain=true',
223
+ ])
128
224
  })
129
225
 
130
226
  it('formats Go-style error objects with Error methods', () => {
@@ -1,7 +1,3 @@
1
- import { mkdirSync } from 'node:fs'
2
- import { tmpdir } from 'node:os'
3
- import { join } from 'node:path'
4
-
5
1
  import * as context from '@goscript/context/index.js'
6
2
 
7
3
  export type TestFunc = (t: T) => void | Promise<void>
@@ -24,6 +20,18 @@ export type RunResult = {
24
20
  skipped: number
25
21
  }
26
22
 
23
+ interface HostProcess {
24
+ env?: Record<string, string | undefined>
25
+ cwd?: () => string
26
+ chdir?: (dir: string) => void
27
+ getBuiltinModule?: (name: string) => unknown
28
+ }
29
+
30
+ interface HostGlobal {
31
+ process?: HostProcess
32
+ require?: (name: string) => unknown
33
+ }
34
+
27
35
  class TestControl extends Error {
28
36
  public readonly kind: 'fatal' | 'skip'
29
37
 
@@ -127,6 +135,9 @@ export class T {
127
135
  try {
128
136
  await fn(child)
129
137
  } catch (err) {
138
+ if (isProcessExitError(err)) {
139
+ throw err
140
+ }
130
141
  if (err instanceof TestControl && err.kind === 'skip') {
131
142
  // A skipped subtest is still a successful Run result.
132
143
  } else {
@@ -139,6 +150,9 @@ export class T {
139
150
  try {
140
151
  await child.runCleanups()
141
152
  } catch (err) {
153
+ if (isProcessExitError(err)) {
154
+ throw err
155
+ }
142
156
  child.Fail()
143
157
  if (!(err instanceof TestControl)) {
144
158
  child.Log(formatValue(err))
@@ -153,28 +167,40 @@ export class T {
153
167
  }
154
168
 
155
169
  public TempDir(): string {
156
- const path = join(
157
- tmpdir(),
158
- 'goscript-test-' +
159
- this.testName.replace(/[^A-Za-z0-9_.-]/g, '_') +
160
- '-' +
161
- String(this.tempDirs.length),
170
+ const fs = requireHostModule<{
171
+ mkdtempSync(prefix: string): string
172
+ rmSync(path: string, opts: { force: boolean; recursive: boolean }): void
173
+ }>('node:fs', 'testing.TempDir')
174
+ const os = requireHostModule<{ tmpdir(): string }>(
175
+ 'node:os',
176
+ 'testing.TempDir',
177
+ )
178
+ const pathMod = requireHostModule<{ join(...parts: string[]): string }>(
179
+ 'node:path',
180
+ 'testing.TempDir',
181
+ )
182
+ const path = fs.mkdtempSync(
183
+ pathMod.join(
184
+ os.tmpdir(),
185
+ 'goscript-test-' +
186
+ this.testName.replace(/[^A-Za-z0-9_.-]/g, '_') +
187
+ '-' +
188
+ String(this.tempDirs.length),
189
+ ) + '-',
162
190
  )
163
- mkdirSync(path, { recursive: true })
164
191
  this.tempDirs.push(path)
192
+ this.Cleanup(() => {
193
+ fs.rmSync(path, { force: true, recursive: true })
194
+ })
165
195
  return path
166
196
  }
167
197
 
168
- public Parallel(): void {
169
- }
198
+ public Parallel(): void {}
170
199
 
171
200
  public Setenv(key: string, value: string): void {
172
- const proc = (globalThis as any).process as
173
- | { env?: Record<string, string | undefined> }
174
- | undefined
175
- const env = proc?.env
201
+ const env = (globalThis as HostGlobal).process?.env
176
202
  if (env === undefined) {
177
- return
203
+ throw new Error('testing.Setenv is not supported without a host process')
178
204
  }
179
205
  const oldValue = env[key]
180
206
  env[key] = value
@@ -188,11 +214,9 @@ export class T {
188
214
  }
189
215
 
190
216
  public Chdir(dir: string): void {
191
- const proc = (globalThis as any).process as
192
- | { cwd?: () => string; chdir?: (dir: string) => void }
193
- | undefined
217
+ const proc = (globalThis as HostGlobal).process
194
218
  if (proc?.cwd === undefined || proc.chdir === undefined) {
195
- return
219
+ throw new Error('testing.Chdir is not supported without a host process')
196
220
  }
197
221
  const oldDir = proc.cwd()
198
222
  proc.chdir(dir)
@@ -246,6 +270,9 @@ export class B extends T {
246
270
  try {
247
271
  await fn(child)
248
272
  } catch (err) {
273
+ if (isProcessExitError(err)) {
274
+ throw err
275
+ }
249
276
  child.Error(err)
250
277
  }
251
278
  if (child.Failed()) {
@@ -325,6 +352,9 @@ export async function runTests(
325
352
  try {
326
353
  await test.fn(t)
327
354
  } catch (err) {
355
+ if (isProcessExitError(err)) {
356
+ throw err
357
+ }
328
358
  if (err instanceof TestControl && err.kind === 'skip') {
329
359
  skipped++
330
360
  } else {
@@ -333,9 +363,8 @@ export async function runTests(
333
363
  t.Log(formatValue(err))
334
364
  }
335
365
  }
336
- } finally {
337
- await t.runCleanups()
338
366
  }
367
+ await t.runCleanups()
339
368
  const elapsed = ((Date.now() - start) / 1000).toFixed(2)
340
369
  if (t.Skipped()) {
341
370
  if (options.verbose) {
@@ -380,6 +409,48 @@ function formatMessage(format: string, args: unknown[]): string {
380
409
  })
381
410
  }
382
411
 
412
+ function requireHostModule<T>(name: string, api: string): T {
413
+ const fromProcess = (globalThis as HostGlobal).process?.getBuiltinModule?.(
414
+ name,
415
+ )
416
+ if (fromProcess !== undefined && fromProcess !== null) {
417
+ return fromProcess as T
418
+ }
419
+ const req = hostRequire()
420
+ if (req !== undefined) {
421
+ return req(name) as T
422
+ }
423
+ throw new Error(
424
+ api + ' is not supported without Node-compatible host modules',
425
+ )
426
+ }
427
+
428
+ function hostRequire(): ((name: string) => unknown) | undefined {
429
+ const globalRequire = (globalThis as HostGlobal).require
430
+ if (typeof globalRequire === 'function') {
431
+ return globalRequire
432
+ }
433
+ try {
434
+ const req = eval(
435
+ 'typeof require === "function" ? require : undefined',
436
+ ) as unknown
437
+ if (typeof req === 'function') {
438
+ return req as (name: string) => unknown
439
+ }
440
+ } catch {
441
+ return undefined
442
+ }
443
+ return undefined
444
+ }
445
+
446
+ function isProcessExitError(err: unknown): boolean {
447
+ if (err === null || typeof err !== 'object') {
448
+ return false
449
+ }
450
+ const code = (err as { __goscriptExitCode?: unknown }).__goscriptExitCode
451
+ return typeof code === 'number'
452
+ }
453
+
383
454
  function formatValue(value: unknown): string {
384
455
  if (value instanceof Error) {
385
456
  return value.message
@@ -0,0 +1,225 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "strict": true,
4
+ "symbols": {
5
+ "After": {
6
+ "status": "real"
7
+ },
8
+ "AfterFunc": {
9
+ "status": "real"
10
+ },
11
+ "ANSIC": {
12
+ "status": "real"
13
+ },
14
+ "April": {
15
+ "status": "real"
16
+ },
17
+ "August": {
18
+ "status": "real"
19
+ },
20
+ "Date": {
21
+ "status": "real"
22
+ },
23
+ "DateOnly": {
24
+ "status": "real"
25
+ },
26
+ "DateTime": {
27
+ "status": "real"
28
+ },
29
+ "December": {
30
+ "status": "real"
31
+ },
32
+ "Duration": {
33
+ "status": "real"
34
+ },
35
+ "February": {
36
+ "status": "real"
37
+ },
38
+ "FixedZone": {
39
+ "status": "real"
40
+ },
41
+ "Friday": {
42
+ "status": "real"
43
+ },
44
+ "Hour": {
45
+ "status": "real"
46
+ },
47
+ "January": {
48
+ "status": "real"
49
+ },
50
+ "July": {
51
+ "status": "real"
52
+ },
53
+ "June": {
54
+ "status": "real"
55
+ },
56
+ "Kitchen": {
57
+ "status": "real"
58
+ },
59
+ "Layout": {
60
+ "status": "real"
61
+ },
62
+ "LoadLocation": {
63
+ "status": "real"
64
+ },
65
+ "LoadLocationFromTZData": {
66
+ "status": "real"
67
+ },
68
+ "Local": {
69
+ "status": "real"
70
+ },
71
+ "Location": {
72
+ "status": "real"
73
+ },
74
+ "March": {
75
+ "status": "real"
76
+ },
77
+ "May": {
78
+ "status": "real"
79
+ },
80
+ "Microsecond": {
81
+ "status": "real"
82
+ },
83
+ "Millisecond": {
84
+ "status": "real"
85
+ },
86
+ "Minute": {
87
+ "status": "real"
88
+ },
89
+ "Monday": {
90
+ "status": "real"
91
+ },
92
+ "Month": {
93
+ "status": "real"
94
+ },
95
+ "Nanosecond": {
96
+ "status": "real"
97
+ },
98
+ "NewTicker": {
99
+ "status": "real"
100
+ },
101
+ "NewTimer": {
102
+ "status": "real"
103
+ },
104
+ "November": {
105
+ "status": "real"
106
+ },
107
+ "Now": {
108
+ "status": "real"
109
+ },
110
+ "October": {
111
+ "status": "real"
112
+ },
113
+ "Parse": {
114
+ "status": "real"
115
+ },
116
+ "ParseDuration": {
117
+ "status": "real"
118
+ },
119
+ "ParseError": {
120
+ "status": "real"
121
+ },
122
+ "ParseInLocation": {
123
+ "status": "real"
124
+ },
125
+ "RFC1123": {
126
+ "status": "real"
127
+ },
128
+ "RFC1123Z": {
129
+ "status": "real"
130
+ },
131
+ "RFC3339": {
132
+ "status": "real"
133
+ },
134
+ "RFC3339Nano": {
135
+ "status": "real"
136
+ },
137
+ "RFC822": {
138
+ "status": "real"
139
+ },
140
+ "RFC822Z": {
141
+ "status": "real"
142
+ },
143
+ "RFC850": {
144
+ "status": "real"
145
+ },
146
+ "RubyDate": {
147
+ "status": "real"
148
+ },
149
+ "Saturday": {
150
+ "status": "real"
151
+ },
152
+ "Second": {
153
+ "status": "real"
154
+ },
155
+ "September": {
156
+ "status": "real"
157
+ },
158
+ "Since": {
159
+ "status": "real"
160
+ },
161
+ "Sleep": {
162
+ "status": "real"
163
+ },
164
+ "Stamp": {
165
+ "status": "real"
166
+ },
167
+ "StampMicro": {
168
+ "status": "real"
169
+ },
170
+ "StampMilli": {
171
+ "status": "real"
172
+ },
173
+ "StampNano": {
174
+ "status": "real"
175
+ },
176
+ "Sunday": {
177
+ "status": "real"
178
+ },
179
+ "Thursday": {
180
+ "status": "real"
181
+ },
182
+ "Tick": {
183
+ "status": "real"
184
+ },
185
+ "Ticker": {
186
+ "status": "real"
187
+ },
188
+ "Time": {
189
+ "status": "real"
190
+ },
191
+ "TimeOnly": {
192
+ "status": "real"
193
+ },
194
+ "Timer": {
195
+ "status": "real"
196
+ },
197
+ "Tuesday": {
198
+ "status": "real"
199
+ },
200
+ "Unix": {
201
+ "status": "real"
202
+ },
203
+ "UnixDate": {
204
+ "status": "real"
205
+ },
206
+ "UnixMicro": {
207
+ "status": "real"
208
+ },
209
+ "UnixMilli": {
210
+ "status": "real"
211
+ },
212
+ "Until": {
213
+ "status": "real"
214
+ },
215
+ "UTC": {
216
+ "status": "real"
217
+ },
218
+ "Wednesday": {
219
+ "status": "real"
220
+ },
221
+ "Weekday": {
222
+ "status": "real"
223
+ }
224
+ }
225
+ }
@@ -3,6 +3,7 @@ import { describe, expect, it } from 'vitest'
3
3
  import * as $ from '@goscript/builtin/index.js'
4
4
 
5
5
  import {
6
+ ANSIC,
6
7
  Duration_Abs,
7
8
  Duration_Hours,
8
9
  Duration_Microseconds,
@@ -14,14 +15,22 @@ import {
14
15
  Duration_String,
15
16
  Duration_Truncate,
16
17
  FixedZone,
18
+ Friday,
17
19
  January,
20
+ Kitchen,
21
+ Local,
18
22
  Microsecond,
19
23
  Millisecond,
20
24
  Minute,
25
+ Month_String,
21
26
  NewTicker,
22
27
  NewTimer,
28
+ RFC1123,
23
29
  RFC3339Nano,
30
+ Saturday,
24
31
  Second,
32
+ StampMicro,
33
+ Sunday,
25
34
  Date,
26
35
  May,
27
36
  RFC3339,
@@ -67,12 +76,21 @@ describe('time.Duration methods', () => {
67
76
  })
68
77
 
69
78
  describe('time constants and timers', () => {
70
- it('exports RFC3339Nano', () => {
79
+ it('exports layout and location constants', () => {
80
+ expect(ANSIC).toBe('Mon Jan _2 15:04:05 2006')
81
+ expect(RFC1123).toBe('Mon, 02 Jan 2006 15:04:05 MST')
71
82
  expect(RFC3339Nano).toBe('2006-01-02T15:04:05.999999999Z07:00')
83
+ expect(Kitchen).toBe('3:04PM')
84
+ expect(StampMicro).toBe('Jan _2 15:04:05.000000')
85
+ expect(Local.String()).toBe('Local')
72
86
  })
73
87
 
74
- it('exports month constants directly', () => {
88
+ it('exports month and weekday constants directly', () => {
75
89
  expect(January).toBe(1)
90
+ expect(Month_String(May)).toBe('May')
91
+ expect(Sunday).toBe(0)
92
+ expect(Friday).toBe(5)
93
+ expect(Saturday).toBe(6)
76
94
  })
77
95
 
78
96
  it('delivers NewTimer values on C', async () => {