@git.zone/tstest 2.3.7 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,184 @@
1
+ import * as plugins from './tstest.plugins.js';
2
+ import { coloredString as cs } from '@push.rocks/consolecolor';
3
+ import { RuntimeAdapter, } from './tstest.classes.runtime.adapter.js';
4
+ import { TapParser } from './tstest.classes.tap.parser.js';
5
+ import { TsTestLogger } from './tstest.logging.js';
6
+ /**
7
+ * Bun runtime adapter
8
+ * Executes tests using the Bun runtime with native TypeScript support
9
+ */
10
+ export class BunRuntimeAdapter extends RuntimeAdapter {
11
+ constructor(logger, smartshellInstance, // SmartShell instance from @push.rocks/smartshell
12
+ timeoutSeconds, filterTags) {
13
+ super();
14
+ this.logger = logger;
15
+ this.smartshellInstance = smartshellInstance;
16
+ this.timeoutSeconds = timeoutSeconds;
17
+ this.filterTags = filterTags;
18
+ this.id = 'bun';
19
+ this.displayName = 'Bun';
20
+ }
21
+ /**
22
+ * Check if Bun is available
23
+ */
24
+ async checkAvailable() {
25
+ try {
26
+ const result = await this.smartshellInstance.exec('bun --version', {
27
+ cwd: process.cwd(),
28
+ onError: () => {
29
+ // Ignore error
30
+ }
31
+ });
32
+ if (result.exitCode !== 0) {
33
+ return {
34
+ available: false,
35
+ error: 'Bun not found. Install from: https://bun.sh/',
36
+ };
37
+ }
38
+ // Bun version is just the version number
39
+ const version = result.stdout.trim();
40
+ return {
41
+ available: true,
42
+ version: `Bun ${version}`,
43
+ };
44
+ }
45
+ catch (error) {
46
+ return {
47
+ available: false,
48
+ error: error.message,
49
+ };
50
+ }
51
+ }
52
+ /**
53
+ * Create command configuration for Bun test execution
54
+ */
55
+ createCommand(testFile, options) {
56
+ const mergedOptions = this.mergeOptions(options);
57
+ const args = ['run'];
58
+ // Add extra args
59
+ if (mergedOptions.extraArgs && mergedOptions.extraArgs.length > 0) {
60
+ args.push(...mergedOptions.extraArgs);
61
+ }
62
+ // Add test file
63
+ args.push(testFile);
64
+ // Set environment variables
65
+ const env = { ...mergedOptions.env };
66
+ if (this.filterTags.length > 0) {
67
+ env.TSTEST_FILTER_TAGS = this.filterTags.join(',');
68
+ }
69
+ return {
70
+ command: 'bun',
71
+ args,
72
+ env,
73
+ cwd: mergedOptions.cwd,
74
+ };
75
+ }
76
+ /**
77
+ * Execute a test file in Bun
78
+ */
79
+ async run(testFile, index, total, options) {
80
+ this.logger.testFileStart(testFile, this.displayName, index, total);
81
+ const tapParser = new TapParser(testFile + ':bun', this.logger);
82
+ const mergedOptions = this.mergeOptions(options);
83
+ // Build Bun command
84
+ const command = this.createCommand(testFile, mergedOptions);
85
+ const fullCommand = `${command.command} ${command.args.join(' ')}`;
86
+ // Set filter tags as environment variable
87
+ if (this.filterTags.length > 0) {
88
+ process.env.TSTEST_FILTER_TAGS = this.filterTags.join(',');
89
+ }
90
+ // Check for 00init.ts file in test directory
91
+ const testDir = plugins.path.dirname(testFile);
92
+ const initFile = plugins.path.join(testDir, '00init.ts');
93
+ const initFileExists = await plugins.smartfile.fs.fileExists(initFile);
94
+ let runCommand = fullCommand;
95
+ let loaderPath = null;
96
+ // If 00init.ts exists, create a loader file
97
+ if (initFileExists) {
98
+ const absoluteInitFile = plugins.path.resolve(initFile);
99
+ const absoluteTestFile = plugins.path.resolve(testFile);
100
+ const loaderContent = `
101
+ import '${absoluteInitFile.replace(/\\/g, '/')}';
102
+ import '${absoluteTestFile.replace(/\\/g, '/')}';
103
+ `;
104
+ loaderPath = plugins.path.join(testDir, `.loader_${plugins.path.basename(testFile)}`);
105
+ await plugins.smartfile.memory.toFs(loaderContent, loaderPath);
106
+ // Rebuild command with loader file
107
+ const loaderCommand = this.createCommand(loaderPath, mergedOptions);
108
+ runCommand = `${loaderCommand.command} ${loaderCommand.args.join(' ')}`;
109
+ }
110
+ const execResultStreaming = await this.smartshellInstance.execStreamingSilent(runCommand);
111
+ // If we created a loader file, clean it up after test execution
112
+ if (loaderPath) {
113
+ const cleanup = () => {
114
+ try {
115
+ if (plugins.smartfile.fs.fileExistsSync(loaderPath)) {
116
+ plugins.smartfile.fs.removeSync(loaderPath);
117
+ }
118
+ }
119
+ catch (e) {
120
+ // Ignore cleanup errors
121
+ }
122
+ };
123
+ execResultStreaming.childProcess.on('exit', cleanup);
124
+ execResultStreaming.childProcess.on('error', cleanup);
125
+ }
126
+ // Start warning timer if no timeout was specified
127
+ let warningTimer = null;
128
+ if (this.timeoutSeconds === null) {
129
+ warningTimer = setTimeout(() => {
130
+ console.error('');
131
+ console.error(cs('⚠️ WARNING: Test file is running for more than 1 minute', 'orange'));
132
+ console.error(cs(` File: ${testFile}`, 'orange'));
133
+ console.error(cs(' Consider using --timeout option to set a timeout for test files.', 'orange'));
134
+ console.error(cs(' Example: tstest test --timeout=300 (for 5 minutes)', 'orange'));
135
+ console.error('');
136
+ }, 60000); // 1 minute
137
+ }
138
+ // Handle timeout if specified
139
+ if (this.timeoutSeconds !== null) {
140
+ const timeoutMs = this.timeoutSeconds * 1000;
141
+ let timeoutId;
142
+ const timeoutPromise = new Promise((_resolve, reject) => {
143
+ timeoutId = setTimeout(async () => {
144
+ // Use smartshell's terminate() to kill entire process tree
145
+ await execResultStreaming.terminate();
146
+ reject(new Error(`Test file timed out after ${this.timeoutSeconds} seconds`));
147
+ }, timeoutMs);
148
+ });
149
+ try {
150
+ await Promise.race([
151
+ tapParser.handleTapProcess(execResultStreaming.childProcess),
152
+ timeoutPromise
153
+ ]);
154
+ // Clear timeout if test completed successfully
155
+ clearTimeout(timeoutId);
156
+ }
157
+ catch (error) {
158
+ // Clear warning timer if it was set
159
+ if (warningTimer) {
160
+ clearTimeout(warningTimer);
161
+ }
162
+ // Handle timeout error
163
+ tapParser.handleTimeout(this.timeoutSeconds);
164
+ // Ensure entire process tree is killed if still running
165
+ try {
166
+ await execResultStreaming.kill(); // This kills the entire process tree with SIGKILL
167
+ }
168
+ catch (killError) {
169
+ // Process tree might already be dead
170
+ }
171
+ await tapParser.evaluateFinalResult();
172
+ }
173
+ }
174
+ else {
175
+ await tapParser.handleTapProcess(execResultStreaming.childProcess);
176
+ }
177
+ // Clear warning timer if it was set
178
+ if (warningTimer) {
179
+ clearTimeout(warningTimer);
180
+ }
181
+ return tapParser;
182
+ }
183
+ }
184
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHN0ZXN0LmNsYXNzZXMucnVudGltZS5idW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy90c3Rlc3QuY2xhc3Nlcy5ydW50aW1lLmJ1bi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHFCQUFxQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxhQUFhLElBQUksRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDL0QsT0FBTyxFQUNMLGNBQWMsR0FJZixNQUFNLHFDQUFxQyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHbkQ7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLGlCQUFrQixTQUFRLGNBQWM7SUFJbkQsWUFDVSxNQUFvQixFQUNwQixrQkFBdUIsRUFBRSxrREFBa0Q7SUFDM0UsY0FBNkIsRUFDN0IsVUFBb0I7UUFFNUIsS0FBSyxFQUFFLENBQUM7UUFMQSxXQUFNLEdBQU4sTUFBTSxDQUFjO1FBQ3BCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBSztRQUN2QixtQkFBYyxHQUFkLGNBQWMsQ0FBZTtRQUM3QixlQUFVLEdBQVYsVUFBVSxDQUFVO1FBUHJCLE9BQUUsR0FBWSxLQUFLLENBQUM7UUFDcEIsZ0JBQVcsR0FBVyxLQUFLLENBQUM7SUFTckMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLGNBQWM7UUFDbEIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRTtnQkFDakUsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUU7Z0JBQ2xCLE9BQU8sRUFBRSxHQUFHLEVBQUU7b0JBQ1osZUFBZTtnQkFDakIsQ0FBQzthQUNGLENBQUMsQ0FBQztZQUVILElBQUksTUFBTSxDQUFD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
@@ -0,0 +1,36 @@
1
+ import { RuntimeAdapter, type ChromiumOptions, type RuntimeCommand, type RuntimeAvailability } from './tstest.classes.runtime.adapter.js';
2
+ import { TapParser } from './tstest.classes.tap.parser.js';
3
+ import { TsTestLogger } from './tstest.logging.js';
4
+ import type { Runtime } from './tstest.classes.runtime.parser.js';
5
+ /**
6
+ * Chromium runtime adapter
7
+ * Executes tests in a headless Chromium browser
8
+ */
9
+ export declare class ChromiumRuntimeAdapter extends RuntimeAdapter {
10
+ private logger;
11
+ private tsbundleInstance;
12
+ private smartbrowserInstance;
13
+ private timeoutSeconds;
14
+ readonly id: Runtime;
15
+ readonly displayName: string;
16
+ constructor(logger: TsTestLogger, tsbundleInstance: any, // TsBundle instance from @push.rocks/tsbundle
17
+ smartbrowserInstance: any, // SmartBrowser instance from @push.rocks/smartbrowser
18
+ timeoutSeconds: number | null);
19
+ /**
20
+ * Check if Chromium is available
21
+ */
22
+ checkAvailable(): Promise<RuntimeAvailability>;
23
+ /**
24
+ * Create command configuration for Chromium test execution
25
+ * Note: Chromium tests don't use a traditional command, but this satisfies the interface
26
+ */
27
+ createCommand(testFile: string, options?: ChromiumOptions): RuntimeCommand;
28
+ /**
29
+ * Find free ports for HTTP server and WebSocket
30
+ */
31
+ private findFreePorts;
32
+ /**
33
+ * Execute a test file in Chromium browser
34
+ */
35
+ run(testFile: string, index: number, total: number, options?: ChromiumOptions): Promise<TapParser>;
36
+ }
@@ -0,0 +1,256 @@
1
+ import * as plugins from './tstest.plugins.js';
2
+ import * as paths from './tstest.paths.js';
3
+ import { coloredString as cs } from '@push.rocks/consolecolor';
4
+ import { RuntimeAdapter, } from './tstest.classes.runtime.adapter.js';
5
+ import { TapParser } from './tstest.classes.tap.parser.js';
6
+ import { TsTestLogger } from './tstest.logging.js';
7
+ /**
8
+ * Chromium runtime adapter
9
+ * Executes tests in a headless Chromium browser
10
+ */
11
+ export class ChromiumRuntimeAdapter extends RuntimeAdapter {
12
+ constructor(logger, tsbundleInstance, // TsBundle instance from @push.rocks/tsbundle
13
+ smartbrowserInstance, // SmartBrowser instance from @push.rocks/smartbrowser
14
+ timeoutSeconds) {
15
+ super();
16
+ this.logger = logger;
17
+ this.tsbundleInstance = tsbundleInstance;
18
+ this.smartbrowserInstance = smartbrowserInstance;
19
+ this.timeoutSeconds = timeoutSeconds;
20
+ this.id = 'chromium';
21
+ this.displayName = 'Chromium';
22
+ }
23
+ /**
24
+ * Check if Chromium is available
25
+ */
26
+ async checkAvailable() {
27
+ try {
28
+ // Check if smartbrowser is available and can start
29
+ // The browser binary is usually handled by @push.rocks/smartbrowser
30
+ return {
31
+ available: true,
32
+ version: 'Chromium (via smartbrowser)',
33
+ };
34
+ }
35
+ catch (error) {
36
+ return {
37
+ available: false,
38
+ error: error.message || 'Chromium not available',
39
+ };
40
+ }
41
+ }
42
+ /**
43
+ * Create command configuration for Chromium test execution
44
+ * Note: Chromium tests don't use a traditional command, but this satisfies the interface
45
+ */
46
+ createCommand(testFile, options) {
47
+ const mergedOptions = this.mergeOptions(options);
48
+ return {
49
+ command: 'chromium',
50
+ args: [],
51
+ env: mergedOptions.env,
52
+ cwd: mergedOptions.cwd,
53
+ };
54
+ }
55
+ /**
56
+ * Find free ports for HTTP server and WebSocket
57
+ */
58
+ async findFreePorts() {
59
+ const smartnetwork = new plugins.smartnetwork.SmartNetwork();
60
+ // Find random free HTTP port in range 30000-40000 to minimize collision chance
61
+ const httpPort = await smartnetwork.findFreePort(30000, 40000, { randomize: true });
62
+ if (!httpPort) {
63
+ throw new Error('Could not find a free HTTP port in range 30000-40000');
64
+ }
65
+ // Find random free WebSocket port, excluding the HTTP port to ensure they're different
66
+ const wsPort = await smartnetwork.findFreePort(30000, 40000, {
67
+ randomize: true,
68
+ exclude: [httpPort]
69
+ });
70
+ if (!wsPort) {
71
+ throw new Error('Could not find a free WebSocket port in range 30000-40000');
72
+ }
73
+ // Log selected ports for debugging
74
+ if (!this.logger.options.quiet) {
75
+ console.log(`Selected ports - HTTP: ${httpPort}, WebSocket: ${wsPort}`);
76
+ }
77
+ return { httpPort, wsPort };
78
+ }
79
+ /**
80
+ * Execute a test file in Chromium browser
81
+ */
82
+ async run(testFile, index, total, options) {
83
+ this.logger.testFileStart(testFile, this.displayName, index, total);
84
+ // lets get all our paths sorted
85
+ const tsbundleCacheDirPath = plugins.path.join(paths.cwd, './.nogit/tstest_cache');
86
+ const bundleFileName = testFile.replace('/', '__') + '.js';
87
+ const bundleFilePath = plugins.path.join(tsbundleCacheDirPath, bundleFileName);
88
+ // lets bundle the test
89
+ await plugins.smartfile.fs.ensureEmptyDir(tsbundleCacheDirPath);
90
+ await this.tsbundleInstance.build(process.cwd(), testFile, bundleFilePath, {
91
+ bundler: 'esbuild',
92
+ });
93
+ // Find free ports for HTTP and WebSocket
94
+ const { httpPort, wsPort } = await this.findFreePorts();
95
+ // lets create a server
96
+ const server = new plugins.typedserver.servertools.Server({
97
+ cors: true,
98
+ port: httpPort,
99
+ });
100
+ server.addRoute('/test', new plugins.typedserver.servertools.Handler('GET', async (_req, res) => {
101
+ res.type('.html');
102
+ res.write(`
103
+ <html>
104
+ <head>
105
+ <script>
106
+ globalThis.testdom = true;
107
+ globalThis.wsPort = ${wsPort};
108
+ </script>
109
+ </head>
110
+ <body></body>
111
+ </html>
112
+ `);
113
+ res.end();
114
+ }));
115
+ server.addRoute('/*splat', new plugins.typedserver.servertools.HandlerStatic(tsbundleCacheDirPath));
116
+ await server.start();
117
+ // lets handle realtime comms
118
+ const tapParser = new TapParser(testFile + ':chrome', this.logger);
119
+ const wss = new plugins.ws.WebSocketServer({ port: wsPort });
120
+ wss.on('connection', (ws) => {
121
+ ws.on('message', (message) => {
122
+ const messageStr = message.toString();
123
+ if (messageStr.startsWith('console:')) {
124
+ const [, level, ...messageParts] = messageStr.split(':');
125
+ this.logger.browserConsole(messageParts.join(':'), level);
126
+ }
127
+ else {
128
+ tapParser.handleTapLog(messageStr);
129
+ }
130
+ });
131
+ });
132
+ // lets do the browser bit with timeout handling
133
+ await this.smartbrowserInstance.start();
134
+ const evaluatePromise = this.smartbrowserInstance.evaluateOnPage(`http://localhost:${httpPort}/test?bundleName=${bundleFileName}`, async () => {
135
+ // lets enable real time comms
136
+ const ws = new WebSocket(`ws://localhost:${globalThis.wsPort}`);
137
+ await new Promise((resolve) => (ws.onopen = resolve));
138
+ // Ensure this function is declared with 'async'
139
+ const logStore = [];
140
+ const originalLog = console.log;
141
+ const originalError = console.error;
142
+ // Override console methods to capture the logs
143
+ console.log = (...args) => {
144
+ logStore.push(args.join(' '));
145
+ ws.send(args.join(' '));
146
+ originalLog(...args);
147
+ };
148
+ console.error = (...args) => {
149
+ logStore.push(args.join(' '));
150
+ ws.send(args.join(' '));
151
+ originalError(...args);
152
+ };
153
+ const bundleName = new URLSearchParams(window.location.search).get('bundleName');
154
+ originalLog(`::TSTEST IN CHROMIUM:: Relevant Script name is: ${bundleName}`);
155
+ try {
156
+ // Dynamically import the test module
157
+ const testModule = await import(`/${bundleName}`);
158
+ if (testModule && testModule.default && testModule.default instanceof Promise) {
159
+ // Execute the exported test function
160
+ await testModule.default;
161
+ }
162
+ else if (testModule && testModule.default && typeof testModule.default.then === 'function') {
163
+ console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
164
+ console.log('Test module default export is just promiselike: Something might be messing with your Promise implementation.');
165
+ console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
166
+ await testModule.default;
167
+ }
168
+ else if (globalThis.tapPromise && typeof globalThis.tapPromise.then === 'function') {
169
+ console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
170
+ console.log('Using globalThis.tapPromise');
171
+ console.log('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
172
+ await testModule.default;
173
+ }
174
+ else {
175
+ console.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
176
+ console.error('Test module does not export a default promise.');
177
+ console.error('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
178
+ console.log(`We got: ${JSON.stringify(testModule)}`);
179
+ }
180
+ }
181
+ catch (err) {
182
+ console.error(err);
183
+ }
184
+ return logStore.join('\n');
185
+ });
186
+ // Start warning timer if no timeout was specified
187
+ let warningTimer = null;
188
+ if (this.timeoutSeconds === null) {
189
+ warningTimer = setTimeout(() => {
190
+ console.error('');
191
+ console.error(cs('⚠️ WARNING: Test file is running for more than 1 minute', 'orange'));
192
+ console.error(cs(` File: ${testFile}`, 'orange'));
193
+ console.error(cs(' Consider using --timeout option to set a timeout for test files.', 'orange'));
194
+ console.error(cs(' Example: tstest test --timeout=300 (for 5 minutes)', 'orange'));
195
+ console.error('');
196
+ }, 60000); // 1 minute
197
+ }
198
+ // Handle timeout if specified
199
+ if (this.timeoutSeconds !== null) {
200
+ const timeoutMs = this.timeoutSeconds * 1000;
201
+ let timeoutId;
202
+ const timeoutPromise = new Promise((_resolve, reject) => {
203
+ timeoutId = setTimeout(() => {
204
+ reject(new Error(`Test file timed out after ${this.timeoutSeconds} seconds`));
205
+ }, timeoutMs);
206
+ });
207
+ try {
208
+ await Promise.race([
209
+ evaluatePromise,
210
+ timeoutPromise
211
+ ]);
212
+ // Clear timeout if test completed successfully
213
+ clearTimeout(timeoutId);
214
+ }
215
+ catch (error) {
216
+ // Clear warning timer if it was set
217
+ if (warningTimer) {
218
+ clearTimeout(warningTimer);
219
+ }
220
+ // Handle timeout error
221
+ tapParser.handleTimeout(this.timeoutSeconds);
222
+ }
223
+ }
224
+ else {
225
+ await evaluatePromise;
226
+ }
227
+ // Clear warning timer if it was set
228
+ if (warningTimer) {
229
+ clearTimeout(warningTimer);
230
+ }
231
+ // Always clean up resources, even on timeout
232
+ try {
233
+ await this.smartbrowserInstance.stop();
234
+ }
235
+ catch (error) {
236
+ // Browser might already be stopped
237
+ }
238
+ try {
239
+ await server.stop();
240
+ }
241
+ catch (error) {
242
+ // Server might already be stopped
243
+ }
244
+ try {
245
+ wss.close();
246
+ }
247
+ catch (error) {
248
+ // WebSocket server might already be closed
249
+ }
250
+ console.log(`${cs('=> ', 'blue')} Stopped ${cs(testFile, 'orange')} chromium instance and server.`);
251
+ // Always evaluate final result (handleTimeout just sets up the test state)
252
+ await tapParser.evaluateFinalResult();
253
+ return tapParser;
254
+ }
255
+ }
256
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHN0ZXN0LmNsYXNzZXMucnVudGltZS5jaHJvbWl1bS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3RzdGVzdC5jbGFzc2VzLnJ1bnRpbWUuY2hyb21pdW0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxxQkFBcUIsQ0FBQztBQUMvQyxPQUFPLEtBQUssS0FBSyxNQUFNLG1CQUFtQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxhQUFhLElBQUksRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDL0QsT0FBTyxFQUNMLGNBQWMsR0FJZixNQUFNLHFDQUFxQyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHbkQ7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLHNCQUF1QixTQUFRLGNBQWM7SUFJeEQsWUFDVSxNQUFvQixFQUNwQixnQkFBcUIsRUFBRSw4Q0FBOEM7SUFDckUsb0JBQXlCLEVBQUUsc0RBQXNEO0lBQ2pGLGNBQTZCO1FBRXJDLEtBQUssRUFBRSxDQUFDO1FBTEEsV0FBTSxHQUFOLE1BQU0sQ0FBYztRQUNwQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQUs7UUFDckIseUJBQW9CLEdBQXBCLG9CQUFvQixDQUFLO1FBQ3pCLG1CQUFjLEdBQWQsY0FBYyxDQUFlO1FBUDlCLE9BQUUsR0FBWSxVQUFVLENBQUM7UUFDekIsZ0JBQVcsR0FBVyxVQUFVLENBQUM7SUFTMUMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLGNBQWM7UUFDbEIsSUFBSSxDQUFDO1lBQ0gsbURBQW1EO1lBQ25ELG9FQUFvRTtZQUNwRSxPQUFPO2dCQUNMLFNBQVMsRUFBRSxJQUFJO2dCQUNmLE9BQU8sRUFBRSw2QkFBNkI7YUFDdkMsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxD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
@@ -0,0 +1,34 @@
1
+ import { RuntimeAdapter, type DenoOptions, type RuntimeCommand, type RuntimeAvailability } from './tstest.classes.runtime.adapter.js';
2
+ import { TapParser } from './tstest.classes.tap.parser.js';
3
+ import { TsTestLogger } from './tstest.logging.js';
4
+ import type { Runtime } from './tstest.classes.runtime.parser.js';
5
+ /**
6
+ * Deno runtime adapter
7
+ * Executes tests using the Deno runtime
8
+ */
9
+ export declare class DenoRuntimeAdapter extends RuntimeAdapter {
10
+ private logger;
11
+ private smartshellInstance;
12
+ private timeoutSeconds;
13
+ private filterTags;
14
+ readonly id: Runtime;
15
+ readonly displayName: string;
16
+ constructor(logger: TsTestLogger, smartshellInstance: any, // SmartShell instance from @push.rocks/smartshell
17
+ timeoutSeconds: number | null, filterTags: string[]);
18
+ /**
19
+ * Get default Deno options
20
+ */
21
+ protected getDefaultOptions(): DenoOptions;
22
+ /**
23
+ * Check if Deno is available
24
+ */
25
+ checkAvailable(): Promise<RuntimeAvailability>;
26
+ /**
27
+ * Create command configuration for Deno test execution
28
+ */
29
+ createCommand(testFile: string, options?: DenoOptions): RuntimeCommand;
30
+ /**
31
+ * Execute a test file in Deno
32
+ */
33
+ run(testFile: string, index: number, total: number, options?: DenoOptions): Promise<TapParser>;
34
+ }