@git.zone/tstest 3.6.7 → 4.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.
package/readme.plan.md DELETED
@@ -1,321 +0,0 @@
1
- # Improvement Plan for tstest and tapbundle
2
-
3
- !! FIRST: Reread /home/philkunz/.claude/CLAUDE.md to ensure following all guidelines !!
4
-
5
- ## Improved Internal Protocol (NEW - Critical) ✅ COMPLETED
6
-
7
- ### Current Issues ✅ RESOLVED
8
- - ✅ TAP protocol uses `#` for metadata which conflicts with test descriptions containing `#`
9
- - ✅ Fragile regex parsing that breaks with special characters
10
- - ✅ Limited extensibility for new metadata types
11
-
12
- ### Proposed Solution: Protocol V2 ✅ IMPLEMENTED
13
- - ✅ Use Unicode delimiters `⟦TSTEST:META:{}⟧` that won't appear in test names
14
- - ✅ Structured JSON metadata format
15
- - ✅ Separate protocol blocks for complex data (errors, snapshots)
16
- - ✅ Complete replacement of v1 (no backwards compatibility needed)
17
-
18
- ### Implementation ✅ COMPLETED
19
- - ✅ Phase 1: Create protocol v2 implementation in ts_tapbundle_protocol
20
- - ✅ Phase 2: Replace all v1 code in both tstest and tapbundle with v2
21
- - ✅ Phase 3: Delete all v1 parsing and generation code
22
-
23
- #### ts_tapbundle_protocol Directory
24
- The protocol v2 implementation will be contained in the `ts_tapbundle_protocol` directory as isomorphic TypeScript code:
25
- - **Isomorphic Design**: All code must work in both browser and Node.js environments
26
- - **No Node.js Imports**: No Node.js-specific modules allowed (no fs, path, child_process, etc.)
27
- - **Protocol Classes**: Contains classes implementing all sides of the protocol:
28
- - ✅ `ProtocolEmitter`: For generating protocol v2 messages (used by tapbundle)
29
- - ✅ `ProtocolParser`: For parsing protocol v2 messages (used by tstest)
30
- - ✅ `ProtocolMessage`: Base classes for different message types
31
- - ✅ `ProtocolTypes`: TypeScript interfaces and types for protocol structures
32
- - **Pure TypeScript**: Only browser-compatible APIs and pure TypeScript/JavaScript code
33
- - **Build Integration**:
34
- - Compiled by `pnpm build` (via tsbuild) to `dist_ts_tapbundle_protocol/`
35
- - Build order defined in tspublish.json files
36
- - Imported by ts and ts_tapbundle modules from the compiled dist directory
37
-
38
- See `readme.protocol.md` for detailed specification.
39
-
40
- ## Test Configuration System (NEW)
41
-
42
- ### Global Test Configuration via 00init.ts
43
- - **Discovery**: Check for `test/00init.ts` before running tests
44
- - **Execution**: Import and execute before any test files if found
45
- - **Purpose**: Define project-wide default test settings
46
-
47
- ### tap.settings() API
48
- ```typescript
49
- interface TapSettings {
50
- // Timing
51
- timeout?: number; // Default timeout for all tests (ms)
52
- slowThreshold?: number; // Mark tests as slow if they exceed this (ms)
53
-
54
- // Execution Control
55
- bail?: boolean; // Stop on first test failure
56
- retries?: number; // Number of retries for failed tests
57
- retryDelay?: number; // Delay between retries (ms)
58
-
59
- // Output Control
60
- suppressConsole?: boolean; // Suppress console output in passing tests
61
- verboseErrors?: boolean; // Show full stack traces
62
- showTestDuration?: boolean; // Show duration for each test
63
-
64
- // Parallel Execution
65
- maxConcurrency?: number; // Max parallel tests (for .para files)
66
- isolateTests?: boolean; // Run each test in fresh context
67
-
68
- // Lifecycle Hooks
69
- beforeAll?: () => Promise<void> | void;
70
- afterAll?: () => Promise<void> | void;
71
- beforeEach?: (testName: string) => Promise<void> | void;
72
- afterEach?: (testName: string, passed: boolean) => Promise<void> | void;
73
-
74
- // Environment
75
- env?: Record<string, string>; // Additional environment variables
76
-
77
- // Features
78
- enableSnapshots?: boolean; // Enable snapshot testing
79
- snapshotDirectory?: string; // Custom snapshot directory
80
- updateSnapshots?: boolean; // Update snapshots instead of comparing
81
- }
82
- ```
83
-
84
- ### Settings Inheritance
85
- - Global (00init.ts) → File level → Test level
86
- - More specific settings override less specific ones
87
- - Arrays/objects are merged, primitives are replaced
88
-
89
- ### Implementation Phases
90
- 1. **Core Infrastructure**: Settings storage and merge logic
91
- 2. **Discovery**: 00init.ts loading mechanism
92
- 3. **Application**: Apply settings to test execution
93
- 4. **Advanced**: Parallel execution and snapshot configuration
94
-
95
- ## 1. Enhanced Communication Between tapbundle and tstest ✅ COMPLETED
96
-
97
- ### 1.1 Real-time Test Progress API ✅ COMPLETED
98
- - ✅ Create a bidirectional communication channel between tapbundle and tstest
99
- - ✅ Emit events for test lifecycle stages (start, progress, completion)
100
- - ✅ Allow tstest to subscribe to tapbundle events for better progress reporting
101
- - ✅ Implement a standardized message format for test metadata
102
-
103
- ### 1.2 Rich Error Reporting ✅ COMPLETED
104
- - ✅ Pass structured error objects from tapbundle to tstest
105
- - ✅ Include stack traces, code snippets, and contextual information
106
- - ✅ Support for error categorization (assertion failures, timeouts, uncaught exceptions)
107
- - ✅ Visual diff output for failed assertions
108
-
109
- ## 2. Enhanced toolsArg Functionality
110
-
111
- ### 2.3 Test Data and Context Sharing (Partial)
112
- ```typescript
113
- tap.test('data-driven test', async (toolsArg) => {
114
- // Parameterized test data (not yet implemented)
115
- const testData = toolsArg.data<TestInput>();
116
- expect(processData(testData)).toEqual(expected);
117
- });
118
- ```
119
-
120
- ## 3. Nested Tests and Test Suites
121
-
122
- ### 3.2 Hierarchical Test Organization (Not yet implemented)
123
- - Support for multiple levels of nesting
124
- - Inherited context and configuration from parent suites
125
- - Aggregated reporting for test suites
126
- - Suite-level lifecycle hooks
127
-
128
- ## 4. Advanced Test Features
129
-
130
- ### 4.1 Snapshot Testing ✅ (Basic implementation complete)
131
-
132
- ### 4.2 Performance Benchmarking
133
- ```typescript
134
- tap.test('performance test', async (toolsArg) => {
135
- const benchmark = toolsArg.benchmark();
136
-
137
- // Run operation
138
- await expensiveOperation();
139
-
140
- // Assert performance constraints
141
- benchmark.expect({
142
- maxDuration: 1000,
143
- maxMemory: '100MB'
144
- });
145
- });
146
- ```
147
-
148
-
149
- ## 5. Test Execution Improvements
150
-
151
-
152
- ### 5.2 Watch Mode ✅ COMPLETED
153
- - Automatically re-run tests on file changes
154
- - Debounced file change detection (300ms)
155
- - Clear console output between runs
156
- - Shows which files triggered re-runs
157
- - Graceful exit with Ctrl+C
158
- - `--watch-ignore` option for excluding patterns
159
-
160
- ### 5.3 Advanced Test Filtering (Partial) ⚠️
161
- ```typescript
162
- // Exclude tests by pattern (not yet implemented)
163
- tstest --exclude "**/slow/**"
164
-
165
- // Run only failed tests from last run (not yet implemented)
166
- tstest --failed
167
-
168
- // Run tests modified in git (not yet implemented)
169
- tstest --changed
170
- ```
171
-
172
- ## 6. Reporting and Analytics
173
-
174
- ### 6.1 Custom Reporters
175
- - Plugin architecture for custom reporters
176
- - Built-in reporters: JSON, JUnit, HTML, Markdown
177
- - Real-time streaming reporters
178
- - Aggregated test metrics and trends
179
-
180
- ### 6.2 Coverage Integration
181
- - Built-in code coverage collection
182
- - Coverage thresholds and enforcement
183
- - Coverage trending over time
184
- - Integration with CI/CD pipelines
185
-
186
- ### 6.3 Test Analytics Dashboard
187
- - Web-based dashboard for test results
188
- - Historical test performance data
189
- - Flaky test detection
190
- - Test impact analysis
191
-
192
- ## 7. Developer Experience
193
-
194
- ### 7.1 Better Error Messages
195
- - Clear, actionable error messages
196
- - Suggestions for common issues
197
- - Links to documentation
198
- - Code examples in error output
199
-
200
- ## Implementation Phases
201
-
202
- ### Phase 1: Improved Internal Protocol (Priority: Critical) ✅ COMPLETED
203
- 1. ✅ Create ts_tapbundle_protocol directory with isomorphic protocol v2 implementation
204
- - ✅ Implement ProtocolEmitter class for message generation
205
- - ✅ Implement ProtocolParser class for message parsing
206
- - ✅ Define ProtocolMessage types and interfaces
207
- - ✅ Ensure all code is browser and Node.js compatible
208
- - ✅ Add tspublish.json to configure build order
209
- 2. ✅ Update build configuration to compile ts_tapbundle_protocol first
210
- 3. ✅ Replace TAP parser in tstest with Protocol V2 parser importing from dist_ts_tapbundle_protocol
211
- 4. ✅ Replace TAP generation in tapbundle with Protocol V2 emitter importing from dist_ts_tapbundle_protocol
212
- 5. ✅ Delete all v1 TAP parsing code from tstest
213
- 6. ✅ Delete all v1 TAP generation code from tapbundle
214
- 7. ✅ Test with real-world test suites containing special characters
215
-
216
- ### Phase 2: Test Configuration System (Priority: High) ✅ COMPLETED
217
- 1. ✅ Implement tap.settings() API with TypeScript interfaces
218
- 2. ✅ Add 00init.ts discovery and loading mechanism
219
- 3. ✅ Implement settings inheritance and merge logic
220
- 4. ✅ Apply settings to test execution (timeouts, retries, etc.)
221
-
222
- ### Phase 3: Enhanced Communication (Priority: High) ✅ COMPLETED
223
- 1. ✅ Build on Protocol V2 for richer communication
224
- 2. ✅ Implement real-time test progress API
225
- 3. ✅ Add structured error reporting with diffs and traces
226
-
227
- ### Phase 4: Developer Experience (Priority: Medium) ❌ NOT STARTED
228
- 1. Add watch mode
229
- 2. Implement custom reporters
230
- 3. Complete advanced test filtering options
231
- 4. Add performance benchmarking API
232
-
233
- ### Phase 5: Analytics and Performance (Priority: Low) ❌ NOT STARTED
234
- 1. Build test analytics dashboard
235
- 2. Implement coverage integration
236
- 3. Create trend analysis tools
237
- 4. Add test impact analysis
238
-
239
- ## Technical Considerations
240
-
241
- ### API Design Principles
242
- - Clean, modern API design without legacy constraints
243
- - Progressive enhancement approach
244
- - Well-documented features and APIs
245
- - Clear, simple interfaces
246
-
247
- ### Performance Goals
248
- - Minimal overhead for test execution
249
- - Efficient parallel execution
250
- - Fast test discovery
251
- - Optimized browser test bundling
252
-
253
- ### Integration Points
254
- - Clean interfaces between tstest and tapbundle
255
- - Extensible plugin architecture
256
- - Standard test result format
257
- - Compatible with existing CI/CD tools
258
-
259
- ## Summary of Remaining Work
260
-
261
- ### ✅ Completed
262
- - **Protocol V2**: Full implementation with Unicode delimiters, structured metadata, and special character handling
263
- - **Test Configuration System**: tap.settings() API, 00init.ts discovery, settings inheritance, lifecycle hooks
264
- - **Enhanced Communication**: Event-based test lifecycle reporting, visual diff output for assertion failures, real-time test progress API
265
- - **Rich Error Reporting**: Stack traces, error metadata, and visual diffs through protocol
266
- - **Tags Filtering**: `--tags` option for running specific tagged tests
267
-
268
- ### ✅ Existing Features (Not in Plan)
269
- - **Timeout Support**: `--timeout` option and per-test timeouts
270
- - **Test Retries**: `tap.retry()` for flaky test handling
271
- - **Parallel Tests**: `.testParallel()` for concurrent execution
272
- - **Snapshot Testing**: Basic implementation with `toMatchSnapshot()`
273
- - **Test Lifecycle**: `describe()` blocks with `beforeEach`/`afterEach`
274
- - **Skip Tests**: `tap.skip.test()` (though it doesn't create test objects)
275
- - **Log Files**: `--logfile` option saves output to `.nogit/testlogs/`
276
- - **Test Range**: `--startFrom` and `--stopAt` for partial runs
277
-
278
- ### ⚠️ Partially Completed
279
- - **Advanced Test Filtering**: Have `--tags` but missing `--exclude`, `--failed`, `--changed`
280
-
281
- ### ❌ Not Started
282
-
283
- #### High Priority
284
-
285
- #### Medium Priority
286
- 2. **Developer Experience**
287
- - Watch mode for file changes
288
- - Custom reporters (JSON, JUnit, HTML, Markdown)
289
- - Performance benchmarking API
290
- - Better error messages with suggestions
291
-
292
- 3. **Enhanced toolsArg**
293
- - Test data injection
294
- - Context sharing between tests
295
- - Parameterized tests
296
-
297
- 4. **Test Organization**
298
- - Hierarchical test suites
299
- - Nested describe blocks
300
- - Suite-level lifecycle hooks
301
-
302
- #### Low Priority
303
- 5. **Analytics and Performance**
304
- - Test analytics dashboard
305
- - Code coverage integration
306
- - Trend analysis
307
- - Flaky test detection
308
-
309
- ### Recently Fixed Issues ✅
310
- - **tap.todo()**: Now fully implemented with test object creation
311
- - **tap.skip.test()**: Now creates test objects and maintains accurate test count
312
- - **tap.only.test()**: Works correctly - when .only tests exist, only those run
313
-
314
- ### Remaining Minor Issues
315
- - **Protocol Output**: Some protocol messages still appear in console output
316
-
317
- ### Next Recommended Steps
318
- 1. Add Watch Mode (Phase 4) - high developer value for fast feedback
319
- 2. Implement Custom Reporters - important for CI/CD integration
320
- 3. Implement performance benchmarking API
321
- 4. Add better error messages with suggestions
@@ -1,287 +0,0 @@
1
- # Improved Internal Protocol Design
2
-
3
- ## Current Issues with TAP Protocol
4
-
5
- 1. **Delimiter Conflict**: Using `#` for metadata conflicts with test descriptions containing `#`
6
- 2. **Ambiguous Parsing**: No clear boundary between test name and metadata
7
- 3. **Limited Extensibility**: Adding new metadata requires regex changes
8
- 4. **Mixed Concerns**: Protocol data mixed with human-readable output
9
-
10
- ## Proposed Internal Protocol v2
11
-
12
- ### Design Principles
13
-
14
- 1. **Clear Separation**: Protocol data must be unambiguously separated from user content
15
- 2. **Extensibility**: Easy to add new metadata without breaking parsers
16
- 3. **Backwards Compatible**: Can coexist with standard TAP for gradual migration
17
- 4. **Machine Readable**: Structured format for reliable parsing
18
- 5. **Human Friendly**: Still readable in raw form
19
-
20
- ### Protocol Options
21
-
22
- #### Option 1: Special Delimiters
23
- ```
24
- ok 1 - test description ::TSTEST:: {"time":123,"retry":0}
25
- not ok 2 - another test ::TSTEST:: {"time":45,"error":"timeout"}
26
- ok 3 - skipped test ::TSTEST:: {"time":0,"skip":"not ready"}
27
- ```
28
-
29
- **Pros**:
30
- - Simple to implement
31
- - Backwards compatible with TAP parsers (they ignore the suffix)
32
- - Easy to parse with split()
33
-
34
- **Cons**:
35
- - Still could conflict if test name contains `::TSTEST::`
36
- - Not standard TAP
37
-
38
- #### Option 2: Separate Metadata Lines
39
- ```
40
- ok 1 - test description
41
- ::METADATA:: {"test":1,"time":123,"retry":0}
42
- not ok 2 - another test
43
- ::METADATA:: {"test":2,"time":45,"error":"timeout"}
44
- ```
45
-
46
- **Pros**:
47
- - Complete separation of concerns
48
- - No chance of conflicts
49
- - Can include arbitrary metadata
50
-
51
- **Cons**:
52
- - Requires correlation between lines
53
- - More complex parsing
54
-
55
- #### Option 3: YAML Blocks (TAP 13 Compatible)
56
- ```
57
- ok 1 - test description
58
- ---
59
- time: 123
60
- retry: 0
61
- ...
62
- not ok 2 - another test
63
- ---
64
- time: 45
65
- error: timeout
66
- stack: |
67
- Error: timeout
68
- at Test.run (test.js:10:5)
69
- ...
70
- ```
71
-
72
- **Pros**:
73
- - Standard TAP 13 feature
74
- - Structured data format
75
- - Human readable
76
- - Extensible
77
-
78
- **Cons**:
79
- - More verbose
80
- - YAML parsing overhead
81
-
82
- #### Option 4: Binary Protocol Markers (Recommended)
83
- ```
84
- ok 1 - test description
85
- ␛[TSTEST:eyJ0aW1lIjoxMjMsInJldHJ5IjowfQ==]␛
86
- not ok 2 - another test
87
- ␛[TSTEST:eyJ0aW1lIjo0NSwiZXJyb3IiOiJ0aW1lb3V0In0=]␛
88
- ```
89
-
90
- Using ASCII escape character (␛ = \x1B) with base64 encoded JSON.
91
-
92
- **Pros**:
93
- - Zero chance of accidental conflicts
94
- - Compact
95
- - Fast to parse
96
- - Invisible in most terminals
97
-
98
- **Cons**:
99
- - Not human readable in raw form
100
- - Requires base64 encoding/decoding
101
-
102
- ### Recommended Implementation: Hybrid Approach
103
-
104
- Use multiple strategies based on context:
105
-
106
- 1. **For timing and basic metadata**: Use structured delimiters
107
- ```
108
- ok 1 - test name ⟦time:123,retry:0⟧
109
- ```
110
-
111
- 2. **For complex data (errors, snapshots)**: Use separate protocol lines
112
- ```
113
- ok 1 - test failed
114
- ⟦TSTEST:ERROR⟧
115
- {"message":"Assertion failed","stack":"...","diff":"..."}
116
- ⟦/TSTEST:ERROR⟧
117
- ```
118
-
119
- 3. **For human-readable output**: Keep standard TAP comments
120
- ```
121
- # Test suite: User Authentication
122
- ok 1 - should login
123
- ```
124
-
125
- ### Implementation Plan
126
-
127
- #### Phase 1: Parser Enhancement
128
- 1. Add new protocol parser alongside existing TAP parser
129
- 2. Support both old and new formats during transition
130
- 3. Add protocol version negotiation
131
-
132
- #### Phase 2: Metadata Structure
133
- ```typescript
134
- interface TestMetadata {
135
- // Timing
136
- time: number; // milliseconds
137
- startTime?: number; // Unix timestamp
138
- endTime?: number; // Unix timestamp
139
-
140
- // Status
141
- skip?: string; // skip reason
142
- todo?: string; // todo reason
143
- retry?: number; // retry attempt
144
- maxRetries?: number; // max retries allowed
145
-
146
- // Error details
147
- error?: {
148
- message: string;
149
- stack?: string;
150
- diff?: string;
151
- actual?: any;
152
- expected?: any;
153
- };
154
-
155
- // Test context
156
- file?: string; // source file
157
- line?: number; // line number
158
- column?: number; // column number
159
-
160
- // Custom data
161
- tags?: string[]; // test tags
162
- custom?: Record<string, any>;
163
- }
164
- ```
165
-
166
- #### Phase 3: Protocol Messages
167
-
168
- ##### Success Message
169
- ```
170
- ok 1 - user authentication works
171
- ⟦TSTEST:META:{"time":123,"tags":["auth","unit"]}⟧
172
- ```
173
-
174
- ##### Failure Message
175
- ```
176
- not ok 2 - login fails with invalid password
177
- ⟦TSTEST:META:{"time":45,"retry":1,"maxRetries":3}⟧
178
- ⟦TSTEST:ERROR⟧
179
- {
180
- "message": "Expected 401 but got 500",
181
- "stack": "Error: Expected 401 but got 500\n at Test.run (auth.test.ts:25:10)",
182
- "actual": 500,
183
- "expected": 401
184
- }
185
- ⟦/TSTEST:ERROR⟧
186
- ```
187
-
188
- ##### Skip Message
189
- ```
190
- ok 3 - database integration test ⟦TSTEST:SKIP:No database connection⟧
191
- ```
192
-
193
- ##### Snapshot Communication
194
- ```
195
- ⟦TSTEST:SNAPSHOT:user-profile⟧
196
- {
197
- "name": "John Doe",
198
- "email": "john@example.com",
199
- "roles": ["user", "admin"]
200
- }
201
- ⟦/TSTEST:SNAPSHOT⟧
202
- ```
203
-
204
- ### Migration Strategy
205
-
206
- 1. **Version Detection**: First line indicates protocol version
207
- ```
208
- ⟦TSTEST:PROTOCOL:2.0⟧
209
- TAP version 13
210
- ```
211
-
212
- 2. **Gradual Rollout**:
213
- - v1.10: Add protocol v2 parser, keep v1 generator
214
- - v1.11: Generate v2 by default, v1 with --legacy flag
215
- - v2.0: Remove v1 support
216
-
217
- 3. **Feature Flags**:
218
- ```typescript
219
- tap.settings({
220
- protocol: 'v2', // or 'v1', 'auto'
221
- protocolFeatures: {
222
- structuredErrors: true,
223
- enhancedTiming: true,
224
- binaryMarkers: false
225
- }
226
- });
227
- ```
228
-
229
- ### Benefits of New Protocol
230
-
231
- 1. **Reliability**: No more regex fragility or description conflicts
232
- 2. **Performance**: Faster parsing with clear boundaries
233
- 3. **Extensibility**: Easy to add new metadata fields
234
- 4. **Debugging**: Rich error information with stack traces and diffs
235
- 5. **Integration**: Better IDE and CI/CD tool integration
236
- 6. **Forward Compatible**: Room for future enhancements
237
-
238
- ### Example Parser Implementation
239
-
240
- ```typescript
241
- class ProtocolV2Parser {
242
- private readonly MARKER_START = '⟦TSTEST:';
243
- private readonly MARKER_END = '⟧';
244
-
245
- parseMetadata(line: string): TestMetadata | null {
246
- const start = line.lastIndexOf(this.MARKER_START);
247
- if (start === -1) return null;
248
-
249
- const end = line.indexOf(this.MARKER_END, start);
250
- if (end === -1) return null;
251
-
252
- const content = line.substring(start + this.MARKER_START.length, end);
253
- const [type, data] = content.split(':', 2);
254
-
255
- switch (type) {
256
- case 'META':
257
- return JSON.parse(data);
258
- case 'SKIP':
259
- return { skip: data };
260
- case 'TODO':
261
- return { todo: data };
262
- default:
263
- return null;
264
- }
265
- }
266
-
267
- parseTestLine(line: string): ParsedTest {
268
- // First extract any metadata
269
- const metadata = this.parseMetadata(line);
270
-
271
- // Then parse the TAP part (without metadata)
272
- const cleanLine = this.removeMetadata(line);
273
- const tapResult = this.parseTAP(cleanLine);
274
-
275
- return { ...tapResult, metadata };
276
- }
277
- }
278
- ```
279
-
280
- ### Next Steps
281
-
282
- 1. Implement proof of concept with basic metadata support
283
- 2. Test with real-world test suites for edge cases
284
- 3. Benchmark parsing performance
285
- 4. Get feedback from users
286
- 5. Finalize protocol specification
287
- 6. Implement in both tapbundle and tstest