@git.zone/tstest 2.4.2 → 2.5.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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/tstest.classes.runtime.parser.d.ts +1 -0
- package/dist_ts/tstest.classes.runtime.parser.js +21 -3
- package/package.json +1 -1
- package/readme.md +211 -122
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/tstest.classes.runtime.parser.ts +21 -2
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@git.zone/tstest',
|
|
6
|
-
version: '2.
|
|
6
|
+
version: '2.5.0',
|
|
7
7
|
description: 'a test utility to run tests that match test/**/*.ts'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxrQkFBa0I7SUFDeEIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHFEQUFxRDtDQUNuRSxDQUFBIn0=
|
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
* - test.chromium.ts
|
|
7
7
|
* - test.node+chromium.ts
|
|
8
8
|
* - test.deno+bun.ts
|
|
9
|
+
* - test.all.ts (runs on all runtimes)
|
|
9
10
|
* - test.chromium.nonci.ts
|
|
10
11
|
*/
|
|
11
12
|
const KNOWN_RUNTIMES = new Set(['node', 'chromium', 'deno', 'bun']);
|
|
12
13
|
const KNOWN_MODIFIERS = new Set(['nonci']);
|
|
13
14
|
const VALID_EXTENSIONS = new Set(['ts', 'tsx', 'mts', 'cts']);
|
|
15
|
+
const ALL_RUNTIMES = ['node', 'chromium', 'deno', 'bun'];
|
|
14
16
|
// Legacy mappings for backwards compatibility
|
|
15
17
|
const LEGACY_RUNTIME_MAP = {
|
|
16
18
|
browser: ['chromium'],
|
|
@@ -67,8 +69,12 @@ export function parseTestFilename(filePath, config = {}) {
|
|
|
67
69
|
const runtimeCandidates = token.split('+').map(r => r.trim()).filter(Boolean);
|
|
68
70
|
const validRuntimes = [];
|
|
69
71
|
const invalidRuntimes = [];
|
|
72
|
+
let hasAllKeyword = false;
|
|
70
73
|
for (const candidate of runtimeCandidates) {
|
|
71
|
-
if (
|
|
74
|
+
if (candidate === 'all') {
|
|
75
|
+
hasAllKeyword = true;
|
|
76
|
+
}
|
|
77
|
+
else if (KNOWN_RUNTIMES.has(candidate)) {
|
|
72
78
|
// Dedupe: only add if not already in list
|
|
73
79
|
if (!validRuntimes.includes(candidate)) {
|
|
74
80
|
validRuntimes.push(candidate);
|
|
@@ -78,10 +84,16 @@ export function parseTestFilename(filePath, config = {}) {
|
|
|
78
84
|
invalidRuntimes.push(candidate);
|
|
79
85
|
}
|
|
80
86
|
}
|
|
87
|
+
// If 'all' keyword is present, expand to all runtimes
|
|
88
|
+
if (hasAllKeyword) {
|
|
89
|
+
runtimes = [...ALL_RUNTIMES];
|
|
90
|
+
runtimeTokenIndex = i;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
81
93
|
if (invalidRuntimes.length > 0) {
|
|
82
94
|
if (strictUnknownRuntime) {
|
|
83
95
|
throw new Error(`Unknown runtime(s) in "${fileName}": ${invalidRuntimes.join(', ')}. ` +
|
|
84
|
-
`Valid runtimes: ${Array.from(KNOWN_RUNTIMES).join(', ')}`);
|
|
96
|
+
`Valid runtimes: ${Array.from(KNOWN_RUNTIMES).join(', ')}, all`);
|
|
85
97
|
}
|
|
86
98
|
else {
|
|
87
99
|
console.warn(`⚠️ Warning: Unknown runtime(s) in "${fileName}": ${invalidRuntimes.join(', ')}. ` +
|
|
@@ -97,6 +109,12 @@ export function parseTestFilename(filePath, config = {}) {
|
|
|
97
109
|
break;
|
|
98
110
|
}
|
|
99
111
|
}
|
|
112
|
+
// Check if this is the 'all' keyword (expands to all runtimes)
|
|
113
|
+
if (token === 'all') {
|
|
114
|
+
runtimes = [...ALL_RUNTIMES];
|
|
115
|
+
runtimeTokenIndex = i;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
100
118
|
// Check if this is a single runtime token
|
|
101
119
|
if (KNOWN_RUNTIMES.has(token)) {
|
|
102
120
|
runtimes = [token];
|
|
@@ -156,4 +174,4 @@ export function getLegacyMigrationTarget(fileName) {
|
|
|
156
174
|
parts.push(parsed.extension);
|
|
157
175
|
return parts.join('.');
|
|
158
176
|
}
|
|
159
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
177
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHN0ZXN0LmNsYXNzZXMucnVudGltZS5wYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy90c3Rlc3QuY2xhc3Nlcy5ydW50aW1lLnBhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7OztHQVVHO0FBbUJILE1BQU0sY0FBYyxHQUFnQixJQUFJLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDakYsTUFBTSxlQUFlLEdBQWdCLElBQUksR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUN4RCxNQUFNLGdCQUFnQixHQUFnQixJQUFJLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDM0UsTUFBTSxZQUFZLEdBQWMsQ0FBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztBQUVwRSw4Q0FBOEM7QUFDOUMsTUFBTSxrQkFBa0IsR0FBOEI7SUFDcEQsT0FBTyxFQUFFLENBQUMsVUFBVSxDQUFDO0lBQ3JCLElBQUksRUFBRSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUM7Q0FDM0IsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsUUFBZ0IsRUFDaEIsU0FBdUIsRUFBRTtJQUV6QixNQUFNLG9CQUFvQixHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsSUFBSSxJQUFJLENBQUM7SUFDakUsTUFBTSxlQUFlLEdBQUcsTUFBTSxDQUFDLGVBQWUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRTNELDBDQUEwQztJQUMxQyxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLFFBQVEsQ0FBQztJQUN2RCxNQUFNLFFBQVEsR0FBRyxR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
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @git.zone/tstest
|
|
2
|
-
🧪 **A powerful, modern test runner for TypeScript** - making your test runs beautiful and informative!
|
|
2
|
+
🧪 **A powerful, modern test runner for TypeScript** - making your test runs beautiful and informative across multiple runtimes!
|
|
3
3
|
|
|
4
|
-
##
|
|
4
|
+
## Availability and Links
|
|
5
5
|
* [npmjs.org (npm package)](https://www.npmjs.com/package/@git.zone/tstest)
|
|
6
6
|
* [code.foss.global (source)](https://code.foss.global/git.zone/tstest)
|
|
7
7
|
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
### ✨ Key Features
|
|
13
13
|
|
|
14
14
|
- 🎯 **Smart Test Execution** - Run all tests, single files, or use glob patterns
|
|
15
|
+
- 🚀 **Multi-Runtime Support** - Run tests in Node.js, Deno, Bun, and Chromium
|
|
15
16
|
- 🎨 **Beautiful Output** - Color-coded results with emojis and clean formatting
|
|
16
17
|
- 📊 **Multiple Output Modes** - Choose from normal, quiet, verbose, or JSON output
|
|
17
18
|
- 🔍 **Automatic Discovery** - Finds all your test files automatically
|
|
18
|
-
- 🌐 **Cross-Environment** - Supports Node.js and browser testing
|
|
19
19
|
- 📝 **Detailed Logging** - Optional file logging for debugging
|
|
20
20
|
- ⚡ **Performance Metrics** - See which tests are slow
|
|
21
21
|
- 🤖 **CI/CD Ready** - JSON output mode for automation
|
|
@@ -26,13 +26,10 @@
|
|
|
26
26
|
- ⏳ **Timeout Control** - Set custom timeouts for tests
|
|
27
27
|
- 🔁 **Retry Logic** - Automatically retry failing tests
|
|
28
28
|
- 🛠️ **Test Fixtures** - Create reusable test data
|
|
29
|
-
- 📦 **Browser-Compatible** - Full browser support with embedded tapbundle
|
|
30
29
|
- 👀 **Watch Mode** - Automatically re-run tests on file changes
|
|
31
30
|
- 📊 **Real-time Progress** - Live test execution progress updates
|
|
32
31
|
- 🎨 **Visual Diffs** - Beautiful side-by-side diffs for failed assertions
|
|
33
32
|
- 🔄 **Event-based Reporting** - Real-time test lifecycle events
|
|
34
|
-
- ⚙️ **Test Configuration** - Flexible test settings with .tstest.json files
|
|
35
|
-
- 🚀 **Protocol V2** - Enhanced TAP protocol with Unicode delimiters
|
|
36
33
|
|
|
37
34
|
## Installation
|
|
38
35
|
|
|
@@ -42,6 +39,154 @@ npm install --save-dev @git.zone/tstest
|
|
|
42
39
|
pnpm add -D @git.zone/tstest
|
|
43
40
|
```
|
|
44
41
|
|
|
42
|
+
## Multi-Runtime Architecture
|
|
43
|
+
|
|
44
|
+
tstest supports running your tests across multiple JavaScript runtimes, allowing you to verify cross-platform compatibility easily.
|
|
45
|
+
|
|
46
|
+
### Supported Runtimes
|
|
47
|
+
|
|
48
|
+
- **Node.js** - Default runtime, uses tsrun for TypeScript execution
|
|
49
|
+
- **Chromium** - Browser environment testing with full DOM support
|
|
50
|
+
- **Deno** - Secure TypeScript/JavaScript runtime with modern features
|
|
51
|
+
- **Bun** - Ultra-fast all-in-one JavaScript runtime
|
|
52
|
+
|
|
53
|
+
### Test File Naming Convention
|
|
54
|
+
|
|
55
|
+
Name your test files with runtime specifiers to control where they run:
|
|
56
|
+
|
|
57
|
+
| Pattern | Runtimes | Example |
|
|
58
|
+
|---------|----------|---------|
|
|
59
|
+
| `*.ts` | Node.js only (default) | `test.api.ts` |
|
|
60
|
+
| `*.node.ts` | Node.js only | `test.server.node.ts` |
|
|
61
|
+
| `*.chromium.ts` | Chromium browser | `test.dom.chromium.ts` |
|
|
62
|
+
| `*.deno.ts` | Deno runtime | `test.http.deno.ts` |
|
|
63
|
+
| `*.bun.ts` | Bun runtime | `test.fast.bun.ts` |
|
|
64
|
+
| `*.all.ts` | All runtimes (Node, Chromium, Deno, Bun) | `test.universal.all.ts` |
|
|
65
|
+
| `*.node+chromium.ts` | Both Node.js and Chromium | `test.isomorphic.node+chromium.ts` |
|
|
66
|
+
| `*.node+deno.ts` | Both Node.js and Deno | `test.cross.node+deno.ts` |
|
|
67
|
+
| `*.deno+bun.ts` | Both Deno and Bun | `test.modern.deno+bun.ts` |
|
|
68
|
+
| `*.chromium.nonci.ts` | Chromium, skip in CI | `test.visual.chromium.nonci.ts` |
|
|
69
|
+
| `*.all.nonci.ts` | All runtimes, skip in CI | `test.comprehensive.all.nonci.ts` |
|
|
70
|
+
|
|
71
|
+
**Multi-Runtime Examples:**
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// test.api.all.ts - runs in all runtimes (Node, Chromium, Deno, Bun)
|
|
75
|
+
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
|
76
|
+
|
|
77
|
+
tap.test('universal HTTP test', async () => {
|
|
78
|
+
const response = await fetch('https://api.example.com/test');
|
|
79
|
+
expect(response.status).toEqual(200);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
export default tap.start();
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// test.api.node+deno+bun.ts - runs in specific runtimes
|
|
87
|
+
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
|
88
|
+
|
|
89
|
+
tap.test('cross-runtime HTTP test', async () => {
|
|
90
|
+
const response = await fetch('https://api.example.com/test');
|
|
91
|
+
expect(response.status).toEqual(200);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
export default tap.start();
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Runtime Execution Order
|
|
98
|
+
|
|
99
|
+
When multiple runtimes are specified, tests execute in this order:
|
|
100
|
+
1. Node.js
|
|
101
|
+
2. Bun
|
|
102
|
+
3. Deno
|
|
103
|
+
4. Chromium
|
|
104
|
+
|
|
105
|
+
### Legacy Naming (Deprecated)
|
|
106
|
+
|
|
107
|
+
The following patterns are still supported but deprecated. Use the migration tool to update:
|
|
108
|
+
|
|
109
|
+
| Legacy Pattern | Modern Equivalent | Migration Command |
|
|
110
|
+
|----------------|-------------------|-------------------|
|
|
111
|
+
| `*.browser.ts` | `*.chromium.ts` | `tstest migrate` |
|
|
112
|
+
| `*.both.ts` | `*.node+chromium.ts` | `tstest migrate` |
|
|
113
|
+
|
|
114
|
+
When running legacy files, tstest shows a deprecation warning with the suggested new name.
|
|
115
|
+
|
|
116
|
+
### Migration Tool
|
|
117
|
+
|
|
118
|
+
Migrate your test files from legacy naming to the new convention:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Dry run - see what would change
|
|
122
|
+
tstest migrate --dry-run
|
|
123
|
+
|
|
124
|
+
# Apply migrations (uses git mv to preserve history)
|
|
125
|
+
tstest migrate --write
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Migration Features:**
|
|
129
|
+
- ✅ Uses `git mv` to preserve file history
|
|
130
|
+
- ✅ Idempotent - safe to run multiple times
|
|
131
|
+
- ✅ Dry-run by default for safety
|
|
132
|
+
- ✅ Colored output showing all changes
|
|
133
|
+
- ✅ Handles modifiers like `.nonci` correctly
|
|
134
|
+
|
|
135
|
+
Example output:
|
|
136
|
+
```
|
|
137
|
+
============================================================
|
|
138
|
+
Test File Migration Tool
|
|
139
|
+
============================================================
|
|
140
|
+
|
|
141
|
+
🔍 DRY RUN MODE - No files will be modified
|
|
142
|
+
|
|
143
|
+
Found 3 legacy test file(s)
|
|
144
|
+
|
|
145
|
+
Would migrate:
|
|
146
|
+
test.browser.ts
|
|
147
|
+
→ test.chromium.ts
|
|
148
|
+
|
|
149
|
+
Would migrate:
|
|
150
|
+
test.both.ts
|
|
151
|
+
→ test.node+chromium.ts
|
|
152
|
+
|
|
153
|
+
Would migrate:
|
|
154
|
+
test.auth.browser.nonci.ts
|
|
155
|
+
→ test.auth.chromium.nonci.ts
|
|
156
|
+
|
|
157
|
+
============================================================
|
|
158
|
+
Summary:
|
|
159
|
+
Total legacy files: 3
|
|
160
|
+
Successfully migrated: 3
|
|
161
|
+
Errors: 0
|
|
162
|
+
============================================================
|
|
163
|
+
|
|
164
|
+
To apply these changes, run:
|
|
165
|
+
tstest migrate --write
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Runtime-Specific Permissions
|
|
169
|
+
|
|
170
|
+
#### Deno Runtime
|
|
171
|
+
|
|
172
|
+
Tests run with these permissions by default:
|
|
173
|
+
```bash
|
|
174
|
+
--allow-read
|
|
175
|
+
--allow-env
|
|
176
|
+
--allow-net
|
|
177
|
+
--allow-write
|
|
178
|
+
--allow-sys
|
|
179
|
+
--allow-import # Enables npm packages and Node.js built-ins
|
|
180
|
+
--node-modules-dir # Node.js compatibility mode
|
|
181
|
+
--sloppy-imports # Allows .js imports to resolve to .ts files
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Configure custom permissions in your test file or via environment variables.
|
|
185
|
+
|
|
186
|
+
#### Bun Runtime
|
|
187
|
+
|
|
188
|
+
Bun runs with its native TypeScript support and full access to Node.js APIs.
|
|
189
|
+
|
|
45
190
|
## Usage
|
|
46
191
|
|
|
47
192
|
### Basic Test Execution
|
|
@@ -92,18 +237,29 @@ tstest "test/unit/*.ts"
|
|
|
92
237
|
Pattern: test
|
|
93
238
|
Found: 4 test file(s)
|
|
94
239
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
240
|
+
━━━ Part 1: Node.js ━━━
|
|
241
|
+
|
|
242
|
+
▶️ test/test.node+deno.ts (1/4)
|
|
243
|
+
Runtime: Node.js
|
|
244
|
+
✅ HTTP request works (12ms)
|
|
245
|
+
✅ JSON parsing works (3ms)
|
|
246
|
+
Summary: 2/2 PASSED in 1.2s
|
|
247
|
+
|
|
248
|
+
━━━ Part 2: Deno ━━━
|
|
249
|
+
|
|
250
|
+
▶️ test/test.node+deno.ts (1/4)
|
|
251
|
+
Runtime: Deno
|
|
252
|
+
✅ HTTP request works (15ms)
|
|
253
|
+
✅ JSON parsing works (2ms)
|
|
254
|
+
Summary: 2/2 PASSED in 1.1s
|
|
99
255
|
|
|
100
256
|
📊 Test Summary
|
|
101
257
|
┌────────────────────────────────┐
|
|
102
258
|
│ Total Files: 4 │
|
|
103
|
-
│ Total Tests:
|
|
104
|
-
│ Passed:
|
|
259
|
+
│ Total Tests: 8 │
|
|
260
|
+
│ Passed: 8 │
|
|
105
261
|
│ Failed: 0 │
|
|
106
|
-
│ Duration:
|
|
262
|
+
│ Duration: 2.4s │
|
|
107
263
|
└────────────────────────────────┘
|
|
108
264
|
|
|
109
265
|
ALL TESTS PASSED! 🎉
|
|
@@ -141,19 +297,7 @@ Perfect for CI/CD pipelines:
|
|
|
141
297
|
{"event":"summary","summary":{"totalFiles":4,"totalTests":4,"totalPassed":4,"totalFailed":0,"totalDuration":542}}
|
|
142
298
|
```
|
|
143
299
|
|
|
144
|
-
##
|
|
145
|
-
|
|
146
|
-
tstest supports different test environments through file naming:
|
|
147
|
-
|
|
148
|
-
| Pattern | Environment | Example |
|
|
149
|
-
|---------|-------------|---------|
|
|
150
|
-
| `*.ts` | Node.js (default) | `test.basic.ts` |
|
|
151
|
-
| `*.node.ts` | Node.js only | `test.api.node.ts` |
|
|
152
|
-
| `*.chrome.ts` | Chrome browser | `test.dom.chrome.ts` |
|
|
153
|
-
| `*.browser.ts` | Browser environment | `test.ui.browser.ts` |
|
|
154
|
-
| `*.both.ts` | Both Node.js and browser | `test.isomorphic.both.ts` |
|
|
155
|
-
|
|
156
|
-
### Writing Tests with tapbundle
|
|
300
|
+
## Writing Tests with tapbundle
|
|
157
301
|
|
|
158
302
|
tstest includes tapbundle, a powerful TAP-based test framework. Import it from the embedded tapbundle:
|
|
159
303
|
|
|
@@ -165,7 +309,7 @@ tap.test('my awesome test', async () => {
|
|
|
165
309
|
expect(result).toEqual('expected value');
|
|
166
310
|
});
|
|
167
311
|
|
|
168
|
-
tap.start();
|
|
312
|
+
export default tap.start();
|
|
169
313
|
```
|
|
170
314
|
|
|
171
315
|
**Module Exports**
|
|
@@ -196,7 +340,7 @@ tap.test('async operations', async (tools) => {
|
|
|
196
340
|
});
|
|
197
341
|
|
|
198
342
|
// Start test execution
|
|
199
|
-
tap.start();
|
|
343
|
+
export default tap.start();
|
|
200
344
|
```
|
|
201
345
|
|
|
202
346
|
### Test Modifiers and Chaining
|
|
@@ -231,20 +375,20 @@ tap.timeout(5000)
|
|
|
231
375
|
```typescript
|
|
232
376
|
tap.describe('User Management', () => {
|
|
233
377
|
let testDatabase;
|
|
234
|
-
|
|
378
|
+
|
|
235
379
|
tap.beforeEach(async () => {
|
|
236
380
|
testDatabase = await createTestDB();
|
|
237
381
|
});
|
|
238
|
-
|
|
382
|
+
|
|
239
383
|
tap.afterEach(async () => {
|
|
240
384
|
await testDatabase.cleanup();
|
|
241
385
|
});
|
|
242
|
-
|
|
386
|
+
|
|
243
387
|
tap.test('should create user', async () => {
|
|
244
388
|
const user = await testDatabase.createUser({ name: 'John' });
|
|
245
389
|
expect(user.id).toBeDefined();
|
|
246
390
|
});
|
|
247
|
-
|
|
391
|
+
|
|
248
392
|
tap.describe('User Permissions', () => {
|
|
249
393
|
tap.test('should set admin role', async () => {
|
|
250
394
|
// Nested describe blocks
|
|
@@ -262,37 +406,37 @@ tap.test('using test tools', async (tools) => {
|
|
|
262
406
|
// Delay utilities
|
|
263
407
|
await tools.delayFor(1000); // delay for 1000ms
|
|
264
408
|
await tools.delayForRandom(100, 500); // random delay between 100-500ms
|
|
265
|
-
|
|
409
|
+
|
|
266
410
|
// Skip test conditionally
|
|
267
411
|
tools.skipIf(process.env.CI === 'true', 'Skipping in CI');
|
|
268
|
-
|
|
412
|
+
|
|
269
413
|
// Skip test unconditionally
|
|
270
414
|
if (!apiKeyAvailable) {
|
|
271
415
|
tools.skip('API key not available');
|
|
272
416
|
}
|
|
273
|
-
|
|
417
|
+
|
|
274
418
|
// Mark as todo
|
|
275
419
|
tools.todo('Needs implementation');
|
|
276
|
-
|
|
420
|
+
|
|
277
421
|
// Retry configuration
|
|
278
422
|
tools.retry(3); // Set retry count
|
|
279
|
-
|
|
423
|
+
|
|
280
424
|
// Timeout configuration
|
|
281
425
|
tools.timeout(10000); // Set timeout to 10s
|
|
282
|
-
|
|
426
|
+
|
|
283
427
|
// Context sharing between tests
|
|
284
428
|
tools.context.set('userId', 12345);
|
|
285
429
|
const userId = tools.context.get('userId');
|
|
286
|
-
|
|
430
|
+
|
|
287
431
|
// Deferred promises
|
|
288
432
|
const deferred = tools.defer();
|
|
289
433
|
setTimeout(() => deferred.resolve('done'), 100);
|
|
290
434
|
await deferred.promise;
|
|
291
|
-
|
|
435
|
+
|
|
292
436
|
// Colored console output
|
|
293
437
|
const coloredString = await tools.coloredString('Success!', 'green');
|
|
294
438
|
console.log(coloredString);
|
|
295
|
-
|
|
439
|
+
|
|
296
440
|
// Error handling helper
|
|
297
441
|
const error = await tools.returnError(async () => {
|
|
298
442
|
throw new Error('Expected error');
|
|
@@ -306,10 +450,10 @@ tap.test('using test tools', async (tools) => {
|
|
|
306
450
|
```typescript
|
|
307
451
|
tap.test('snapshot test', async (tools) => {
|
|
308
452
|
const output = generateComplexOutput();
|
|
309
|
-
|
|
453
|
+
|
|
310
454
|
// Compare with saved snapshot
|
|
311
455
|
await tools.matchSnapshot(output);
|
|
312
|
-
|
|
456
|
+
|
|
313
457
|
// Named snapshots for multiple checks in one test
|
|
314
458
|
await tools.matchSnapshot(output.header, 'header');
|
|
315
459
|
await tools.matchSnapshot(output.body, 'body');
|
|
@@ -339,9 +483,9 @@ tap.defineFixture('testPost', async (data) => ({
|
|
|
339
483
|
tap.test('fixture test', async (tools) => {
|
|
340
484
|
const user = await tools.fixture('testUser', { name: 'John' });
|
|
341
485
|
const post = await tools.fixture('testPost', { authorId: user.id });
|
|
342
|
-
|
|
486
|
+
|
|
343
487
|
expect(post.authorId).toEqual(user.id);
|
|
344
|
-
|
|
488
|
+
|
|
345
489
|
// Factory pattern for multiple instances
|
|
346
490
|
const users = await tools.factory('testUser').createMany(5);
|
|
347
491
|
expect(users).toHaveLength(5);
|
|
@@ -485,7 +629,7 @@ tap.test('first test', async (tools) => {
|
|
|
485
629
|
tap.test('second test', async (tools) => {
|
|
486
630
|
const sessionId = tools.context.get('sessionId');
|
|
487
631
|
expect(sessionId).toBeDefined();
|
|
488
|
-
|
|
632
|
+
|
|
489
633
|
// Cleanup
|
|
490
634
|
tools.context.delete('sessionId');
|
|
491
635
|
});
|
|
@@ -506,9 +650,9 @@ tap.test('DOM manipulation', async () => {
|
|
|
506
650
|
<button id="test-btn">Click Me</button>
|
|
507
651
|
</div>
|
|
508
652
|
`);
|
|
509
|
-
|
|
653
|
+
|
|
510
654
|
expect(element.querySelector('h1').textContent).toEqual('Test Title');
|
|
511
|
-
|
|
655
|
+
|
|
512
656
|
// Simulate interactions
|
|
513
657
|
const button = element.querySelector('#test-btn');
|
|
514
658
|
button.click();
|
|
@@ -521,7 +665,7 @@ tap.test('CSS testing', async () => {
|
|
|
521
665
|
font-size: 16px;
|
|
522
666
|
}
|
|
523
667
|
`;
|
|
524
|
-
|
|
668
|
+
|
|
525
669
|
// styles is a string that can be injected into the page
|
|
526
670
|
expect(styles).toInclude('color: red');
|
|
527
671
|
});
|
|
@@ -535,7 +679,7 @@ tap.test('error handling', async (tools) => {
|
|
|
535
679
|
const error = await tools.returnError(async () => {
|
|
536
680
|
await functionThatThrows();
|
|
537
681
|
});
|
|
538
|
-
|
|
682
|
+
|
|
539
683
|
expect(error).toBeInstanceOf(Error);
|
|
540
684
|
expect(error.message).toEqual('Expected error message');
|
|
541
685
|
});
|
|
@@ -612,7 +756,7 @@ When assertions fail, tstest shows beautiful side-by-side diffs:
|
|
|
612
756
|
String Diff:
|
|
613
757
|
- Expected
|
|
614
758
|
+ Received
|
|
615
|
-
|
|
759
|
+
|
|
616
760
|
- Hello World
|
|
617
761
|
+ Hello Universe
|
|
618
762
|
|
|
@@ -625,73 +769,6 @@ When assertions fail, tstest shows beautiful side-by-side diffs:
|
|
|
625
769
|
}
|
|
626
770
|
```
|
|
627
771
|
|
|
628
|
-
### Test Configuration (.tstest.json)
|
|
629
|
-
|
|
630
|
-
Configure test behavior with `.tstest.json` files:
|
|
631
|
-
|
|
632
|
-
```json
|
|
633
|
-
{
|
|
634
|
-
"timeout": 30000,
|
|
635
|
-
"retries": 2,
|
|
636
|
-
"bail": false,
|
|
637
|
-
"parallel": true,
|
|
638
|
-
"tags": ["unit", "fast"],
|
|
639
|
-
"env": {
|
|
640
|
-
"NODE_ENV": "test"
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
```
|
|
644
|
-
|
|
645
|
-
Configuration files are discovered in:
|
|
646
|
-
1. Test file directory
|
|
647
|
-
2. Parent directories (up to project root)
|
|
648
|
-
3. Project root
|
|
649
|
-
4. Home directory (`~/.tstest.json`)
|
|
650
|
-
|
|
651
|
-
Settings cascade and merge, with closer files taking precedence.
|
|
652
|
-
|
|
653
|
-
### Event-based Test Reporting
|
|
654
|
-
|
|
655
|
-
tstest emits detailed events during test execution for integration with CI/CD tools:
|
|
656
|
-
|
|
657
|
-
```json
|
|
658
|
-
{"event":"suite:started","file":"test/api.test.ts","timestamp":"2025-05-26T10:30:00.000Z"}
|
|
659
|
-
{"event":"test:started","name":"api endpoint validation","timestamp":"2025-05-26T10:30:00.100Z"}
|
|
660
|
-
{"event":"test:progress","name":"api endpoint validation","message":"Validating response schema"}
|
|
661
|
-
{"event":"test:completed","name":"api endpoint validation","passed":true,"duration":145}
|
|
662
|
-
{"event":"suite:completed","file":"test/api.test.ts","passed":true,"total":2,"failed":0}
|
|
663
|
-
```
|
|
664
|
-
|
|
665
|
-
### Enhanced TAP Protocol (Protocol V2)
|
|
666
|
-
|
|
667
|
-
tstest uses an enhanced TAP protocol with Unicode delimiters for better parsing:
|
|
668
|
-
|
|
669
|
-
```
|
|
670
|
-
⟦TSTEST:EVENT:test:started⟧{"name":"my test","timestamp":"2025-05-26T10:30:00.000Z"}
|
|
671
|
-
ok 1 my test
|
|
672
|
-
⟦TSTEST:EVENT:test:completed⟧{"name":"my test","passed":true,"duration":145}
|
|
673
|
-
```
|
|
674
|
-
|
|
675
|
-
This prevents conflicts with test output that might contain TAP-like formatting.
|
|
676
|
-
|
|
677
|
-
## Advanced Features
|
|
678
|
-
|
|
679
|
-
### Glob Pattern Support
|
|
680
|
-
|
|
681
|
-
Run specific test patterns:
|
|
682
|
-
```bash
|
|
683
|
-
# Run all unit tests
|
|
684
|
-
tstest "test/unit/**/*.ts"
|
|
685
|
-
|
|
686
|
-
# Run all integration tests
|
|
687
|
-
tstest "test/integration/*.test.ts"
|
|
688
|
-
|
|
689
|
-
# Run multiple patterns
|
|
690
|
-
tstest "test/**/*.spec.ts" "test/**/*.test.ts"
|
|
691
|
-
```
|
|
692
|
-
|
|
693
|
-
**Important**: Always quote glob patterns to prevent shell expansion. Without quotes, the shell will expand the pattern and only pass the first matching file to tstest.
|
|
694
|
-
|
|
695
772
|
### Enhanced Test Logging
|
|
696
773
|
|
|
697
774
|
The `--logfile` option provides intelligent test logging with automatic organization:
|
|
@@ -849,6 +926,18 @@ tstest test/api/endpoints.test.ts --verbose --timeout 60
|
|
|
849
926
|
|
|
850
927
|
## Changelog
|
|
851
928
|
|
|
929
|
+
### Version 2.4.0
|
|
930
|
+
- 🚀 **Multi-Runtime Architecture** - Support for Deno, Bun, Node.js, and Chromium
|
|
931
|
+
- 🔀 **New Naming Convention** - Flexible `.runtime1+runtime2.ts` pattern
|
|
932
|
+
- 🌐 **Universal Testing** - `.all.ts` pattern runs tests on all supported runtimes
|
|
933
|
+
- 🔄 **Migration Tool** - Easy migration from legacy naming (`.browser.ts`, `.both.ts`)
|
|
934
|
+
- 🦕 **Deno Support** - Full Deno runtime with Node.js compatibility
|
|
935
|
+
- 🐰 **Bun Support** - Ultra-fast Bun runtime integration
|
|
936
|
+
- ⚡ **Dynamic Port Selection** - Random port allocation (30000-40000) prevents conflicts
|
|
937
|
+
- 🏗️ **Runtime Adapter Pattern** - Extensible architecture for adding new runtimes
|
|
938
|
+
- 📝 **Deprecation Warnings** - Helpful migration suggestions for legacy naming
|
|
939
|
+
- ✅ **Comprehensive Tests** - Full test coverage for parser and migration tool
|
|
940
|
+
|
|
852
941
|
### Version 1.11.0
|
|
853
942
|
- 👀 Added Watch Mode with `--watch`/`-w` flag for automatic test re-runs
|
|
854
943
|
- 📊 Implemented real-time test progress updates with event streaming
|
|
@@ -878,7 +967,7 @@ tstest test/api/endpoints.test.ts --verbose --timeout 60
|
|
|
878
967
|
- 📝 Improved internal protocol design documentation
|
|
879
968
|
- 🔧 Added protocol v2 utilities for future improvements
|
|
880
969
|
|
|
881
|
-
### Version 1.9.1
|
|
970
|
+
### Version 1.9.1
|
|
882
971
|
- 🐛 Fixed log file naming to preserve directory structure
|
|
883
972
|
- 📁 Log files now prevent collisions: `test__dir__file.log`
|
|
884
973
|
|
|
@@ -901,7 +990,7 @@ tstest test/api/endpoints.test.ts --verbose --timeout 60
|
|
|
901
990
|
|
|
902
991
|
## License and Legal Information
|
|
903
992
|
|
|
904
|
-
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license
|
|
993
|
+
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
|
|
905
994
|
|
|
906
995
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
|
907
996
|
|
|
@@ -911,9 +1000,9 @@ This project is owned and maintained by Task Venture Capital GmbH. The names and
|
|
|
911
1000
|
|
|
912
1001
|
### Company Information
|
|
913
1002
|
|
|
914
|
-
Task Venture Capital GmbH
|
|
1003
|
+
Task Venture Capital GmbH
|
|
915
1004
|
Registered at District court Bremen HRB 35230 HB, Germany
|
|
916
1005
|
|
|
917
1006
|
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
|
|
918
1007
|
|
|
919
|
-
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
|
1008
|
+
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* - test.chromium.ts
|
|
7
7
|
* - test.node+chromium.ts
|
|
8
8
|
* - test.deno+bun.ts
|
|
9
|
+
* - test.all.ts (runs on all runtimes)
|
|
9
10
|
* - test.chromium.nonci.ts
|
|
10
11
|
*/
|
|
11
12
|
|
|
@@ -29,6 +30,7 @@ export interface ParserConfig {
|
|
|
29
30
|
const KNOWN_RUNTIMES: Set<string> = new Set(['node', 'chromium', 'deno', 'bun']);
|
|
30
31
|
const KNOWN_MODIFIERS: Set<string> = new Set(['nonci']);
|
|
31
32
|
const VALID_EXTENSIONS: Set<string> = new Set(['ts', 'tsx', 'mts', 'cts']);
|
|
33
|
+
const ALL_RUNTIMES: Runtime[] = ['node', 'chromium', 'deno', 'bun'];
|
|
32
34
|
|
|
33
35
|
// Legacy mappings for backwards compatibility
|
|
34
36
|
const LEGACY_RUNTIME_MAP: Record<string, Runtime[]> = {
|
|
@@ -102,9 +104,12 @@ export function parseTestFilename(
|
|
|
102
104
|
const runtimeCandidates = token.split('+').map(r => r.trim()).filter(Boolean);
|
|
103
105
|
const validRuntimes: Runtime[] = [];
|
|
104
106
|
const invalidRuntimes: string[] = [];
|
|
107
|
+
let hasAllKeyword = false;
|
|
105
108
|
|
|
106
109
|
for (const candidate of runtimeCandidates) {
|
|
107
|
-
if (
|
|
110
|
+
if (candidate === 'all') {
|
|
111
|
+
hasAllKeyword = true;
|
|
112
|
+
} else if (KNOWN_RUNTIMES.has(candidate)) {
|
|
108
113
|
// Dedupe: only add if not already in list
|
|
109
114
|
if (!validRuntimes.includes(candidate as Runtime)) {
|
|
110
115
|
validRuntimes.push(candidate as Runtime);
|
|
@@ -114,11 +119,18 @@ export function parseTestFilename(
|
|
|
114
119
|
}
|
|
115
120
|
}
|
|
116
121
|
|
|
122
|
+
// If 'all' keyword is present, expand to all runtimes
|
|
123
|
+
if (hasAllKeyword) {
|
|
124
|
+
runtimes = [...ALL_RUNTIMES];
|
|
125
|
+
runtimeTokenIndex = i;
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
|
|
117
129
|
if (invalidRuntimes.length > 0) {
|
|
118
130
|
if (strictUnknownRuntime) {
|
|
119
131
|
throw new Error(
|
|
120
132
|
`Unknown runtime(s) in "${fileName}": ${invalidRuntimes.join(', ')}. ` +
|
|
121
|
-
`Valid runtimes: ${Array.from(KNOWN_RUNTIMES).join(', ')}`
|
|
133
|
+
`Valid runtimes: ${Array.from(KNOWN_RUNTIMES).join(', ')}, all`
|
|
122
134
|
);
|
|
123
135
|
} else {
|
|
124
136
|
console.warn(
|
|
@@ -138,6 +150,13 @@ export function parseTestFilename(
|
|
|
138
150
|
}
|
|
139
151
|
}
|
|
140
152
|
|
|
153
|
+
// Check if this is the 'all' keyword (expands to all runtimes)
|
|
154
|
+
if (token === 'all') {
|
|
155
|
+
runtimes = [...ALL_RUNTIMES];
|
|
156
|
+
runtimeTokenIndex = i;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
141
160
|
// Check if this is a single runtime token
|
|
142
161
|
if (KNOWN_RUNTIMES.has(token)) {
|
|
143
162
|
runtimes = [token as Runtime];
|