goscript 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/README.md +267 -255
  2. package/cmd/goscript/cmd-test.go +193 -0
  3. package/cmd/goscript/cmd-test_test.go +76 -0
  4. package/cmd/goscript/main.go +1 -0
  5. package/compiler/build-flags.go +38 -0
  6. package/compiler/compile-request.go +2 -0
  7. package/compiler/compliance_test.go +0 -8
  8. package/compiler/gotest/owner.go +24 -0
  9. package/compiler/gotest/package-result.go +67 -0
  10. package/compiler/gotest/request.go +145 -0
  11. package/compiler/gotest/result.go +28 -0
  12. package/compiler/gotest/runner.go +588 -0
  13. package/compiler/gotest/runner_test.go +627 -0
  14. package/compiler/gotest/test.go +9 -0
  15. package/compiler/index.test.ts +1 -1
  16. package/compiler/lowered-program.go +71 -19
  17. package/compiler/lowering.go +5065 -569
  18. package/compiler/override-facts.go +307 -0
  19. package/compiler/override-registry.go +50 -189
  20. package/compiler/override-registry_test.go +47 -0
  21. package/compiler/package-graph.go +50 -27
  22. package/compiler/package-graph_test.go +37 -2
  23. package/compiler/package-test-function.go +9 -0
  24. package/compiler/package-test-graph-package.go +40 -0
  25. package/compiler/package-test-graph-variant.go +105 -0
  26. package/compiler/package-test-graph.go +117 -0
  27. package/compiler/package-test-graph_test.go +144 -0
  28. package/compiler/runtime-contract.go +189 -29
  29. package/compiler/runtime-contract_test.go +44 -30
  30. package/compiler/semantic-model-types.go +9 -6
  31. package/compiler/semantic-model.go +538 -38
  32. package/compiler/semantic-model_test.go +55 -0
  33. package/compiler/service.go +1 -1
  34. package/compiler/skeleton_test.go +679 -49
  35. package/compiler/tsworkspace/owner.go +334 -0
  36. package/compiler/tsworkspace/owner_test.go +93 -0
  37. package/compiler/tsworkspace/result.go +17 -0
  38. package/compiler/typescript-emitter.go +459 -82
  39. package/compiler/wasm/compile.go +1 -1
  40. package/compiler/wasm/compile_test.go +61 -11
  41. package/compiler/wasm_api.go +172 -7
  42. package/dist/gs/builtin/builtin.d.ts +20 -2
  43. package/dist/gs/builtin/builtin.js +194 -6
  44. package/dist/gs/builtin/builtin.js.map +1 -1
  45. package/dist/gs/builtin/channel.d.ts +8 -0
  46. package/dist/gs/builtin/channel.js +12 -0
  47. package/dist/gs/builtin/channel.js.map +1 -1
  48. package/dist/gs/builtin/slice.d.ts +22 -2
  49. package/dist/gs/builtin/slice.js +216 -44
  50. package/dist/gs/builtin/slice.js.map +1 -1
  51. package/dist/gs/builtin/type.d.ts +5 -2
  52. package/dist/gs/builtin/type.js +83 -24
  53. package/dist/gs/builtin/type.js.map +1 -1
  54. package/dist/gs/builtin/varRef.d.ts +5 -0
  55. package/dist/gs/builtin/varRef.js +23 -0
  56. package/dist/gs/builtin/varRef.js.map +1 -1
  57. package/dist/gs/bytes/buffer.gs.js +48 -44
  58. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  59. package/dist/gs/bytes/reader.gs.js +20 -18
  60. package/dist/gs/bytes/reader.gs.js.map +1 -1
  61. package/dist/gs/context/context.d.ts +5 -4
  62. package/dist/gs/context/context.js +10 -10
  63. package/dist/gs/context/context.js.map +1 -1
  64. package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
  65. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
  66. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
  67. package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
  68. package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
  69. package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
  70. package/dist/gs/embed/index.d.ts +7 -0
  71. package/dist/gs/embed/index.js +16 -0
  72. package/dist/gs/embed/index.js.map +1 -0
  73. package/dist/gs/encoding/json/index.d.ts +1 -0
  74. package/dist/gs/encoding/json/index.js +18 -0
  75. package/dist/gs/encoding/json/index.js.map +1 -1
  76. package/dist/gs/errors/errors.d.ts +4 -0
  77. package/dist/gs/errors/errors.js +81 -0
  78. package/dist/gs/errors/errors.js.map +1 -1
  79. package/dist/gs/fmt/fmt.d.ts +4 -4
  80. package/dist/gs/fmt/fmt.js +42 -11
  81. package/dist/gs/fmt/fmt.js.map +1 -1
  82. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +35 -0
  83. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +211 -1
  84. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  85. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
  86. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +825 -0
  87. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
  88. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +163 -0
  89. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +449 -0
  90. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
  91. package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
  92. package/dist/gs/github.com/klauspost/compress/internal/le/index.js +71 -0
  93. package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
  94. package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
  95. package/dist/gs/go/internal/scannerhooks/index.js +5 -0
  96. package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
  97. package/dist/gs/go/scanner/index.d.ts +13 -0
  98. package/dist/gs/go/scanner/index.js +35 -0
  99. package/dist/gs/go/scanner/index.js.map +1 -1
  100. package/dist/gs/go/token/index.d.ts +156 -0
  101. package/dist/gs/go/token/index.js +500 -4
  102. package/dist/gs/go/token/index.js.map +1 -1
  103. package/dist/gs/internal/abi/index.d.ts +4 -0
  104. package/dist/gs/internal/abi/index.js +10 -0
  105. package/dist/gs/internal/abi/index.js.map +1 -1
  106. package/dist/gs/internal/bytealg/index.d.ts +2 -0
  107. package/dist/gs/internal/bytealg/index.js +14 -0
  108. package/dist/gs/internal/bytealg/index.js.map +1 -1
  109. package/dist/gs/internal/byteorder/index.d.ts +8 -2
  110. package/dist/gs/internal/byteorder/index.js +56 -25
  111. package/dist/gs/internal/byteorder/index.js.map +1 -1
  112. package/dist/gs/internal/godebug/index.d.ts +12 -0
  113. package/dist/gs/internal/godebug/index.js +30 -0
  114. package/dist/gs/internal/godebug/index.js.map +1 -0
  115. package/dist/gs/io/fs/index.d.ts +1 -0
  116. package/dist/gs/io/fs/index.js +1 -0
  117. package/dist/gs/io/fs/index.js.map +1 -1
  118. package/dist/gs/io/fs/readlink.d.ts +8 -0
  119. package/dist/gs/io/fs/readlink.js +64 -0
  120. package/dist/gs/io/fs/readlink.js.map +1 -0
  121. package/dist/gs/io/fs/walk.d.ts +3 -3
  122. package/dist/gs/io/fs/walk.js +7 -7
  123. package/dist/gs/io/fs/walk.js.map +1 -1
  124. package/dist/gs/io/io.d.ts +40 -6
  125. package/dist/gs/io/io.js +151 -26
  126. package/dist/gs/io/io.js.map +1 -1
  127. package/dist/gs/maps/iter.d.ts +3 -3
  128. package/dist/gs/maps/iter.js +3 -3
  129. package/dist/gs/maps/iter.js.map +1 -1
  130. package/dist/gs/maps/maps.d.ts +2 -2
  131. package/dist/gs/maps/maps.js +1 -1
  132. package/dist/gs/maps/maps.js.map +1 -1
  133. package/dist/gs/math/bits/index.d.ts +13 -4
  134. package/dist/gs/math/bits/index.js +66 -34
  135. package/dist/gs/math/bits/index.js.map +1 -1
  136. package/dist/gs/math/const.gs.d.ts +5 -5
  137. package/dist/gs/math/const.gs.js +4 -4
  138. package/dist/gs/math/const.gs.js.map +1 -1
  139. package/dist/gs/mime/index.d.ts +1 -0
  140. package/dist/gs/mime/index.js +50 -0
  141. package/dist/gs/mime/index.js.map +1 -0
  142. package/dist/gs/net/http/httptest/index.d.ts +11 -0
  143. package/dist/gs/net/http/httptest/index.js +21 -0
  144. package/dist/gs/net/http/httptest/index.js.map +1 -0
  145. package/dist/gs/net/http/index.d.ts +27 -0
  146. package/dist/gs/net/http/index.js +61 -0
  147. package/dist/gs/net/http/index.js.map +1 -0
  148. package/dist/gs/os/dir_unix.gs.js +2 -2
  149. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  150. package/dist/gs/os/types_js.gs.js.map +1 -1
  151. package/dist/gs/path/filepath/match.js +165 -3
  152. package/dist/gs/path/filepath/match.js.map +1 -1
  153. package/dist/gs/path/filepath/path.d.ts +3 -1
  154. package/dist/gs/path/filepath/path.js +133 -4
  155. package/dist/gs/path/filepath/path.js.map +1 -1
  156. package/dist/gs/path/path.d.ts +4 -1
  157. package/dist/gs/path/path.js +16 -4
  158. package/dist/gs/path/path.js.map +1 -1
  159. package/dist/gs/reflect/index.d.ts +1 -1
  160. package/dist/gs/reflect/index.js +1 -1
  161. package/dist/gs/reflect/index.js.map +1 -1
  162. package/dist/gs/reflect/map.js +3 -0
  163. package/dist/gs/reflect/map.js.map +1 -1
  164. package/dist/gs/reflect/type.d.ts +7 -4
  165. package/dist/gs/reflect/type.js +148 -7
  166. package/dist/gs/reflect/type.js.map +1 -1
  167. package/dist/gs/runtime/debug/index.d.ts +2 -0
  168. package/dist/gs/runtime/debug/index.js +8 -0
  169. package/dist/gs/runtime/debug/index.js.map +1 -0
  170. package/dist/gs/runtime/runtime.d.ts +35 -3
  171. package/dist/gs/runtime/runtime.js +72 -0
  172. package/dist/gs/runtime/runtime.js.map +1 -1
  173. package/dist/gs/slices/slices.d.ts +24 -5
  174. package/dist/gs/slices/slices.js +214 -5
  175. package/dist/gs/slices/slices.js.map +1 -1
  176. package/dist/gs/sort/slice.gs.d.ts +3 -3
  177. package/dist/gs/sort/slice.gs.js +6 -6
  178. package/dist/gs/sort/slice.gs.js.map +1 -1
  179. package/dist/gs/sort/sort.gs.d.ts +4 -4
  180. package/dist/gs/sort/sort.gs.js +11 -8
  181. package/dist/gs/sort/sort.gs.js.map +1 -1
  182. package/dist/gs/strings/builder.d.ts +1 -1
  183. package/dist/gs/strings/builder.js +3 -2
  184. package/dist/gs/strings/builder.js.map +1 -1
  185. package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
  186. package/dist/gs/sync/atomic/type.gs.js +0 -2
  187. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  188. package/dist/gs/sync/sync.d.ts +2 -0
  189. package/dist/gs/sync/sync.js +27 -0
  190. package/dist/gs/sync/sync.js.map +1 -1
  191. package/dist/gs/syscall/constants.d.ts +36 -24
  192. package/dist/gs/syscall/constants.js +12 -0
  193. package/dist/gs/syscall/constants.js.map +1 -1
  194. package/dist/gs/syscall/errors.d.ts +2 -0
  195. package/dist/gs/syscall/errors.js +8 -0
  196. package/dist/gs/syscall/errors.js.map +1 -1
  197. package/dist/gs/syscall/fs.d.ts +43 -0
  198. package/dist/gs/syscall/fs.js +102 -0
  199. package/dist/gs/syscall/fs.js.map +1 -1
  200. package/dist/gs/syscall/js/index.d.ts +90 -0
  201. package/dist/gs/syscall/js/index.js +375 -0
  202. package/dist/gs/syscall/js/index.js.map +1 -0
  203. package/dist/gs/syscall/types.d.ts +22 -0
  204. package/dist/gs/syscall/types.js +45 -1
  205. package/dist/gs/syscall/types.js.map +1 -1
  206. package/dist/gs/testing/index.d.ts +1 -0
  207. package/dist/gs/testing/index.js +2 -0
  208. package/dist/gs/testing/index.js.map +1 -0
  209. package/dist/gs/testing/testing.d.ts +77 -0
  210. package/dist/gs/testing/testing.js +301 -0
  211. package/dist/gs/testing/testing.js.map +1 -0
  212. package/dist/gs/time/time.d.ts +41 -4
  213. package/dist/gs/time/time.js +205 -36
  214. package/dist/gs/time/time.js.map +1 -1
  215. package/dist/gs/unicode/unicode.d.ts +23 -1
  216. package/dist/gs/unicode/unicode.js +79 -10
  217. package/dist/gs/unicode/unicode.js.map +1 -1
  218. package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
  219. package/dist/gs/unicode/utf8/utf8.js +24 -11
  220. package/dist/gs/unicode/utf8/utf8.js.map +1 -1
  221. package/dist/gs/unique/index.d.ts +11 -0
  222. package/dist/gs/unique/index.js +71 -0
  223. package/dist/gs/unique/index.js.map +1 -0
  224. package/go.sum +9 -0
  225. package/gs/builtin/builtin.ts +239 -8
  226. package/gs/builtin/channel.ts +22 -0
  227. package/gs/builtin/runtime-contract.test.ts +126 -0
  228. package/gs/builtin/slice.ts +259 -50
  229. package/gs/builtin/type.ts +109 -34
  230. package/gs/builtin/varRef.ts +38 -1
  231. package/gs/bytes/buffer.gs.ts +48 -44
  232. package/gs/bytes/meta.json +8 -3
  233. package/gs/bytes/reader.gs.ts +20 -19
  234. package/gs/context/context.test.ts +41 -0
  235. package/gs/context/context.ts +22 -26
  236. package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
  237. package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
  238. package/gs/embed/index.ts +20 -0
  239. package/gs/embed/meta.json +5 -0
  240. package/gs/encoding/json/index.test.ts +15 -1
  241. package/gs/encoding/json/index.ts +24 -0
  242. package/gs/errors/errors.test.ts +82 -0
  243. package/gs/errors/errors.ts +104 -0
  244. package/gs/fmt/fmt.ts +56 -16
  245. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +73 -1
  246. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +297 -1
  247. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +159 -0
  248. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1005 -0
  249. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +719 -0
  250. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +40 -0
  251. package/gs/github.com/klauspost/compress/internal/le/index.test.ts +36 -0
  252. package/gs/github.com/klauspost/compress/internal/le/index.ts +114 -0
  253. package/gs/go/internal/scannerhooks/index.test.ts +14 -0
  254. package/gs/go/internal/scannerhooks/index.ts +9 -0
  255. package/gs/go/scanner/index.test.ts +22 -0
  256. package/gs/go/scanner/index.ts +47 -0
  257. package/gs/go/token/index.test.ts +47 -1
  258. package/gs/go/token/index.ts +570 -4
  259. package/gs/internal/abi/index.test.ts +18 -0
  260. package/gs/internal/abi/index.ts +14 -0
  261. package/gs/internal/bytealg/index.test.ts +18 -0
  262. package/gs/internal/bytealg/index.ts +16 -0
  263. package/gs/internal/byteorder/index.test.ts +39 -0
  264. package/gs/internal/byteorder/index.ts +100 -27
  265. package/gs/internal/godebug/index.test.ts +16 -0
  266. package/gs/internal/godebug/index.ts +35 -0
  267. package/gs/io/fs/index.ts +1 -0
  268. package/gs/io/fs/meta.json +5 -0
  269. package/gs/io/fs/readlink.test.ts +43 -0
  270. package/gs/io/fs/readlink.ts +77 -0
  271. package/gs/io/fs/walk.test.ts +61 -0
  272. package/gs/io/fs/walk.ts +9 -9
  273. package/gs/io/io.ts +174 -31
  274. package/gs/io/meta.json +10 -2
  275. package/gs/maps/iter.ts +12 -6
  276. package/gs/maps/maps.ts +8 -6
  277. package/gs/math/bits/index.ts +103 -47
  278. package/gs/math/const.gs.test.ts +11 -5
  279. package/gs/math/const.gs.ts +5 -6
  280. package/gs/mime/index.ts +54 -0
  281. package/gs/net/http/httptest/index.ts +25 -0
  282. package/gs/net/http/index.test.ts +20 -0
  283. package/gs/net/http/index.ts +81 -0
  284. package/gs/os/dir_unix.gs.ts +2 -3
  285. package/gs/os/types_js.gs.ts +2 -2
  286. package/gs/path/filepath/match.test.ts +31 -12
  287. package/gs/path/filepath/match.ts +178 -3
  288. package/gs/path/filepath/path.test.ts +25 -0
  289. package/gs/path/filepath/path.ts +159 -5
  290. package/gs/path/path.ts +20 -5
  291. package/gs/reflect/index.ts +1 -0
  292. package/gs/reflect/map.test.ts +19 -0
  293. package/gs/reflect/map.ts +4 -0
  294. package/gs/reflect/type.ts +197 -17
  295. package/gs/runtime/debug/index.test.ts +24 -0
  296. package/gs/runtime/debug/index.ts +8 -0
  297. package/gs/runtime/runtime.test.ts +19 -0
  298. package/gs/runtime/runtime.ts +98 -3
  299. package/gs/slices/slices.test.ts +94 -0
  300. package/gs/slices/slices.ts +245 -5
  301. package/gs/sort/meta.json +7 -0
  302. package/gs/sort/slice.gs.ts +16 -7
  303. package/gs/sort/sort.gs.ts +16 -13
  304. package/gs/strings/builder.ts +4 -3
  305. package/gs/sync/atomic/type.gs.ts +13 -14
  306. package/gs/sync/meta.json +3 -1
  307. package/gs/sync/sync.test.ts +13 -1
  308. package/gs/sync/sync.ts +27 -0
  309. package/gs/syscall/constants.ts +39 -24
  310. package/gs/syscall/errors.ts +10 -0
  311. package/gs/syscall/fs.ts +195 -0
  312. package/gs/syscall/js/index.ts +458 -0
  313. package/gs/syscall/js/meta.json +4 -0
  314. package/gs/syscall/net.test.ts +85 -0
  315. package/gs/syscall/types.ts +56 -0
  316. package/gs/testing/index.ts +1 -0
  317. package/gs/testing/meta.json +5 -0
  318. package/gs/testing/testing.test.ts +90 -0
  319. package/gs/testing/testing.ts +382 -0
  320. package/gs/time/time.test.ts +106 -0
  321. package/gs/time/time.ts +278 -57
  322. package/gs/unicode/unicode.test.ts +25 -0
  323. package/gs/unicode/unicode.ts +119 -9
  324. package/gs/unicode/utf8/utf8.test.ts +13 -0
  325. package/gs/unicode/utf8/utf8.ts +28 -16
  326. package/gs/unique/index.ts +91 -0
  327. package/package.json +2 -1
