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,627 @@
1
+ package gotest
2
+
3
+ import (
4
+ "context"
5
+ "os"
6
+ "path/filepath"
7
+ "strings"
8
+ "testing"
9
+ "time"
10
+ )
11
+
12
+ func TestRunnerRunsOrdinaryPackageTest(t *testing.T) {
13
+ moduleDir := writeFixture(t, map[string]string{
14
+ "go.mod": "module example.test/gotest\n\ngo 1.25.3\n",
15
+ "value.go": strings.Join([]string{
16
+ "package gotest",
17
+ "",
18
+ "func Add(a int, b int) int {",
19
+ "\treturn a + b",
20
+ "}",
21
+ "",
22
+ }, "\n"),
23
+ "value_test.go": strings.Join([]string{
24
+ "package gotest",
25
+ "",
26
+ "import \"testing\"",
27
+ "",
28
+ "func TestAdd(t *testing.T) {",
29
+ "\tif Add(1, 2) != 3 {",
30
+ "\t\tt.Fatalf(\"unexpected sum\")",
31
+ "\t}",
32
+ "}",
33
+ "",
34
+ }, "\n"),
35
+ })
36
+
37
+ result, err := NewRunner().Run(context.Background(), &Request{
38
+ Dir: moduleDir,
39
+ Patterns: []string{"."},
40
+ Timeout: 30 * time.Second,
41
+ Verbose: true,
42
+ })
43
+ if err != nil {
44
+ t.Fatalf("run package test: %v", err)
45
+ }
46
+ if !result.Passed() {
47
+ t.Fatalf("expected package test to pass: %#v", result.Packages)
48
+ }
49
+ if len(result.Packages) != 1 || len(result.Packages[0].Tests) != 1 {
50
+ t.Fatalf("unexpected package results: %#v", result.Packages)
51
+ }
52
+ if result.Packages[0].Tests[0].Name != "TestAdd" {
53
+ t.Fatalf("unexpected test discovery: %#v", result.Packages[0].Tests)
54
+ }
55
+ if result.Packages[0].Phases.Workspace != PhaseStatusPass ||
56
+ result.Packages[0].Phases.Compile != PhaseStatusPass ||
57
+ result.Packages[0].Phases.Emit != PhaseStatusPass ||
58
+ result.Packages[0].Phases.TypeCheck != PhaseStatusPass ||
59
+ result.Packages[0].Phases.Runtime != PhaseStatusPass {
60
+ t.Fatalf("unexpected phase status: %#v", result.Packages[0].Phases)
61
+ }
62
+ }
63
+
64
+ func TestRunnerReportsShortMode(t *testing.T) {
65
+ moduleDir := writeFixture(t, map[string]string{
66
+ "go.mod": "module example.test/short\n\ngo 1.25.3\n",
67
+ "value_test.go": strings.Join([]string{
68
+ "package short",
69
+ "",
70
+ "import \"testing\"",
71
+ "",
72
+ "func TestShort(t *testing.T) {",
73
+ "\tif !testing.Short() {",
74
+ "\t\tt.Fatalf(\"expected short mode\")",
75
+ "\t}",
76
+ "}",
77
+ "",
78
+ }, "\n"),
79
+ })
80
+
81
+ result, err := NewRunner().Run(context.Background(), &Request{
82
+ Dir: moduleDir,
83
+ Patterns: []string{"."},
84
+ Short: true,
85
+ Timeout: 30 * time.Second,
86
+ })
87
+ if err != nil {
88
+ t.Fatalf("run short package: %v", err)
89
+ }
90
+ if !result.Passed() {
91
+ t.Fatalf("expected short package to pass: %#v", result.Packages)
92
+ }
93
+ }
94
+
95
+ func TestRunnerRunsAsyncSubtest(t *testing.T) {
96
+ moduleDir := writeFixture(t, map[string]string{
97
+ "go.mod": "module example.test/asyncsubtest\n\ngo 1.25.3\n",
98
+ "value_test.go": strings.Join([]string{
99
+ "package asyncsubtest",
100
+ "",
101
+ "import \"testing\"",
102
+ "",
103
+ "func TestAsyncSubtest(t *testing.T) {",
104
+ "\tt.Run(\"child\", func(t *testing.T) {",
105
+ "\t\tch := make(chan string, 1)",
106
+ "\t\tch <- \"ok\"",
107
+ "\t\tif <-ch != \"ok\" {",
108
+ "\t\t\tt.Fatalf(\"unexpected channel value\")",
109
+ "\t\t}",
110
+ "\t})",
111
+ "}",
112
+ "",
113
+ }, "\n"),
114
+ })
115
+
116
+ result, err := NewRunner().Run(context.Background(), &Request{
117
+ Dir: moduleDir,
118
+ Patterns: []string{"."},
119
+ Timeout: 30 * time.Second,
120
+ })
121
+ if err != nil {
122
+ t.Fatalf("run async subtest package: %v", err)
123
+ }
124
+ if !result.Passed() {
125
+ t.Fatalf("expected async subtest to pass: %#v", result.Packages)
126
+ }
127
+ }
128
+
129
+ func TestRunnerAwaitsAsyncDependencyCallsInTests(t *testing.T) {
130
+ moduleDir := writeFixture(t, map[string]string{
131
+ "go.mod": "module example.test/asyncdep\n\ngo 1.25.3\n",
132
+ "value_test.go": strings.Join([]string{
133
+ "package asyncdep",
134
+ "",
135
+ "import (",
136
+ "\t\"math/rand\"",
137
+ "\t\"testing\"",
138
+ ")",
139
+ "",
140
+ "func TestAsyncDependencyCall(t *testing.T) {",
141
+ "\tr := rand.New(rand.NewSource(1))",
142
+ "\t_ = uint8(r.Intn(256))",
143
+ "}",
144
+ "",
145
+ }, "\n"),
146
+ })
147
+
148
+ result, err := NewRunner().Run(context.Background(), &Request{
149
+ Dir: moduleDir,
150
+ Patterns: []string{"."},
151
+ Timeout: 30 * time.Second,
152
+ })
153
+ if err != nil {
154
+ t.Fatalf("run async dependency package: %v", err)
155
+ }
156
+ if !result.Passed() {
157
+ t.Fatalf("expected async dependency package to pass: %#v", result.Packages)
158
+ }
159
+ }
160
+
161
+ func TestRunnerRunsExternalPackageTest(t *testing.T) {
162
+ moduleDir := writeFixture(t, map[string]string{
163
+ "go.mod": "module example.test/external\n\ngo 1.25.3\n",
164
+ "value.go": strings.Join([]string{
165
+ "package external",
166
+ "",
167
+ "func Add(a int, b int) int {",
168
+ "\treturn a + b",
169
+ "}",
170
+ "",
171
+ }, "\n"),
172
+ "value_test.go": strings.Join([]string{
173
+ "package external_test",
174
+ "",
175
+ "import (",
176
+ "\t\"testing\"",
177
+ "",
178
+ "\texternal \"example.test/external\"",
179
+ ")",
180
+ "",
181
+ "func TestExternalAdd(t *testing.T) {",
182
+ "\tif external.Add(4, 5) != 9 {",
183
+ "\t\tt.Fatalf(\"unexpected sum\")",
184
+ "\t}",
185
+ "}",
186
+ "",
187
+ }, "\n"),
188
+ })
189
+
190
+ result, err := NewRunner().Run(context.Background(), &Request{
191
+ Dir: moduleDir,
192
+ Patterns: []string{"."},
193
+ Timeout: 30 * time.Second,
194
+ })
195
+ if err != nil {
196
+ t.Fatalf("run external package test: %v", err)
197
+ }
198
+ if !result.Passed() {
199
+ t.Fatalf("expected external package test to pass: %#v", result.Packages)
200
+ }
201
+ if len(result.Packages) != 1 || len(result.Packages[0].Tests) != 1 {
202
+ t.Fatalf("unexpected package results: %#v", result.Packages)
203
+ }
204
+ if result.Packages[0].TestPackagePath == "" {
205
+ t.Fatalf("expected test package path: %#v", result.Packages[0])
206
+ }
207
+ }
208
+
209
+ func TestRunnerRejectsInvalidRunPattern(t *testing.T) {
210
+ moduleDir := writeFixture(t, map[string]string{
211
+ "go.mod": "module example.test/badrun\n\ngo 1.25.3\n",
212
+ "value.go": "package badrun\n",
213
+ })
214
+
215
+ result, err := NewRunner().Run(context.Background(), &Request{
216
+ Dir: moduleDir,
217
+ Patterns: []string{"."},
218
+ Run: "[",
219
+ })
220
+ if err != nil {
221
+ t.Fatalf("run package test: %v", err)
222
+ }
223
+ if result.Passed() {
224
+ t.Fatalf("expected invalid run pattern to fail")
225
+ }
226
+ if result.Packages[0].Owner != OwnerPackageGraph {
227
+ t.Fatalf("unexpected owner classification: %#v", result.Packages[0])
228
+ }
229
+ if len(result.Diagnostics) != 1 || result.Diagnostics[0].Code != "goscript/gotest:run-pattern" {
230
+ t.Fatalf("expected structured run-pattern diagnostic: %#v", result.Diagnostics)
231
+ }
232
+ }
233
+
234
+ func TestRunnerFailsPackagePatternsWhenGraphHasOnlyDiagnostics(t *testing.T) {
235
+ moduleDir := writeFixture(t, map[string]string{
236
+ "go.mod": "module example.test/missing\n\ngo 1.25.3\n",
237
+ "value.go": "package missing\n",
238
+ })
239
+
240
+ result, err := NewRunner().Run(context.Background(), &Request{
241
+ Dir: moduleDir,
242
+ Patterns: []string{"./does-not-exist"},
243
+ Timeout: 30 * time.Second,
244
+ })
245
+ if err != nil {
246
+ t.Fatalf("run missing package test: %v", err)
247
+ }
248
+ if result.Passed() {
249
+ t.Fatalf("expected missing package pattern to fail")
250
+ }
251
+ if len(result.Packages) != 1 || result.Packages[0].Owner != OwnerPackageGraph {
252
+ t.Fatalf("unexpected package graph failure: %#v", result.Packages)
253
+ }
254
+ }
255
+
256
+ func TestMarkAllFailuresPreservesExistingPackageOwners(t *testing.T) {
257
+ result := &Result{Packages: []PackageResult{
258
+ {
259
+ PackagePath: "example.test/broken",
260
+ Action: ActionFail,
261
+ Owner: OwnerPackageGraph,
262
+ Error: "load failed",
263
+ },
264
+ {
265
+ PackagePath: "example.test/run",
266
+ Action: ActionFail,
267
+ },
268
+ {
269
+ PackagePath: "example.test/notests",
270
+ Action: ActionSkip,
271
+ },
272
+ }}
273
+
274
+ markAllFailures(result, OwnerTestRunner, "typecheck failed")
275
+
276
+ if result.Packages[0].Owner != OwnerPackageGraph || result.Packages[0].Error != "load failed" {
277
+ t.Fatalf("package graph failure was overwritten: %#v", result.Packages[0])
278
+ }
279
+ if result.Packages[1].Owner != OwnerTestRunner || result.Packages[1].Error != "typecheck failed" {
280
+ t.Fatalf("unowned failure was not marked: %#v", result.Packages[1])
281
+ }
282
+ if result.Packages[2].Action != ActionSkip || result.Packages[2].Owner != "" {
283
+ t.Fatalf("skipped package should stay skipped: %#v", result.Packages[2])
284
+ }
285
+ }
286
+
287
+ func TestRunnerScopesPackageLoadErrors(t *testing.T) {
288
+ moduleDir := writeFixture(t, map[string]string{
289
+ "go.mod": "module example.test/mixed\n\ngo 1.25.3\n",
290
+ "clean/value.go": strings.Join([]string{
291
+ "package clean",
292
+ "",
293
+ "func Value() int { return 11 }",
294
+ "",
295
+ }, "\n"),
296
+ "clean/value_test.go": strings.Join([]string{
297
+ "package clean",
298
+ "",
299
+ "import \"testing\"",
300
+ "",
301
+ "func TestValue(t *testing.T) {",
302
+ "\tif Value() != 11 {",
303
+ "\t\tt.Fatal(\"bad value\")",
304
+ "\t}",
305
+ "}",
306
+ "",
307
+ }, "\n"),
308
+ "broken/value.go": "package broken\nfunc Value() int { return 12 }\n",
309
+ "broken/value_test.go": strings.Join([]string{
310
+ "package broken",
311
+ "",
312
+ "import \"testing\"",
313
+ "",
314
+ "func TestBroken(t *testing.T) {",
315
+ "\tMissing()",
316
+ "}",
317
+ "",
318
+ }, "\n"),
319
+ "notests/value.go": "package notests\nfunc Value() int { return 13 }\n",
320
+ })
321
+
322
+ result, err := NewRunner().Run(context.Background(), &Request{
323
+ Dir: moduleDir,
324
+ Patterns: []string{"./..."},
325
+ Timeout: 30 * time.Second,
326
+ })
327
+ if err != nil {
328
+ t.Fatalf("run mixed package tests: %v", err)
329
+ }
330
+
331
+ clean := requirePackageResult(t, result, "example.test/mixed/clean")
332
+ if clean.Action != ActionPass {
333
+ t.Fatalf("clean package should pass independently: %#v", clean)
334
+ }
335
+ broken := requirePackageResult(t, result, "example.test/mixed/broken")
336
+ if broken.Action != ActionFail || broken.Owner != OwnerPackageGraph {
337
+ t.Fatalf("broken package should carry package graph failure: %#v", broken)
338
+ }
339
+ if broken.Phases.Compile != PhaseStatusFail {
340
+ t.Fatalf("broken package should carry compile phase failure: %#v", broken)
341
+ }
342
+ if !strings.Contains(broken.Error, "Missing") {
343
+ t.Fatalf("broken package error should preserve load diagnostic: %#v", broken)
344
+ }
345
+ noTests := requirePackageResult(t, result, "example.test/mixed/notests")
346
+ if noTests.Action != ActionSkip {
347
+ t.Fatalf("no-test package should stay skipped: %#v", noTests)
348
+ }
349
+ }
350
+
351
+ func TestRunnerScopesPackageCompileErrors(t *testing.T) {
352
+ moduleDir := writeFixture(t, map[string]string{
353
+ "go.mod": "module example.test/mixedcompile\n\ngo 1.25.3\n",
354
+ "clean/value.go": strings.Join([]string{
355
+ "package clean",
356
+ "",
357
+ "func Value() int { return 11 }",
358
+ "",
359
+ }, "\n"),
360
+ "clean/value_test.go": strings.Join([]string{
361
+ "package clean",
362
+ "",
363
+ "import \"testing\"",
364
+ "",
365
+ "func TestValue(t *testing.T) {",
366
+ "\tif Value() != 11 {",
367
+ "\t\tt.Fatal(\"bad value\")",
368
+ "\t}",
369
+ "}",
370
+ "",
371
+ }, "\n"),
372
+ "broken/value.go": strings.Join([]string{
373
+ "package broken",
374
+ "",
375
+ "func Value() int {",
376
+ "\tx := 1",
377
+ "\t_ = &(x)",
378
+ "\treturn x",
379
+ "}",
380
+ "",
381
+ }, "\n"),
382
+ "broken/value_test.go": strings.Join([]string{
383
+ "package broken",
384
+ "",
385
+ "import \"testing\"",
386
+ "",
387
+ "func TestBroken(t *testing.T) {",
388
+ "\tif Value() == 0 {",
389
+ "\t\tt.Fatal(\"bad value\")",
390
+ "\t}",
391
+ "}",
392
+ "",
393
+ }, "\n"),
394
+ })
395
+
396
+ result, err := NewRunner().Run(context.Background(), &Request{
397
+ Dir: moduleDir,
398
+ Patterns: []string{"./..."},
399
+ Timeout: 30 * time.Second,
400
+ })
401
+ if err != nil {
402
+ t.Fatalf("run mixed compile test: %v", err)
403
+ }
404
+
405
+ clean := requirePackageResult(t, result, "example.test/mixedcompile/clean")
406
+ if clean.Action != ActionPass {
407
+ t.Fatalf("clean package should pass independently: %#v", clean)
408
+ }
409
+ broken := requirePackageResult(t, result, "example.test/mixedcompile/broken")
410
+ if broken.Action != ActionFail || broken.Owner != OwnerLowering {
411
+ t.Fatalf("broken package should carry lowering failure: %#v", broken)
412
+ }
413
+ if !strings.Contains(broken.Error, "unsupported address expression") {
414
+ t.Fatalf("broken package error should preserve compile diagnostic: %#v", broken)
415
+ }
416
+ }
417
+
418
+ func TestRunnerDoesNotCompileDependencyTests(t *testing.T) {
419
+ moduleDir := writeFixture(t, map[string]string{
420
+ "go.mod": "module example.test/deptest\n\ngo 1.25.3\n",
421
+ "dep/value.go": strings.Join([]string{
422
+ "package dep",
423
+ "",
424
+ "func Value() int { return 11 }",
425
+ "",
426
+ }, "\n"),
427
+ "dep/value_test.go": strings.Join([]string{
428
+ "package dep",
429
+ "",
430
+ "import \"testing\"",
431
+ "",
432
+ "func TestDependencyOnly(t *testing.T) {",
433
+ "Loop:",
434
+ "\tfor {",
435
+ "\t\tbreak Loop",
436
+ "\t}",
437
+ "}",
438
+ "",
439
+ }, "\n"),
440
+ "app/value.go": strings.Join([]string{
441
+ "package app",
442
+ "",
443
+ "import \"example.test/deptest/dep\"",
444
+ "",
445
+ "func Value() int { return dep.Value() }",
446
+ "",
447
+ }, "\n"),
448
+ "app/value_test.go": strings.Join([]string{
449
+ "package app",
450
+ "",
451
+ "import \"testing\"",
452
+ "",
453
+ "func TestValue(t *testing.T) {",
454
+ "\tif Value() != 11 {",
455
+ "\t\tt.Fatal(\"bad value\")",
456
+ "\t}",
457
+ "}",
458
+ "",
459
+ }, "\n"),
460
+ })
461
+
462
+ result, err := NewRunner().Run(context.Background(), &Request{
463
+ Dir: moduleDir,
464
+ Patterns: []string{"./app"},
465
+ Timeout: 30 * time.Second,
466
+ })
467
+ if err != nil {
468
+ t.Fatalf("run dependency test isolation fixture: %v", err)
469
+ }
470
+
471
+ app := requirePackageResult(t, result, "example.test/deptest/app")
472
+ if app.Action != ActionPass {
473
+ t.Fatalf("package under test should ignore dependency-only tests: %#v", app)
474
+ }
475
+ }
476
+
477
+ func TestRunnerScopesPackageTypecheckErrors(t *testing.T) {
478
+ moduleDir := writeFixture(t, map[string]string{
479
+ "go.mod": "module example.test/mixedtypecheck\n\ngo 1.25.3\n",
480
+ "clean/value.go": strings.Join([]string{
481
+ "package clean",
482
+ "",
483
+ "func Value() int { return 11 }",
484
+ "",
485
+ }, "\n"),
486
+ "clean/value_test.go": strings.Join([]string{
487
+ "package clean",
488
+ "",
489
+ "import \"testing\"",
490
+ "",
491
+ "func TestValue(t *testing.T) {",
492
+ "\tif Value() != 11 {",
493
+ "\t\tt.Fatal(\"bad value\")",
494
+ "\t}",
495
+ "}",
496
+ "",
497
+ }, "\n"),
498
+ "bad/value.go": strings.Join([]string{
499
+ "package bad",
500
+ "",
501
+ "func Value() int { return 12 }",
502
+ "",
503
+ }, "\n"),
504
+ "bad/value_test.go": strings.Join([]string{
505
+ "package bad",
506
+ "",
507
+ "import \"testing\"",
508
+ "",
509
+ "func TestBad(t *testing.T) {",
510
+ "\tif Value() != 12 {",
511
+ "\t\tt.Fatal(\"bad value\")",
512
+ "\t}",
513
+ "}",
514
+ "",
515
+ }, "\n"),
516
+ })
517
+ writeExecutable(t, filepath.Join(moduleDir, "node_modules", ".bin", "tsgo"), strings.Join([]string{
518
+ "#!/bin/sh",
519
+ "project=",
520
+ "while [ \"$#\" -gt 0 ]; do",
521
+ "\tif [ \"$1\" = \"--project\" ]; then",
522
+ "\t\tshift",
523
+ "\t\tproject=\"$1\"",
524
+ "\tfi",
525
+ "\tshift || break",
526
+ "done",
527
+ "runner=$(sed -n 's/.*\"\\(runner-[0-9][0-9]*\\.ts\\)\".*/\\1/p' \"$project\" | head -n 1)",
528
+ "if grep -q 'example.test/mixedtypecheck/bad' \"$runner\"; then",
529
+ "\techo 'TypeScript TS9000: bad package'",
530
+ "\texit 1",
531
+ "fi",
532
+ "exit 0",
533
+ "",
534
+ }, "\n"))
535
+ writeExecutable(t, filepath.Join(moduleDir, "node_modules", ".bin", "bun"), strings.Join([]string{
536
+ "#!/bin/sh",
537
+ "exit 0",
538
+ "",
539
+ }, "\n"))
540
+
541
+ result, err := NewRunner().Run(context.Background(), &Request{
542
+ Dir: moduleDir,
543
+ Patterns: []string{"./..."},
544
+ Timeout: 30 * time.Second,
545
+ })
546
+ if err != nil {
547
+ t.Fatalf("run mixed typecheck test: %v", err)
548
+ }
549
+
550
+ clean := requirePackageResult(t, result, "example.test/mixedtypecheck/clean")
551
+ if clean.Action != ActionPass {
552
+ t.Fatalf("clean package should pass independently: %#v", clean)
553
+ }
554
+ bad := requirePackageResult(t, result, "example.test/mixedtypecheck/bad")
555
+ if bad.Action != ActionFail || bad.Owner != OwnerTypeScriptEmitter {
556
+ t.Fatalf("bad package should carry typecheck failure: %#v", bad)
557
+ }
558
+ if !strings.Contains(bad.Error, "TS9000") {
559
+ t.Fatalf("bad package error should preserve typecheck output: %#v", bad)
560
+ }
561
+ }
562
+
563
+ func TestRenderTypeScriptProjectDisablesAmbientTypePackages(t *testing.T) {
564
+ req := &normalizedRequest{
565
+ WorkDir: "/work",
566
+ }
567
+
568
+ tsconfig := renderTypeScriptProject(req, "/work/output/package-0", "runner-0.ts", false)
569
+ if !strings.Contains(tsconfig, "\"types\": []") {
570
+ t.Fatalf("expected generated tsconfig to disable ambient @types packages: %s", tsconfig)
571
+ }
572
+ if !strings.Contains(tsconfig, "\"goscript-node.d.ts\"") {
573
+ t.Fatalf("expected generated tsconfig to include GoScript node ambient declarations: %s", tsconfig)
574
+ }
575
+ }
576
+
577
+ func TestRenderTypeScriptProjectUsesNodeTypesWhenAvailable(t *testing.T) {
578
+ req := &normalizedRequest{
579
+ WorkDir: "/work",
580
+ }
581
+
582
+ tsconfig := renderTypeScriptProject(req, "/work/output/package-0", "runner-0.ts", true)
583
+ if !strings.Contains(tsconfig, "\"types\": [\"node\"]") {
584
+ t.Fatalf("expected generated tsconfig to opt into node types: %s", tsconfig)
585
+ }
586
+ }
587
+
588
+ func requirePackageResult(t *testing.T, result *Result, packagePath string) PackageResult {
589
+ t.Helper()
590
+
591
+ if result != nil {
592
+ for _, pkg := range result.Packages {
593
+ if pkg.PackagePath == packagePath {
594
+ return pkg
595
+ }
596
+ }
597
+ }
598
+ t.Fatalf("missing package result %q in %#v", packagePath, result)
599
+ return PackageResult{}
600
+ }
601
+
602
+ func writeFixture(t *testing.T, files map[string]string) string {
603
+ t.Helper()
604
+
605
+ dir := t.TempDir()
606
+ for name, contents := range files {
607
+ path := filepath.Join(dir, name)
608
+ if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
609
+ t.Fatal(err.Error())
610
+ }
611
+ if err := os.WriteFile(path, []byte(contents), 0o644); err != nil {
612
+ t.Fatal(err.Error())
613
+ }
614
+ }
615
+ return dir
616
+ }
617
+
618
+ func writeExecutable(t *testing.T, path string, contents string) {
619
+ t.Helper()
620
+
621
+ if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
622
+ t.Fatal(err.Error())
623
+ }
624
+ if err := os.WriteFile(path, []byte(contents), 0o755); err != nil {
625
+ t.Fatal(err.Error())
626
+ }
627
+ }
@@ -0,0 +1,9 @@
1
+ package gotest
2
+
3
+ // Test describes one discovered Go test function.
4
+ type Test struct {
5
+ // Name is the Go TestXxx function name.
6
+ Name string
7
+ // PackagePath is the package variant that exports the function.
8
+ PackagePath string
9
+ }
@@ -25,7 +25,7 @@ describe('GoScript Compiler API', () => {
25
25
  })
26
26
 
27
27
  const generated = await readFile(join(output, '@goscript', 'example.test', 'api', 'main.gs.ts'), 'utf8')
28
- expect(generated).toContain('export async function main(): Promise<void>')
28
+ expect(generated).toContain('export async function main(): globalThis.Promise<void>')
29
29
  expect(generated).toContain('$.println("api")')
30
30
  }, 30000)
31
31
  })