From d6842326ad9f4f68d36a23a1df99b00b2f1a0014 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Fri, 17 Oct 2025 06:50:44 +0000 Subject: [PATCH] fix(runtime.node): Improve Node runtime adapter to use tsrun.spawnPath, strengthen tsrun detection, and improve process lifecycle and loader handling; update tsrun dependency. --- changelog.md | 11 ++ cli.js | 0 package.json | 2 +- pnpm-lock.yaml | 226 +++++++++++++++--------------- ts/00_commitinfo_data.ts | 2 +- ts/tstest.classes.runtime.node.ts | 62 ++++---- ts/tstest.plugins.ts | 3 +- 7 files changed, 160 insertions(+), 146 deletions(-) mode change 100644 => 100755 cli.js diff --git a/changelog.md b/changelog.md index c0e6417..8e4dec7 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,16 @@ # Changelog +## 2025-10-17 - 2.5.2 - fix(runtime.node) +Improve Node runtime adapter to use tsrun.spawnPath, strengthen tsrun detection, and improve process lifecycle and loader handling; update tsrun dependency. + +- Use tsrun.spawnPath to spawn Node test processes and pass structured spawn options (cwd, env, args, stdio). +- Detect tsrun availability via plugins.tsrun and require spawnPath; provide a clearer error message when tsrun is missing or outdated. +- Pass --web via spawn args and set TSTEST_FILTER_TAGS on the spawned process env instead of mutating the parent process.env. +- When a 00init.ts exists, create a temporary loader that imports both 00init.ts and the test file, run the loader via tsrun.spawnPath, and clean up the loader after execution. +- Use tsrunProcess.terminate()/kill for timeouts to ensure proper process termination and improve cleanup handling. +- Export tsrun from ts/tstest.plugins.ts so runtime code can access tsrun APIs via the plugins object. +- Bump dependency @git.zone/tsrun from ^1.3.4 to ^1.6.2 in package.json. + ## 2025-10-16 - 2.5.1 - fix(deps) Bump dependencies and add local tooling settings diff --git a/cli.js b/cli.js old mode 100644 new mode 100755 diff --git a/package.json b/package.json index 8c2e932..0e1b443 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "dependencies": { "@api.global/typedserver": "^3.0.79", "@git.zone/tsbundle": "^2.5.1", - "@git.zone/tsrun": "^1.3.4", + "@git.zone/tsrun": "^1.6.2", "@push.rocks/consolecolor": "^2.0.3", "@push.rocks/qenv": "^6.1.3", "@push.rocks/smartbrowser": "^2.0.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f5a4789..1913d2d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,8 +15,8 @@ importers: specifier: ^2.5.1 version: 2.5.1 '@git.zone/tsrun': - specifier: ^1.3.4 - version: 1.3.4 + specifier: ^1.6.2 + version: 1.6.2 '@push.rocks/consolecolor': specifier: ^2.0.3 version: 2.0.3 @@ -425,8 +425,8 @@ packages: '@emnapi/wasi-threads@1.0.4': resolution: {integrity: sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==} - '@esbuild/aix-ppc64@0.25.10': - resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} + '@esbuild/aix-ppc64@0.25.11': + resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -437,8 +437,8 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.10': - resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} + '@esbuild/android-arm64@0.25.11': + resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -449,8 +449,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.10': - resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} + '@esbuild/android-arm@0.25.11': + resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -461,8 +461,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.10': - resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} + '@esbuild/android-x64@0.25.11': + resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -473,8 +473,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.10': - resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} + '@esbuild/darwin-arm64@0.25.11': + resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -485,8 +485,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.10': - resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} + '@esbuild/darwin-x64@0.25.11': + resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -497,8 +497,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.10': - resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} + '@esbuild/freebsd-arm64@0.25.11': + resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -509,8 +509,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.10': - resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} + '@esbuild/freebsd-x64@0.25.11': + resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -521,8 +521,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.10': - resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} + '@esbuild/linux-arm64@0.25.11': + resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -533,8 +533,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.10': - resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} + '@esbuild/linux-arm@0.25.11': + resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -545,8 +545,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.10': - resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} + '@esbuild/linux-ia32@0.25.11': + resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -557,8 +557,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.10': - resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} + '@esbuild/linux-loong64@0.25.11': + resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -569,8 +569,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.10': - resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} + '@esbuild/linux-mips64el@0.25.11': + resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -581,8 +581,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.10': - resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} + '@esbuild/linux-ppc64@0.25.11': + resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -593,8 +593,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.10': - resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} + '@esbuild/linux-riscv64@0.25.11': + resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -605,8 +605,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.10': - resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} + '@esbuild/linux-s390x@0.25.11': + resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -617,8 +617,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.10': - resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} + '@esbuild/linux-x64@0.25.11': + resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==} engines: {node: '>=18'} cpu: [x64] os: [linux] @@ -629,8 +629,8 @@ packages: cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.10': - resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} + '@esbuild/netbsd-arm64@0.25.11': + resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -641,8 +641,8 @@ packages: cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.10': - resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} + '@esbuild/netbsd-x64@0.25.11': + resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] @@ -653,8 +653,8 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.10': - resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} + '@esbuild/openbsd-arm64@0.25.11': + resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -665,8 +665,8 @@ packages: cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.10': - resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} + '@esbuild/openbsd-x64@0.25.11': + resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -677,8 +677,8 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.10': - resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} + '@esbuild/openharmony-arm64@0.25.11': + resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] @@ -689,8 +689,8 @@ packages: cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.10': - resolution: {integrity: sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==} + '@esbuild/sunos-x64@0.25.11': + resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -701,8 +701,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.10': - resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} + '@esbuild/win32-arm64@0.25.11': + resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -713,8 +713,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.10': - resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} + '@esbuild/win32-ia32@0.25.11': + resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -725,8 +725,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.10': - resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} + '@esbuild/win32-x64@0.25.11': + resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -749,8 +749,8 @@ packages: resolution: {integrity: sha512-o2/jvNsdLC8SRdH1kQ7JjNOQNu9el0FpJ/QOW3mgiC5C9reuTp18iU4kijsVVLgvw4KZv6Z289SoKPh3HPsS0g==} hasBin: true - '@git.zone/tsrun@1.3.4': - resolution: {integrity: sha512-bAhlV5ORVyahl6ew1SC379qf48Gnc0HB5CVZbQZrqoVtOgXvUo9A47WynCyLOw+7sCeYMLYp3/yfwlgmuRoFPw==} + '@git.zone/tsrun@1.6.2': + resolution: {integrity: sha512-SOHbQqBg3/769/jPQcdpPCmugdEtIJINiG0O6aWx+su91GvGhheha5dAhccsCutJYErr+aJcBqBYuUYfhOfkFQ==} hasBin: true '@happy-dom/global-registrator@15.11.7': @@ -2242,8 +2242,8 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - esbuild@0.25.10: - resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==} + esbuild@0.25.11: + resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} engines: {node: '>=18'} hasBin: true @@ -5002,157 +5002,157 @@ snapshots: tslib: 2.8.1 optional: true - '@esbuild/aix-ppc64@0.25.10': + '@esbuild/aix-ppc64@0.25.11': optional: true '@esbuild/aix-ppc64@0.25.9': optional: true - '@esbuild/android-arm64@0.25.10': + '@esbuild/android-arm64@0.25.11': optional: true '@esbuild/android-arm64@0.25.9': optional: true - '@esbuild/android-arm@0.25.10': + '@esbuild/android-arm@0.25.11': optional: true '@esbuild/android-arm@0.25.9': optional: true - '@esbuild/android-x64@0.25.10': + '@esbuild/android-x64@0.25.11': optional: true '@esbuild/android-x64@0.25.9': optional: true - '@esbuild/darwin-arm64@0.25.10': + '@esbuild/darwin-arm64@0.25.11': optional: true '@esbuild/darwin-arm64@0.25.9': optional: true - '@esbuild/darwin-x64@0.25.10': + '@esbuild/darwin-x64@0.25.11': optional: true '@esbuild/darwin-x64@0.25.9': optional: true - '@esbuild/freebsd-arm64@0.25.10': + '@esbuild/freebsd-arm64@0.25.11': optional: true '@esbuild/freebsd-arm64@0.25.9': optional: true - '@esbuild/freebsd-x64@0.25.10': + '@esbuild/freebsd-x64@0.25.11': optional: true '@esbuild/freebsd-x64@0.25.9': optional: true - '@esbuild/linux-arm64@0.25.10': + '@esbuild/linux-arm64@0.25.11': optional: true '@esbuild/linux-arm64@0.25.9': optional: true - '@esbuild/linux-arm@0.25.10': + '@esbuild/linux-arm@0.25.11': optional: true '@esbuild/linux-arm@0.25.9': optional: true - '@esbuild/linux-ia32@0.25.10': + '@esbuild/linux-ia32@0.25.11': optional: true '@esbuild/linux-ia32@0.25.9': optional: true - '@esbuild/linux-loong64@0.25.10': + '@esbuild/linux-loong64@0.25.11': optional: true '@esbuild/linux-loong64@0.25.9': optional: true - '@esbuild/linux-mips64el@0.25.10': + '@esbuild/linux-mips64el@0.25.11': optional: true '@esbuild/linux-mips64el@0.25.9': optional: true - '@esbuild/linux-ppc64@0.25.10': + '@esbuild/linux-ppc64@0.25.11': optional: true '@esbuild/linux-ppc64@0.25.9': optional: true - '@esbuild/linux-riscv64@0.25.10': + '@esbuild/linux-riscv64@0.25.11': optional: true '@esbuild/linux-riscv64@0.25.9': optional: true - '@esbuild/linux-s390x@0.25.10': + '@esbuild/linux-s390x@0.25.11': optional: true '@esbuild/linux-s390x@0.25.9': optional: true - '@esbuild/linux-x64@0.25.10': + '@esbuild/linux-x64@0.25.11': optional: true '@esbuild/linux-x64@0.25.9': optional: true - '@esbuild/netbsd-arm64@0.25.10': + '@esbuild/netbsd-arm64@0.25.11': optional: true '@esbuild/netbsd-arm64@0.25.9': optional: true - '@esbuild/netbsd-x64@0.25.10': + '@esbuild/netbsd-x64@0.25.11': optional: true '@esbuild/netbsd-x64@0.25.9': optional: true - '@esbuild/openbsd-arm64@0.25.10': + '@esbuild/openbsd-arm64@0.25.11': optional: true '@esbuild/openbsd-arm64@0.25.9': optional: true - '@esbuild/openbsd-x64@0.25.10': + '@esbuild/openbsd-x64@0.25.11': optional: true '@esbuild/openbsd-x64@0.25.9': optional: true - '@esbuild/openharmony-arm64@0.25.10': + '@esbuild/openharmony-arm64@0.25.11': optional: true '@esbuild/openharmony-arm64@0.25.9': optional: true - '@esbuild/sunos-x64@0.25.10': + '@esbuild/sunos-x64@0.25.11': optional: true '@esbuild/sunos-x64@0.25.9': optional: true - '@esbuild/win32-arm64@0.25.10': + '@esbuild/win32-arm64@0.25.11': optional: true '@esbuild/win32-arm64@0.25.9': optional: true - '@esbuild/win32-ia32@0.25.10': + '@esbuild/win32-ia32@0.25.11': optional: true '@esbuild/win32-ia32@0.25.9': optional: true - '@esbuild/win32-x64@0.25.10': + '@esbuild/win32-x64@0.25.11': optional: true '@esbuild/win32-x64@0.25.9': @@ -5209,7 +5209,7 @@ snapshots: - aws-crt - supports-color - '@git.zone/tsrun@1.3.4': + '@git.zone/tsrun@1.6.2': dependencies: '@push.rocks/smartfile': 11.2.7 '@push.rocks/smartshell': 3.3.0 @@ -7377,34 +7377,34 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 - esbuild@0.25.10: + esbuild@0.25.11: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.10 - '@esbuild/android-arm': 0.25.10 - '@esbuild/android-arm64': 0.25.10 - '@esbuild/android-x64': 0.25.10 - '@esbuild/darwin-arm64': 0.25.10 - '@esbuild/darwin-x64': 0.25.10 - '@esbuild/freebsd-arm64': 0.25.10 - '@esbuild/freebsd-x64': 0.25.10 - '@esbuild/linux-arm': 0.25.10 - '@esbuild/linux-arm64': 0.25.10 - '@esbuild/linux-ia32': 0.25.10 - '@esbuild/linux-loong64': 0.25.10 - '@esbuild/linux-mips64el': 0.25.10 - '@esbuild/linux-ppc64': 0.25.10 - '@esbuild/linux-riscv64': 0.25.10 - '@esbuild/linux-s390x': 0.25.10 - '@esbuild/linux-x64': 0.25.10 - '@esbuild/netbsd-arm64': 0.25.10 - '@esbuild/netbsd-x64': 0.25.10 - '@esbuild/openbsd-arm64': 0.25.10 - '@esbuild/openbsd-x64': 0.25.10 - '@esbuild/openharmony-arm64': 0.25.10 - '@esbuild/sunos-x64': 0.25.10 - '@esbuild/win32-arm64': 0.25.10 - '@esbuild/win32-ia32': 0.25.10 - '@esbuild/win32-x64': 0.25.10 + '@esbuild/aix-ppc64': 0.25.11 + '@esbuild/android-arm': 0.25.11 + '@esbuild/android-arm64': 0.25.11 + '@esbuild/android-x64': 0.25.11 + '@esbuild/darwin-arm64': 0.25.11 + '@esbuild/darwin-x64': 0.25.11 + '@esbuild/freebsd-arm64': 0.25.11 + '@esbuild/freebsd-x64': 0.25.11 + '@esbuild/linux-arm': 0.25.11 + '@esbuild/linux-arm64': 0.25.11 + '@esbuild/linux-ia32': 0.25.11 + '@esbuild/linux-loong64': 0.25.11 + '@esbuild/linux-mips64el': 0.25.11 + '@esbuild/linux-ppc64': 0.25.11 + '@esbuild/linux-riscv64': 0.25.11 + '@esbuild/linux-s390x': 0.25.11 + '@esbuild/linux-x64': 0.25.11 + '@esbuild/netbsd-arm64': 0.25.11 + '@esbuild/netbsd-x64': 0.25.11 + '@esbuild/openbsd-arm64': 0.25.11 + '@esbuild/openbsd-x64': 0.25.11 + '@esbuild/openharmony-arm64': 0.25.11 + '@esbuild/sunos-x64': 0.25.11 + '@esbuild/win32-arm64': 0.25.11 + '@esbuild/win32-ia32': 0.25.11 + '@esbuild/win32-x64': 0.25.11 esbuild@0.25.9: optionalDependencies: @@ -9268,7 +9268,7 @@ snapshots: tsx@4.20.6: dependencies: - esbuild: 0.25.10 + esbuild: 0.25.11 get-tsconfig: 4.12.0 optionalDependencies: fsevents: 2.3.3 diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 4d86c43..3dc6542 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@git.zone/tstest', - version: '2.5.1', + version: '2.5.2', description: 'a test utility to run tests that match test/**/*.ts' } diff --git a/ts/tstest.classes.runtime.node.ts b/ts/tstest.classes.runtime.node.ts index 6443333..0f663cf 100644 --- a/ts/tstest.classes.runtime.node.ts +++ b/ts/tstest.classes.runtime.node.ts @@ -35,18 +35,11 @@ export class NodeRuntimeAdapter extends RuntimeAdapter { // Check Node.js version const nodeVersion = process.version; - // Check if tsrun is available - const result = await this.smartshellInstance.exec('tsrun --version', { - cwd: process.cwd(), - onError: () => { - // Ignore error - } - }); - - if (result.exitCode !== 0) { + // Check if tsrun module is available (imported as dependency) + if (!plugins.tsrun || !plugins.tsrun.spawnPath) { return { available: false, - error: 'tsrun not found. Install with: pnpm install --save-dev @git.zone/tsrun', + error: 'tsrun module not found or outdated (requires version 1.6.0+)', }; } @@ -96,7 +89,7 @@ export class NodeRuntimeAdapter extends RuntimeAdapter { } /** - * Execute a test file in Node.js + * Execute a test file in Node.js using tsrun's spawnPath API */ async run( testFile: string, @@ -109,28 +102,35 @@ export class NodeRuntimeAdapter extends RuntimeAdapter { const mergedOptions = this.mergeOptions(options); - // Build tsrun command - let tsrunOptions = ''; + // Build spawn options + const spawnOptions: any = { + cwd: mergedOptions.cwd || process.cwd(), + env: { ...mergedOptions.env }, + args: [] as string[], + stdio: 'pipe' as const, + }; + + // Add --web flag if needed if (process.argv.includes('--web')) { - tsrunOptions += ' --web'; + spawnOptions.args.push('--web'); } // Set filter tags as environment variable if (this.filterTags.length > 0) { - process.env.TSTEST_FILTER_TAGS = this.filterTags.join(','); + spawnOptions.env.TSTEST_FILTER_TAGS = this.filterTags.join(','); } // Check for 00init.ts file in test directory const testDir = plugins.path.dirname(testFile); const initFile = plugins.path.join(testDir, '00init.ts'); - let runCommand = `tsrun ${testFile}${tsrunOptions}`; - const initFileExists = await plugins.smartfile.fs.fileExists(initFile); - // If 00init.ts exists, run it first + // Determine which file to run + let fileToRun = testFile; let loaderPath: string | null = null; + + // If 00init.ts exists, create a loader file if (initFileExists) { - // Create a temporary loader file that imports both 00init.ts and the test file const absoluteInitFile = plugins.path.resolve(initFile); const absoluteTestFile = plugins.path.resolve(testFile); const loaderContent = ` @@ -139,10 +139,12 @@ import '${absoluteTestFile.replace(/\\/g, '/')}'; `; loaderPath = plugins.path.join(testDir, `.loader_${plugins.path.basename(testFile)}`); await plugins.smartfile.memory.toFs(loaderContent, loaderPath); - runCommand = `tsrun ${loaderPath}${tsrunOptions}`; + fileToRun = loaderPath; } - const execResultStreaming = await this.smartshellInstance.execStreamingSilent(runCommand); + // Spawn the test process using tsrun's spawnPath API + // Pass undefined for fromFileUrl since fileToRun is already an absolute path + const tsrunProcess = plugins.tsrun.spawnPath(fileToRun, undefined, spawnOptions); // If we created a loader file, clean it up after test execution if (loaderPath) { @@ -156,8 +158,8 @@ import '${absoluteTestFile.replace(/\\/g, '/')}'; } }; - execResultStreaming.childProcess.on('exit', cleanup); - execResultStreaming.childProcess.on('error', cleanup); + tsrunProcess.childProcess.on('exit', cleanup); + tsrunProcess.childProcess.on('error', cleanup); } // Start warning timer if no timeout was specified @@ -180,15 +182,15 @@ import '${absoluteTestFile.replace(/\\/g, '/')}'; const timeoutPromise = new Promise((_resolve, reject) => { timeoutId = setTimeout(async () => { - // Use smartshell's terminate() to kill entire process tree - await execResultStreaming.terminate(); + // Use tsrun's terminate() to gracefully kill the process + await tsrunProcess.terminate(); reject(new Error(`Test file timed out after ${this.timeoutSeconds} seconds`)); }, timeoutMs); }); try { await Promise.race([ - tapParser.handleTapProcess(execResultStreaming.childProcess), + tapParser.handleTapProcess(tsrunProcess.childProcess), timeoutPromise ]); // Clear timeout if test completed successfully @@ -200,16 +202,16 @@ import '${absoluteTestFile.replace(/\\/g, '/')}'; } // Handle timeout error tapParser.handleTimeout(this.timeoutSeconds); - // Ensure entire process tree is killed if still running + // Ensure process is killed if still running try { - await execResultStreaming.kill(); // This kills the entire process tree with SIGKILL + tsrunProcess.kill('SIGKILL'); } catch (killError) { - // Process tree might already be dead + // Process might already be dead } await tapParser.evaluateFinalResult(); } } else { - await tapParser.handleTapProcess(execResultStreaming.childProcess); + await tapParser.handleTapProcess(tsrunProcess.childProcess); } // Clear warning timer if it was set diff --git a/ts/tstest.plugins.ts b/ts/tstest.plugins.ts index 765df88..80d72f7 100644 --- a/ts/tstest.plugins.ts +++ b/ts/tstest.plugins.ts @@ -37,8 +37,9 @@ export { // @git.zone scope import * as tsbundle from '@git.zone/tsbundle'; +import * as tsrun from '@git.zone/tsrun'; -export { tsbundle }; +export { tsbundle, tsrun }; // sindresorhus import figures from 'figures';