@@ -0,0 +1,382 @@
1
+ import { mkdirSync } from 'node:fs'
2
+ import { tmpdir } from 'node:os'
3
+ import { join } from 'node:path'
4
+
5
+ export type TestFunc = (t: T) => void | Promise<void>
6
+ export type TB = T | B | F
7
+
8
+ export type TestCase = {
9
+ name: string
10
+ fn: TestFunc
11
+ }
12
+
13
+ export type RunOptions = {
14
+ verbose?: boolean
15
+ count?: number
16
+ short?: boolean
17
+ }
18
+
19
+ export type RunResult = {
20
+ ok: boolean
21
+ failed: number
22
+ skipped: number
23
+ }
24
+
25
+ class TestControl extends Error {
26
+ public readonly kind: 'fatal' | 'skip'
27
+
28
+ constructor(kind: 'fatal' | 'skip', message: string) {
29
+ super(message)
30
+ this.kind = kind
31
+ }
32
+ }
33
+
34
+ let shortMode = false
35
+
36
+ export class T {
37
+ private readonly testName: string
38
+ private failed = false
39
+ private skipped = false
40
+ private logs: string[] = []
41
+ private cleanups: (() => void | Promise<void>)[] = []
42
+ private tempDirs: string[] = []
43
+
44
+ constructor(name: string) {
45
+ this.testName = name
46
+ }
47
+
48
+ public Name(): string {
49
+ return this.testName
50
+ }
51
+
52
+ public Fail(): void {
53
+ this.failed = true
54
+ }
55
+
56
+ public FailNow(): never {
57
+ this.failed = true
58
+ throw new TestControl('fatal', 'test failed')
59
+ }
60
+
61
+ public Failed(): boolean {
62
+ return this.failed
63
+ }
64
+
65
+ public Error(...args: unknown[]): void {
66
+ this.Log(...args)
67
+ this.Fail()
68
+ }
69
+
70
+ public Errorf(format: string, ...args: unknown[]): void {
71
+ this.Log(formatMessage(format, args))
72
+ this.Fail()
73
+ }
74
+
75
+ public Fatal(...args: unknown[]): never {
76
+ this.Log(...args)
77
+ this.FailNow()
78
+ }
79
+
80
+ public Fatalf(format: string, ...args: unknown[]): never {
81
+ this.Log(formatMessage(format, args))
82
+ this.FailNow()
83
+ }
84
+
85
+ public Log(...args: unknown[]): void {
86
+ this.logs.push(args.map(formatValue).join(' '))
87
+ }
88
+
89
+ public Logf(format: string, ...args: unknown[]): void {
90
+ this.logs.push(formatMessage(format, args))
91
+ }
92
+
93
+ public Skip(...args: unknown[]): never {
94
+ this.Log(...args)
95
+ this.SkipNow()
96
+ }
97
+
98
+ public Skipf(format: string, ...args: unknown[]): never {
99
+ this.Log(formatMessage(format, args))
100
+ this.SkipNow()
101
+ }
102
+
103
+ public SkipNow(): never {
104
+ this.skipped = true
105
+ throw new TestControl('skip', 'test skipped')
106
+ }
107
+
108
+ public Skipped(): boolean {
109
+ return this.skipped
110
+ }
111
+
112
+ public Helper(): void {}
113
+
114
+ public Cleanup(fn: () => void | Promise<void>): void {
115
+ this.cleanups.push(fn)
116
+ }
117
+
118
+ public async Run(name: string, fn: TestFunc): Promise<boolean> {
119
+ const child = new T(this.testName + '/' + name)
120
+ try {
121
+ await fn(child)
122
+ } catch (err) {
123
+ if (err instanceof TestControl && err.kind === 'skip') {
124
+ // A skipped subtest is still a successful Run result.
125
+ } else {
126
+ child.Fail()
127
+ if (!(err instanceof TestControl)) {
128
+ child.Log(formatValue(err))
129
+ }
130
+ }
131
+ }
132
+ try {
133
+ await child.runCleanups()
134
+ } catch (err) {
135
+ child.Fail()
136
+ if (!(err instanceof TestControl)) {
137
+ child.Log(formatValue(err))
138
+ }
139
+ }
140
+ if (child.Failed()) {
141
+ this.Fail()
142
+ child.flushLogs()
143
+ return false
144
+ }
145
+ return true
146
+ }
147
+
148
+ public TempDir(): string {
149
+ const path = join(
150
+ tmpdir(),
151
+ 'goscript-test-' +
152
+ this.testName.replace(/[^A-Za-z0-9_.-]/g, '_') +
153
+ '-' +
154
+ String(this.tempDirs.length),
155
+ )
156
+ mkdirSync(path, { recursive: true })
157
+ this.tempDirs.push(path)
158
+ return path
159
+ }
160
+
161
+ public Parallel(): never {
162
+ throw new TestControl(
163
+ 'fatal',
164
+ 'testing.T.Parallel is not supported by GoScript test',
165
+ )
166
+ }
167
+
168
+ public Setenv(key: string, value: string): void {
169
+ const proc = (globalThis as any).process as
170
+ | { env?: Record<string, string | undefined> }
171
+ | undefined
172
+ const env = proc?.env
173
+ if (env === undefined) {
174
+ return
175
+ }
176
+ const oldValue = env[key]
177
+ env[key] = value
178
+ this.Cleanup(() => {
179
+ if (oldValue === undefined) {
180
+ delete env[key]
181
+ return
182
+ }
183
+ env[key] = oldValue
184
+ })
185
+ }
186
+
187
+ public Chdir(dir: string): void {
188
+ const proc = (globalThis as any).process as
189
+ | { cwd?: () => string; chdir?: (dir: string) => void }
190
+ | undefined
191
+ if (proc?.cwd === undefined || proc.chdir === undefined) {
192
+ return
193
+ }
194
+ const oldDir = proc.cwd()
195
+ proc.chdir(dir)
196
+ this.Cleanup(() => {
197
+ proc.chdir!(oldDir)
198
+ })
199
+ }
200
+
201
+ public ArtifactDir(): string {
202
+ return this.TempDir()
203
+ }
204
+
205
+ public Attr(_key: string, _value: string): void {}
206
+
207
+ public Context(): null {
208
+ return null
209
+ }
210
+
211
+ public Output(): null {
212
+ return null
213
+ }
214
+
215
+ public private(): void {}
216
+
217
+ public async runCleanups(): Promise<void> {
218
+ for (let i = this.cleanups.length - 1; i >= 0; i--) {
219
+ await this.cleanups[i]()
220
+ }
221
+ }
222
+
223
+ public flushLogs(): void {
224
+ for (const line of this.logs) {
225
+ console.log(' ' + line)
226
+ }
227
+ }
228
+ }
229
+
230
+ export class B extends T {
231
+ public N = 1
232
+
233
+ constructor(name = 'Benchmark') {
234
+ super(name)
235
+ }
236
+
237
+ public async Run(
238
+ name: string,
239
+ fn: (b: B) => void | Promise<void>,
240
+ ): Promise<boolean> {
241
+ const child = new B(this.Name() + '/' + name)
242
+ child.N = this.N
243
+ try {
244
+ await fn(child)
245
+ } catch (err) {
246
+ child.Error(err)
247
+ }
248
+ if (child.Failed()) {
249
+ this.Fail()
250
+ return false
251
+ }
252
+ return true
253
+ }
254
+
255
+ public StartTimer(): void {}
256
+
257
+ public StopTimer(): void {}
258
+
259
+ public ResetTimer(): void {}
260
+
261
+ public ReportAllocs(): void {}
262
+
263
+ public SetBytes(_bytes: number): void {}
264
+
265
+ public ReportMetric(_n: number, _unit: string): void {}
266
+
267
+ public RunParallel(_fn: (pb: PB) => void): void {}
268
+
269
+ public Loop(): boolean {
270
+ if (this.N > 0) {
271
+ this.N--
272
+ return true
273
+ }
274
+ return false
275
+ }
276
+ }
277
+
278
+ export class F extends T {
279
+ constructor(name = 'Fuzz') {
280
+ super(name)
281
+ }
282
+
283
+ public Add(..._args: unknown[]): void {}
284
+
285
+ public Fuzz(_fn: unknown): void {}
286
+ }
287
+
288
+ export class PB {
289
+ private remaining = 1
290
+
291
+ public Next(): boolean {
292
+ if (this.remaining > 0) {
293
+ this.remaining--
294
+ return true
295
+ }
296
+ return false
297
+ }
298
+ }
299
+
300
+ export function Short(): boolean {
301
+ return shortMode
302
+ }
303
+
304
+ export async function runTests(
305
+ packagePath: string,
306
+ tests: TestCase[],
307
+ options: RunOptions = {},
308
+ ): Promise<RunResult> {
309
+ const previousShortMode = shortMode
310
+ shortMode = options.short ?? false
311
+ const count = options.count ?? 1
312
+ let failed = 0
313
+ let skipped = 0
314
+ try {
315
+ for (let run = 0; run < count; run++) {
316
+ for (const test of tests) {
317
+ if (options.verbose) {
318
+ console.log('=== RUN ' + test.name)
319
+ }
320
+ const t = new T(test.name)
321
+ const start = Date.now()
322
+ try {
323
+ await test.fn(t)
324
+ } catch (err) {
325
+ if (err instanceof TestControl && err.kind === 'skip') {
326
+ skipped++
327
+ } else {
328
+ t.Fail()
329
+ if (!(err instanceof TestControl)) {
330
+ t.Log(formatValue(err))
331
+ }
332
+ }
333
+ } finally {
334
+ await t.runCleanups()
335
+ }
336
+ const elapsed = ((Date.now() - start) / 1000).toFixed(2)
337
+ if (t.Skipped()) {
338
+ if (options.verbose) {
339
+ t.flushLogs()
340
+ }
341
+ console.log('--- SKIP: ' + test.name + ' (' + elapsed + 's)')
342
+ continue
343
+ }
344
+ if (t.Failed()) {
345
+ failed++
346
+ t.flushLogs()
347
+ console.log('--- FAIL: ' + test.name + ' (' + elapsed + 's)')
348
+ continue
349
+ }
350
+ if (options.verbose) {
351
+ t.flushLogs()
352
+ console.log('--- PASS: ' + test.name + ' (' + elapsed + 's)')
353
+ }
354
+ }
355
+ }
356
+ if (failed === 0) {
357
+ if (options.verbose) {
358
+ console.log('PASS')
359
+ }
360
+ return { ok: true, failed, skipped }
361
+ }
362
+ console.log('FAIL\t' + packagePath)
363
+ return { ok: false, failed, skipped }
364
+ } finally {
365
+ shortMode = previousShortMode
366
+ }
367
+ }
368
+
369
+ function formatMessage(format: string, args: unknown[]): string {
370
+ let index = 0
371
+ return format.replace(/%[vds]/g, () => formatValue(args[index++]))
372
+ }
373
+
374
+ function formatValue(value: unknown): string {
375
+ if (value instanceof Error) {
376
+ return value.message
377
+ }
378
+ if (value === null) {
379
+ return '<nil>'
380
+ }
381
+ return String(value)
382
+ }
@@ -0,0 +1,106 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import * as $ from '@goscript/builtin/index.js'
4
+
5
+ import {
6
+ Duration_Abs,
7
+ Duration_Hours,
8
+ Duration_Microseconds,
9
+ Duration_Milliseconds,
10
+ Duration_Minutes,
11
+ Duration_Nanoseconds,
12
+ Duration_Round,
13
+ Duration_Seconds,
14
+ Duration_String,
15
+ Duration_Truncate,
16
+ FixedZone,
17
+ January,
18
+ Microsecond,
19
+ Millisecond,
20
+ Minute,
21
+ NewTicker,
22
+ NewTimer,
23
+ RFC3339Nano,
24
+ Second,
25
+ Date,
26
+ May,
27
+ RFC3339,
28
+ Time,
29
+ UTC,
30
+ } from './time.js'
31
+
32
+ describe('time.Duration_String', () => {
33
+ it('formats common durations', () => {
34
+ expect(Duration_String(0)).toBe('0s')
35
+ expect(Duration_String(1500 * Millisecond)).toBe('1.5s')
36
+ expect(Duration_String(-1500 * Millisecond)).toBe('-1.5s')
37
+ expect(Duration_String(2 * Second)).toBe('2s')
38
+ })
39
+ })
40
+
41
+ describe('time.Duration methods', () => {
42
+ it('converts to integer and fractional units', () => {
43
+ expect(Duration_Nanoseconds(1500 * Microsecond)).toBe(1500000)
44
+ expect(Duration_Microseconds(1500 * Microsecond)).toBe(1500)
45
+ expect(Duration_Milliseconds(1500 * Microsecond)).toBe(1)
46
+ expect(Duration_Seconds(1500 * Millisecond)).toBe(1.5)
47
+ expect(Duration_Minutes(90 * Second)).toBe(1.5)
48
+ expect(Duration_Hours(90 * Minute)).toBe(1.5)
49
+ })
50
+
51
+ it('rounds and truncates with Go duration semantics', () => {
52
+ expect(Duration_Truncate(1500 * Millisecond, Second)).toBe(Second)
53
+ expect(Duration_Truncate(-1500 * Millisecond, Second)).toBe(-Second)
54
+ expect(Duration_Round(1500 * Millisecond, Second)).toBe(2 * Second)
55
+ expect(Duration_Round(-1500 * Millisecond, Second)).toBe(-2 * Second)
56
+ expect(Duration_Round(1500 * Millisecond, 0)).toBe(1500 * Millisecond)
57
+ })
58
+
59
+ it('returns absolute values', () => {
60
+ expect(Duration_Abs(2 * Second)).toBe(2 * Second)
61
+ expect(Duration_Abs(-2 * Second)).toBe(2 * Second)
62
+ })
63
+ })
64
+
65
+ describe('time constants and timers', () => {
66
+ it('exports RFC3339Nano', () => {
67
+ expect(RFC3339Nano).toBe('2006-01-02T15:04:05.999999999Z07:00')
68
+ })
69
+
70
+ it('exports month constants directly', () => {
71
+ expect(January).toBe(1)
72
+ })
73
+
74
+ it('delivers NewTimer values on C', async () => {
75
+ const timer = NewTimer(0)
76
+ const value = await timer.C.receive()
77
+
78
+ expect(value.Unix()).toBeGreaterThan(0)
79
+ })
80
+
81
+ it('delivers NewTicker values on C', async () => {
82
+ const ticker = NewTicker(0)
83
+ const value = await ticker.C.receive()
84
+ ticker.Stop()
85
+
86
+ expect(value.Unix()).toBeGreaterThan(0)
87
+ })
88
+ })
89
+
90
+ describe('time.Time.In', () => {
91
+ it('returns the same instant in another fixed location', () => {
92
+ const utc = Date(2025, May, 15, 1, 10, 42, 0, UTC)
93
+ const pdt = FixedZone('PDT', -7 * 60 * 60)
94
+
95
+ expect(utc.In(pdt).Format(RFC3339)).toBe('2025-05-14T18:10:42-07:00')
96
+ expect(utc.In($.varRef(pdt)).Format(RFC3339)).toBe(
97
+ '2025-05-14T18:10:42-07:00',
98
+ )
99
+ })
100
+
101
+ it('panics for nil locations', () => {
102
+ expect(() => new Time().In(null)).toThrow(
103
+ 'time: missing Location in call to Time.In',
104
+ )
105
+ })
106
+ })